AI Voice Designer
Run ID: 69cd216d3e7fb09ff16a834a2026-04-01Design
PantheraHive BOS
BOS Dashboard

Design a completely custom AI voice by describing the characteristics you want

This document details the comprehensive design specifications, wireframe descriptions, color palettes, and user experience (UX) recommendations for the "AI Voice Designer" step within your workflow. The goal is to provide a powerful, intuitive, and highly customizable interface for users to craft unique AI voices using ElevenLabs' advanced capabilities.


AI Voice Designer: Detailed Specifications & UX Design

This step empowers users to design a completely custom AI voice from scratch by defining a comprehensive set of characteristics. The output will be a unique AI voice ready for use in various applications.

1. Design Specifications (Core Functionality & Input Fields)

The "AI Voice Designer" interface will provide granular control over various voice attributes, allowing for both precise adjustments and broad descriptive inputs.

1.1 Core Voice Attributes (Sliders & Dropdowns)

These controls offer quantitative and qualitative adjustments to fundamental voice properties.

  • Gender:

* Dropdown: Male, Female, Androgynous (with a slider for spectrum).

  • Age Range:

* Dropdown: Child, Teen, Young Adult, Adult, Middle-Aged, Senior.

* Slider (Fine-tune): A continuous slider within the selected range (e.g., "Early 20s" to "Late 30s").

  • Pitch:

* Slider: Low to High (e.g., -50% to +50% from a neutral base).

* Unit: Semitones or Hertz (displayed on hover).

  • Speech Rate (Speed):

* Slider: Slow to Fast (e.g., 0.5x to 2.0x normal speed).

* Unit: Words Per Minute (WPM) approximation.

  • Tone/Resonance:

* Slider: Deep/Resonant to Bright/Clear.

  • Volume/Loudness:

* Slider: Soft/Whisper to Loud/Projected.

  • Emotional Range (Primary Emotion Emphasis):

* Dropdown: Neutral, Happy, Sad, Angry, Fearful, Surprised, Disgusted, Calm, Excited, Empathetic, Authoritative.

* Slider (Intensity): Low to High for the selected emotion.

  • Accent/Dialect:

* Dropdown: Standard American English, British English (RP), Australian English, Indian English, Irish English, Canadian English, Spanish (Castilian), Spanish (Mexican), French (Parisian), German (Standard), etc. (Extensive list based on ElevenLabs capabilities).

  • Speaking Style/Delivery:

* Dropdown: Formal, Casual, Conversational, Authoritative, Friendly, Storyteller, News Reporter, Announcer, Energetic, Calm, Soothing, Dramatic, Monotone.

  • Voice Texture/Quality:

* Dropdown: Smooth, Raspy, Breathy, Clear, Gravelly, Warm, Crisp.

1.2 Descriptive Input (Text Fields)

For more nuanced and free-form descriptions.

  • Voice Persona/Description:

* Text Area (Multi-line): "Describe the personality or character of the voice you envision (e.g., 'A wise old professor with a calming presence,' 'An energetic young entrepreneur who inspires confidence')."

* Character Limit: 500 characters.

* AI Interpretation: ElevenLabs' model will interpret this text to influence subtle vocal nuances.

  • Reference Adjectives:

* Text Input (Comma-separated): "Enter specific adjectives (e.g., 'reassuring, confident, friendly, articulate')."

* Suggestion Engine: Provide auto-suggestions as the user types.

1.3 Sample Text & Output Preview

  • Sample Text Input:

* Text Area: "Enter text to hear your custom voice (max 250 characters)."

* Placeholder: "The quick brown fox jumps over the lazy dog." or "Hello, this is your new custom AI voice."

  • Audio Playback Controls:

* Play Button: To generate and play the audio sample.

* Stop Button: To halt playback.

* Progress Bar/Waveform Visualizer: Displays audio progress and waveform.

  • Voice ID & Naming:

* Display: Automatically generated unique Voice ID.

* Text Input: "Name your custom voice (e.g., 'PantheraHive Narrator')."

1.4 Action Buttons

  • "Generate Voice Sample": Triggers the ElevenLabs API to synthesize the voice based on current parameters and play a sample.
  • "Refine Voice": (If a voice has already been generated) Allows for iterative adjustments and re-generation.
  • "Save Voice": Saves the current voice configuration to the user's ElevenLabs Voice Lab.
  • "Start Over": Resets all parameters to default.
  • "Randomize": Generates a random set of voice parameters for exploration.
  • "Load Preset": Opens a modal to select from pre-defined voice templates (e.g., "Standard Narrator," "Friendly AI Assistant," "Deep Storyteller").

2. Wireframe Descriptions (UI Layout)

The interface will be designed for clarity, ease of use, and an iterative design process. It will likely be a single-page application (SPA) or a multi-panel layout.

2.1 Main Layout: Two-Column Structure

  • Left Column (Controls Panel - ~65% width):

* Header: "Design Your AI Voice"

* Section 1: Core Attributes:

* Group sliders and dropdowns for Gender, Age, Pitch, Speed, Tone, Volume.

* Each control will have a clear label, the current value displayed, and tooltips for explanation.

* Visual separation (e.g., thin dividers or slight background shading) between groups of related controls.

* Section 2: Expressive Attributes:

* Group dropdowns/sliders for Emotional Range, Accent, Speaking Style, Voice Texture.

* Section 3: Descriptive Input:

* Voice Persona Text Area.

* Reference Adjectives Text Input.

* Action Buttons (Bottom of Left Column): "Start Over," "Randomize," "Load Preset."

  • Right Column (Preview & Actions Panel - ~35% width):

* Header: "Voice Preview & Management"

* Sample Text Input: Large text area for user to type sample text.

* Audio Playback Controls: Prominently placed Play/Stop buttons with a waveform visualization.

* Voice Details: Display for Voice ID and editable field for Voice Name.

* Primary Action Buttons: "Generate Voice Sample," "Refine Voice," "Save Voice."

* Saved Voices (Optional Mini-Panel): A collapsible section or small list showing recently saved voices, allowing quick selection to load and modify.

2.2 Responsive Design Considerations

  • Tablet/Smaller Screens: Columns would stack vertically, with controls panel above the preview panel.
  • Mobile: Controls would be presented as accordion sections or a tabbed interface to manage screen real estate. Essential buttons would remain prominent.

2.3 Interaction Flow

  1. User adjusts parameters in the left panel.
  2. User types sample text in the right panel.
  3. User clicks "Generate Voice Sample."
  4. Audio plays, and waveform visualizes.
  5. User can further adjust parameters and click "Refine Voice" to iterate.
  6. Once satisfied, user names the voice and clicks "Save Voice."
  7. Confirmation message appears.

3. Color Palettes

The color palette will align with ElevenLabs' modern, clean, and professional aesthetic, prioritizing readability and user focus.

  • Primary Brand Colors (ElevenLabs Inspired):

* #2D3748 (Dark Blue-Gray): Main text, primary headers.

* #4A5568 (Medium Gray): Secondary text, disabled states.

* #667EEA (Vibrant Purple/Blue): Primary interactive elements, active states, highlights.

* #EDF2F7 (Light Gray/Off-White): Backgrounds, card elements.

* #FFFFFF (White): Main content areas, input fields.

  • Accent & Feedback Colors:

* #805AD5 (Deep Purple): Hover/active states for primary buttons, progress bars.

* #4FD1C5 (Teal): Success messages, positive indicators.

* #F6AD55 (Orange): Warning messages, attention-grabbing elements.

* #F56565 (Red): Error messages, destructive actions.

  • Typography:

* Font Family: Sans-serif, clean and modern (e.g., Inter, Open Sans, Roboto).

* Weights: Regular, Medium, Semibold.

* Sizes: Clear hierarchy for headers, body text, and labels.

4. UX Recommendations

4.1 Iterative Design & Instant Feedback

  • Fast Generation: Optimize ElevenLabs API calls for near-instantaneous voice sample generation (ideally under 2-3 seconds).
  • Live Parameter Updates: As sliders are dragged, display the numerical value in real-time.
  • "Listen & Tweak" Loop: Encourage users to generate samples, make small adjustments, and re-generate.

4.2 Guidance & Accessibility

  • Tooltips & Explanations: Provide clear, concise tooltips for every slider, dropdown, and input field explaining its impact on the voice.
  • Default Presets: Offer a set of well-designed default voices to serve as starting points or inspiration.
  • Accessibility: Ensure high contrast ratios for text and interactive elements. Support keyboard navigation and screen readers.
  • Clear Error Messages: If a voice cannot be generated, provide specific and actionable feedback.

4.3 Ease of Use

  • Intuitive Controls: Use standard UI elements (sliders, dropdowns) that users are familiar with.
  • Logical Grouping: Organize controls into logical sections to prevent cognitive overload.
  • Undo/Redo Functionality: Allow users to revert recent changes to parameters.
  • "Randomize" Option: A fun and useful feature for users who want to explore possibilities or get unstuck.
  • Voice Naming: Prompt users to name their voice upon saving for better organization.

4.4 Performance & Scalability

  • Efficient API Calls: Batch parameter changes if possible, or ensure each "Generate" call is optimized.
  • Progress Indicators: Use loading spinners or progress bars during voice generation to manage user expectations.
  • Future Expansion: Design the layout to accommodate additional voice parameters or advanced features as ElevenLabs evolves without requiring a complete overhaul.

4.5 User Onboarding (First-time User Experience)

  • Brief Tutorial: A quick, optional overlay or guided tour for first-time users explaining the main sections and the "Generate -> Refine -> Save" workflow.
  • Example Descriptions: Provide a few examples for the "Voice Persona" text area to inspire users.

This detailed output provides a robust framework for developing the "AI Voice Designer" interface, ensuring a powerful, intuitive, and satisfying experience for users creating custom AI voices.

ai_voice_designer.md
Download as Markdown
Copy all content
Full output as text
Download ZIP
IDE-ready project ZIP
Copy share link
Permanent URL for this run
Get Embed Code
Embed this result on any website
Print / Save PDF
Use browser print dialog
"); var hasSrcMain=Object.keys(extracted).some(function(k){return k.indexOf("src/main")>=0;}); if(!hasSrcMain) zip.file(folder+"src/main."+ext,"import React from 'react' import ReactDOM from 'react-dom/client' import App from './App' import './index.css' ReactDOM.createRoot(document.getElementById('root')!).render( ) "); var hasSrcApp=Object.keys(extracted).some(function(k){return k==="src/App."+ext||k==="App."+ext;}); if(!hasSrcApp) zip.file(folder+"src/App."+ext,"import React from 'react' import './App.css' function App(){ return(

"+slugTitle(pn)+"

Built with PantheraHive BOS

) } export default App "); zip.file(folder+"src/index.css","*{margin:0;padding:0;box-sizing:border-box} body{font-family:system-ui,-apple-system,sans-serif;background:#f0f2f5;color:#1a1a2e} .app{min-height:100vh;display:flex;flex-direction:column} .app-header{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:40px} h1{font-size:2.5rem;font-weight:700} "); zip.file(folder+"src/App.css",""); zip.file(folder+"src/components/.gitkeep",""); zip.file(folder+"src/pages/.gitkeep",""); zip.file(folder+"src/hooks/.gitkeep",""); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+" Generated by PantheraHive BOS. ## Setup ```bash npm install npm run dev ``` ## Build ```bash npm run build ``` ## Open in IDE Open the project folder in VS Code or WebStorm. "); zip.file(folder+".gitignore","node_modules/ dist/ .env .DS_Store *.local "); } /* --- Vue (Vite + Composition API + TypeScript) --- */ function buildVue(zip,folder,app,code,panelTxt){ var pn=pkgName(app); var C=cc(pn); var extracted=extractCode(panelTxt); zip.file(folder+"package.json",'{ "name": "'+pn+'", "version": "0.0.0", "type": "module", "scripts": { "dev": "vite", "build": "vue-tsc -b && vite build", "preview": "vite preview" }, "dependencies": { "vue": "^3.5.13", "vue-router": "^4.4.5", "pinia": "^2.3.0", "axios": "^1.7.9" }, "devDependencies": { "@vitejs/plugin-vue": "^5.2.1", "typescript": "~5.7.3", "vite": "^6.0.5", "vue-tsc": "^2.2.0" } } '); zip.file(folder+"vite.config.ts","import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import { resolve } from 'path' export default defineConfig({ plugins: [vue()], resolve: { alias: { '@': resolve(__dirname,'src') } } }) "); zip.file(folder+"tsconfig.json",'{"files":[],"references":[{"path":"./tsconfig.app.json"},{"path":"./tsconfig.node.json"}]} '); zip.file(folder+"tsconfig.app.json",'{ "compilerOptions":{ "target":"ES2020","useDefineForClassFields":true,"module":"ESNext","lib":["ES2020","DOM","DOM.Iterable"], "skipLibCheck":true,"moduleResolution":"bundler","allowImportingTsExtensions":true, "isolatedModules":true,"moduleDetection":"force","noEmit":true,"jsxImportSource":"vue", "strict":true,"paths":{"@/*":["./src/*"]} }, "include":["src/**/*.ts","src/**/*.d.ts","src/**/*.tsx","src/**/*.vue"] } '); zip.file(folder+"env.d.ts","/// "); zip.file(folder+"index.html"," "+slugTitle(pn)+"
"); var hasMain=Object.keys(extracted).some(function(k){return k==="src/main.ts"||k==="main.ts";}); if(!hasMain) zip.file(folder+"src/main.ts","import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' import './assets/main.css' const app = createApp(App) app.use(createPinia()) app.mount('#app') "); var hasApp=Object.keys(extracted).some(function(k){return k.indexOf("App.vue")>=0;}); if(!hasApp) zip.file(folder+"src/App.vue"," "); zip.file(folder+"src/assets/main.css","*{margin:0;padding:0;box-sizing:border-box}body{font-family:system-ui,sans-serif;background:#fff;color:#213547} "); zip.file(folder+"src/components/.gitkeep",""); zip.file(folder+"src/views/.gitkeep",""); zip.file(folder+"src/stores/.gitkeep",""); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+" Generated by PantheraHive BOS. ## Setup ```bash npm install npm run dev ``` ## Build ```bash npm run build ``` Open in VS Code or WebStorm. "); zip.file(folder+".gitignore","node_modules/ dist/ .env .DS_Store *.local "); } /* --- Angular (v19 standalone) --- */ function buildAngular(zip,folder,app,code,panelTxt){ var pn=pkgName(app); var C=cc(pn); var sel=pn.replace(/_/g,"-"); var extracted=extractCode(panelTxt); zip.file(folder+"package.json",'{ "name": "'+pn+'", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "test": "ng test" }, "dependencies": { "@angular/animations": "^19.0.0", "@angular/common": "^19.0.0", "@angular/compiler": "^19.0.0", "@angular/core": "^19.0.0", "@angular/forms": "^19.0.0", "@angular/platform-browser": "^19.0.0", "@angular/platform-browser-dynamic": "^19.0.0", "@angular/router": "^19.0.0", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "~0.15.0" }, "devDependencies": { "@angular-devkit/build-angular": "^19.0.0", "@angular/cli": "^19.0.0", "@angular/compiler-cli": "^19.0.0", "typescript": "~5.6.0" } } '); zip.file(folder+"angular.json",'{ "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "newProjectRoot": "projects", "projects": { "'+pn+'": { "projectType": "application", "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular-devkit/build-angular:application", "options": { "outputPath": "dist/'+pn+'", "index": "src/index.html", "browser": "src/main.ts", "tsConfig": "tsconfig.app.json", "styles": ["src/styles.css"], "scripts": [] } }, "serve": {"builder":"@angular-devkit/build-angular:dev-server","configurations":{"production":{"buildTarget":"'+pn+':build:production"},"development":{"buildTarget":"'+pn+':build:development"}},"defaultConfiguration":"development"} } } } } '); zip.file(folder+"tsconfig.json",'{ "compileOnSave": false, "compilerOptions": {"baseUrl":"./","outDir":"./dist/out-tsc","forceConsistentCasingInFileNames":true,"strict":true,"noImplicitOverride":true,"noPropertyAccessFromIndexSignature":true,"noImplicitReturns":true,"noFallthroughCasesInSwitch":true,"paths":{"@/*":["src/*"]},"skipLibCheck":true,"esModuleInterop":true,"sourceMap":true,"declaration":false,"experimentalDecorators":true,"moduleResolution":"bundler","importHelpers":true,"target":"ES2022","module":"ES2022","useDefineForClassFields":false,"lib":["ES2022","dom"]}, "references":[{"path":"./tsconfig.app.json"}] } '); zip.file(folder+"tsconfig.app.json",'{ "extends":"./tsconfig.json", "compilerOptions":{"outDir":"./dist/out-tsc","types":[]}, "files":["src/main.ts"], "include":["src/**/*.d.ts"] } '); zip.file(folder+"src/index.html"," "+slugTitle(pn)+" "); zip.file(folder+"src/main.ts","import { bootstrapApplication } from '@angular/platform-browser'; import { appConfig } from './app/app.config'; import { AppComponent } from './app/app.component'; bootstrapApplication(AppComponent, appConfig) .catch(err => console.error(err)); "); zip.file(folder+"src/styles.css","* { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: system-ui, -apple-system, sans-serif; background: #f9fafb; color: #111827; } "); var hasComp=Object.keys(extracted).some(function(k){return k.indexOf("app.component")>=0;}); if(!hasComp){ zip.file(folder+"src/app/app.component.ts","import { Component } from '@angular/core'; import { RouterOutlet } from '@angular/router'; @Component({ selector: 'app-root', standalone: true, imports: [RouterOutlet], templateUrl: './app.component.html', styleUrl: './app.component.css' }) export class AppComponent { title = '"+pn+"'; } "); zip.file(folder+"src/app/app.component.html","

"+slugTitle(pn)+"

Built with PantheraHive BOS

"); zip.file(folder+"src/app/app.component.css",".app-header{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:60vh;gap:16px}h1{font-size:2.5rem;font-weight:700;color:#6366f1} "); } zip.file(folder+"src/app/app.config.ts","import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; import { provideRouter } from '@angular/router'; import { routes } from './app.routes'; export const appConfig: ApplicationConfig = { providers: [ provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes) ] }; "); zip.file(folder+"src/app/app.routes.ts","import { Routes } from '@angular/router'; export const routes: Routes = []; "); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+" Generated by PantheraHive BOS. ## Setup ```bash npm install ng serve # or: npm start ``` ## Build ```bash ng build ``` Open in VS Code with Angular Language Service extension. "); zip.file(folder+".gitignore","node_modules/ dist/ .env .DS_Store *.local .angular/ "); } /* --- Python --- */ function buildPython(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^```[w]* ?/m,"").replace(/ ?```$/m,"").trim(); var reqMap={"numpy":"numpy","pandas":"pandas","sklearn":"scikit-learn","tensorflow":"tensorflow","torch":"torch","flask":"flask","fastapi":"fastapi","uvicorn":"uvicorn","requests":"requests","sqlalchemy":"sqlalchemy","pydantic":"pydantic","dotenv":"python-dotenv","PIL":"Pillow","cv2":"opencv-python","matplotlib":"matplotlib","seaborn":"seaborn","scipy":"scipy"}; var reqs=[]; Object.keys(reqMap).forEach(function(k){if(src.indexOf("import "+k)>=0||src.indexOf("from "+k)>=0)reqs.push(reqMap[k]);}); var reqsTxt=reqs.length?reqs.join(" "):"# add dependencies here "; zip.file(folder+"main.py",src||"# "+title+" # Generated by PantheraHive BOS print(title+" loaded") "); zip.file(folder+"requirements.txt",reqsTxt); zip.file(folder+".env.example","# Environment variables "); zip.file(folder+"README.md","# "+title+" Generated by PantheraHive BOS. ## Setup ```bash python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt ``` ## Run ```bash python main.py ``` "); zip.file(folder+".gitignore",".venv/ __pycache__/ *.pyc .env .DS_Store "); } /* --- Node.js --- */ function buildNode(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^```[w]* ?/m,"").replace(/ ?```$/m,"").trim(); var depMap={"mongoose":"^8.0.0","dotenv":"^16.4.5","axios":"^1.7.9","cors":"^2.8.5","bcryptjs":"^2.4.3","jsonwebtoken":"^9.0.2","socket.io":"^4.7.4","uuid":"^9.0.1","zod":"^3.22.4","express":"^4.18.2"}; var deps={}; Object.keys(depMap).forEach(function(k){if(src.indexOf(k)>=0)deps[k]=depMap[k];}); if(!deps["express"])deps["express"]="^4.18.2"; var pkgJson=JSON.stringify({"name":pn,"version":"1.0.0","main":"src/index.js","scripts":{"start":"node src/index.js","dev":"nodemon src/index.js"},"dependencies":deps,"devDependencies":{"nodemon":"^3.0.3"}},null,2)+" "; zip.file(folder+"package.json",pkgJson); var fallback="const express=require("express"); const app=express(); app.use(express.json()); app.get("/",(req,res)=>{ res.json({message:""+title+" API"}); }); const PORT=process.env.PORT||3000; app.listen(PORT,()=>console.log("Server on port "+PORT)); "; zip.file(folder+"src/index.js",src||fallback); zip.file(folder+".env.example","PORT=3000 "); zip.file(folder+".gitignore","node_modules/ .env .DS_Store "); zip.file(folder+"README.md","# "+title+" Generated by PantheraHive BOS. ## Setup ```bash npm install ``` ## Run ```bash npm run dev ``` "); } /* --- Vanilla HTML --- */ function buildVanillaHtml(zip,folder,app,code){ var title=slugTitle(app); var isFullDoc=code.trim().toLowerCase().indexOf("=0||code.trim().toLowerCase().indexOf("=0; var indexHtml=isFullDoc?code:" "+title+" "+code+" "; zip.file(folder+"index.html",indexHtml); zip.file(folder+"style.css","/* "+title+" — styles */ *{margin:0;padding:0;box-sizing:border-box} body{font-family:system-ui,-apple-system,sans-serif;background:#fff;color:#1a1a2e} "); zip.file(folder+"script.js","/* "+title+" — scripts */ "); zip.file(folder+"assets/.gitkeep",""); zip.file(folder+"README.md","# "+title+" Generated by PantheraHive BOS. ## Open Double-click `index.html` in your browser. Or serve locally: ```bash npx serve . # or python3 -m http.server 3000 ``` "); zip.file(folder+".gitignore",".DS_Store node_modules/ .env "); } /* ===== MAIN ===== */ var sc=document.createElement("script"); sc.src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"; sc.onerror=function(){ if(lbl)lbl.textContent="Download ZIP"; alert("JSZip load failed — check connection."); }; sc.onload=function(){ var zip=new JSZip(); var base=(_phFname||"output").replace(/.[^.]+$/,""); var app=base.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_+|_+$/g,"")||"my_app"; var folder=app+"/"; var vc=document.getElementById("panel-content"); var panelTxt=vc?(vc.innerText||vc.textContent||""):""; var lang=detectLang(_phCode,panelTxt); if(_phIsHtml){ buildVanillaHtml(zip,folder,app,_phCode); } else if(lang==="flutter"){ buildFlutter(zip,folder,app,_phCode,panelTxt); } else if(lang==="react-native"){ buildReactNative(zip,folder,app,_phCode,panelTxt); } else if(lang==="swift"){ buildSwift(zip,folder,app,_phCode,panelTxt); } else if(lang==="kotlin"){ buildKotlin(zip,folder,app,_phCode,panelTxt); } else if(lang==="react"){ buildReact(zip,folder,app,_phCode,panelTxt); } else if(lang==="vue"){ buildVue(zip,folder,app,_phCode,panelTxt); } else if(lang==="angular"){ buildAngular(zip,folder,app,_phCode,panelTxt); } else if(lang==="python"){ buildPython(zip,folder,app,_phCode); } else if(lang==="node"){ buildNode(zip,folder,app,_phCode); } else { /* Document/content workflow */ var title=app.replace(/_/g," "); var md=_phAll||_phCode||panelTxt||"No content"; zip.file(folder+app+".md",md); var h=""+title+""; h+="

"+title+"

"; var hc=md.replace(/&/g,"&").replace(//g,">"); hc=hc.replace(/^### (.+)$/gm,"

$1

"); hc=hc.replace(/^## (.+)$/gm,"

$1

"); hc=hc.replace(/^# (.+)$/gm,"

$1

"); hc=hc.replace(/**(.+?)**/g,"$1"); hc=hc.replace(/ {2,}/g,"

"); h+="

"+hc+"

Generated by PantheraHive BOS
"; zip.file(folder+app+".html",h); zip.file(folder+"README.md","# "+title+" Generated by PantheraHive BOS. Files: - "+app+".md (Markdown) - "+app+".html (styled HTML) "); } zip.generateAsync({type:"blob"}).then(function(blob){ var a=document.createElement("a"); a.href=URL.createObjectURL(blob); a.download=app+".zip"; a.click(); URL.revokeObjectURL(a.href); if(lbl)lbl.textContent="Download ZIP"; }); }; document.head.appendChild(sc); }function phShare(){navigator.clipboard.writeText(window.location.href).then(function(){var el=document.getElementById("ph-share-lbl");if(el){el.textContent="Link copied!";setTimeout(function(){el.textContent="Copy share link";},2500);}});}function phEmbed(){var runId=window.location.pathname.split("/").pop().replace(".html","");var embedUrl="https://pantherahive.com/embed/"+runId;var code='';navigator.clipboard.writeText(code).then(function(){var el=document.getElementById("ph-embed-lbl");if(el){el.textContent="Embed code copied!";setTimeout(function(){el.textContent="Get Embed Code";},2500);}});}