AI Voice Designer
Run ID: 69cb9e9a61b1021a29a8abc72026-03-31Design
PantheraHive BOS
BOS Dashboard

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

AI Voice Designer: Custom Voice Design Specifications

This document outlines the detailed design specifications, user interface (UI) wireframe descriptions, recommended color palettes, and user experience (UX) recommendations for the "AI Voice Designer" feature. The goal is to provide a comprehensive and intuitive platform for users to create completely custom AI voices based on their specific characteristics.


1. Detailed Design Specifications for AI Voice Characteristics

The AI Voice Designer will allow users to define a custom voice through a combination of structured inputs, natural language descriptions, and optional audio references.

1.1 Core Voice Attributes

  • Gender:

* Options: Male, Female, Non-binary/Androgynous.

* Control: Radio buttons or dropdown with visual icons.

  • Age Range:

* Options: Child, Teenager, Young Adult, Adult, Middle-aged, Elderly.

* Control: Slider with labeled ranges or discrete radio buttons.

  • Accent/Dialect:

* Options:

* English: American (General, Southern, New York), British (RP, Cockney, Scottish, Irish), Australian, Indian, Canadian, etc.

* Other Languages: French (Standard, Canadian), German, Spanish (Castilian, Latin American), Japanese, Mandarin, etc. (Extensible based on Eleven Labs language support).

* Control: Searchable dropdown with geographical flags/icons.

  • Language:

* Options: A comprehensive list of languages supported by Eleven Labs (e.g., English, Spanish, French, German, Italian, Portuguese, Polish, Turkish, Dutch, Japanese, Korean, Hindi, Indonesian, Ukrainian, Arabic, Czech, Danish, Finnish, Greek, Hebrew, Hungarian, Malay, Norwegian, Romanian, Slovak, Swedish, Thai, Vietnamese, Traditional Chinese, Simplified Chinese).

* Control: Dropdown menu.

1.2 Vocal Qualities & Parameters

  • Pitch:

* Description: How high or low the voice sounds.

* Control: Slider (e.g., -50% to +50%) with "Lower" to "Higher" labels.

  • Tone/Timbre:

* Description: The quality or character of the voice (e.g., warm, bright, rich, clear, husky, resonant).

* Control: Multiple choice checkboxes/radio buttons or a multi-dimensional slider/grid for nuanced selection.

  • Pace/Speed:

* Description: How fast or slow the speaker talks.

* Control: Slider (e.g., -50% to +50%) with "Slow" to "Fast" labels.

  • Volume/Loudness:

* Description: The perceived loudness of the voice.

* Control: Slider (e.g., -50% to +50%) with "Soft" to "Loud" labels.

  • Resonance:

* Description: The richness and depth of the voice, affecting its carrying power.

* Control: Slider from "Thin" to "Resonant."

  • Breathiness:

* Description: The amount of air audible in the voice.

* Control: Slider from "Clear" to "Breathy."

  • Vocal Fry/Creak:

* Description: The lowest vocal register, producing a creaky sound.

* Control: Slider from "None" to "Prominent."

  • Articulation:

* Description: The clarity and precision of speech.

* Control: Slider from "Mumbled" to "Crisp."

1.3 Emotional Range & Persona

  • Emotional Tendency:

* Options: Calm, Energetic, Friendly, Authoritative, Empathetic, Enthusiastic, Serious, Playful, Mysterious, Robotic, etc. (Multi-select encouraged).

* Control: Checkboxes or tags, potentially with a "Dominant Emotion" slider.

  • Speech Style:

* Options: Conversational, Broadcast, Narration, Announcement, Storyteller, Academic, Explainer.

* Control: Radio buttons or multi-select dropdown.

1.4 Custom Description & AI Assistance

  • Free-form Text Description:

* Input: A large text area where users can describe the voice in natural language (e.g., "I want a voice like a wise old wizard, deep and resonant, but with a friendly, slightly mischievous tone, suitable for narrating fantasy stories.").

* AI Interpretation: The system will process this text to refine and suggest parameter adjustments.

  • AI Suggestions/Refinements:

* Based on user input, the AI can suggest common voice archetypes or specific parameter adjustments.

* "Feeling stuck? Try a 'Podcast Host' or 'Documentary Narrator' preset!"

1.5 Reference Audio (Optional)

  • Upload Audio:

* Functionality: Allow users to upload a short audio clip (e.g., 5-30 seconds) of a voice they want to emulate or use as a reference point.

* Supported Formats: MP3, WAV, FLAC.

* AI Analysis: The system analyzes the uploaded audio to extract vocal characteristics and automatically adjust the design parameters.

  • Link to Existing Voice:

* Functionality: Option to link to an existing voice from Eleven Labs' Voice Library or a custom voice they've previously created, and then modify it.


2. Wireframe Descriptions for the UI

The AI Voice Designer will be presented as a multi-section or multi-step interface, guiding the user through the process with clear visual feedback.

2.1 Main Dashboard/Entry Point

  • Layout: A landing page with a prominent "Create New Voice" button, a list of "My Saved Voices," and possibly "Featured Presets."
  • Elements:

* Header: "AI Voice Designer" title.

* Call to Action: Large button: "Start Designing Your Voice."

* Saved Voices: Card-based display of previously designed voices, with options to "Edit," "Use," "Duplicate," "Delete."

* Preset Voices (Optional): Categories like "Narrators," "Customer Service," "Characters," each with sample audio.

2.2 Voice Design Interface (Multi-Section / Tabbed Layout)

This will be the core screen where the voice is designed.

Section 1: Basic Attributes (Left Panel / First Tab)

  • Layout: Clear, easy-to-understand input fields.
  • Elements:

* Gender: Radio buttons (Male, Female, Androgynous) with icons.

* Age Range: Slider or dropdown.

* Language: Dropdown with search.

* Accent/Dialect: Searchable dropdown with flags.

* "Next" Button: To proceed to the next section/tab.

Section 2: Vocal Qualities (Middle Panel / Second Tab)

  • Layout: Sliders prominently displayed, with clear labels and tooltips for explanation.
  • Elements:

* Pitch: Slider (-50% to +50%).

* Pace: Slider (-50% to +50%).

* Volume: Slider (-50% to +50%).

* Tone: Multi-select checkboxes (e.g., Warm, Bright, Husky, Clear).

* Resonance: Slider (Thin to Resonant).

* Breathiness: Slider (Clear to Breathy).

* Vocal Fry: Slider (None to Prominent).

* Articulation: Slider (Mumbled to Crisp).

* "Next" Button: To proceed.

Section 3: Persona & Style (Right Panel / Third Tab)

  • Layout: Checkboxes and text input.
  • Elements:

* Emotional Tendency: Checkbox grid (e.g., Calm, Energetic, Friendly, Authoritative).

* Speech Style: Radio buttons (Conversational, Broadcast, Narration).

* Free-form Description: Text area for natural language input. "Describe your ideal voice..."

* AI Suggestion Button: "Generate Suggestions" based on text input.

* "Next" Button: To proceed.

Section 4: Reference Audio (Optional) (Fourth Tab)

  • Layout: Upload area with instructions.
  • Elements:

* Drag & Drop Area: "Upload an audio file (MP3, WAV, FLAC)" with a file size limit.

* Link Input: Text field for "Link to a voice sample."

* "Analyze Audio" Button: Triggers AI analysis and parameter adjustment.

* "Skip" or "Next" Button.

2.3 Preview & Refine Panel (Persistent Side Panel or Bottom Bar)

  • Layout: Always visible, allowing real-time testing.
  • Elements:

* Text Input: Text area for "Enter text to preview your voice" (e.g., 50-200 characters limit).

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

* Loading Indicator: During audio generation.

* Voice Name Input: Field to name the custom voice.

* "Save Voice" Button: To save the current configuration.

* "Reset" Button: To clear all parameters and start over.

* "Download Sample" Button: To download the preview audio.


3. Color Palettes

We recommend a professional, clean, and intuitive color scheme that promotes focus on the creative process.

Palette 1: Professional & Modern

  • Primary Accent: #007AFF (Vibrant Blue - for CTAs, selected states)
  • Secondary/Highlight: #5AC8FA (Lighter Blue - for active elements, subtle highlights)
  • Backgrounds:

* #F8F8F8 (Light Grey - main content areas)

* #FFFFFF (Pure White - card backgrounds, modals)

  • Text:

* #333333 (Dark Grey - primary text)

* #666666 (Medium Grey - secondary text, descriptions)

* #999999 (Light Grey - placeholder text, disabled states)

  • Borders/Dividers: #E0E0E0 (Soft Grey)
  • Feedback Colors:

* Success: #4CAF50 (Green)

* Error: #F44336 (Red)

* Warning: #FFC107 (Amber)

Palette 2: Calm & Creative

  • Primary Accent: #673AB7 (Deep Purple - for CTAs, main interactive elements)
  • Secondary/Highlight: #9C27B0 (Magenta Purple - for active states, subtle accents)
  • Backgrounds:

* #F0F2F5 (Very Light Blue-Grey - main content areas)

* #FFFFFF (Pure White - card backgrounds, input fields)

  • Text:

* #212121 (Dark Grey - primary text)

* #757575 (Medium Grey - secondary text)

* #BDBDBD (Light Grey - placeholder text)

  • Borders/Dividers: #E0E0E0 (Soft Grey)
  • Feedback Colors: (Same as Palette 1 for consistency)

4. UX Recommendations

4.1 Clarity and Simplicity

  • Intuitive Labels: Use clear, descriptive language for all parameters and controls. Avoid technical jargon where possible.
  • Tooltips & Explanations: Provide "i" icons with tooltips for complex parameters, offering brief explanations and examples (e.g., what "Resonance" means for a voice).
  • Visual Hierarchy: Use size, color, and spacing to guide the user's eye and highlight important actions.

4.2 Real-time Feedback & Iteration

  • Instant Audio Preview: The most critical UX element. Allow users to type text and hear their custom voice immediately as they adjust parameters. This creates a highly engaging and iterative design loop.
  • Parameter Impact: When a user adjusts a slider, the preview text-to-speech should reflect that change as quickly as possible.
  • Save & Load: Enable users to save multiple versions of their custom voices and easily load them for further refinement.

4.3 Guidance and Presets

  • Starting Points: Offer a selection of "Voice Presets" (e.g., "Standard Male Narrator," "Friendly Female AI," "Deep Storyteller") as starting points that users can then modify.
  • AI-Driven Suggestions: Leverage AI to provide intelligent suggestions based on user input (e.g., "You described a 'wise old wizard' – consider increasing 'Resonance' and lowering 'Pitch'").
  • Onboarding Tour: For first-time users, a brief interactive tour highlighting key features and the design flow can be beneficial.

4.4 Accessibility

  • High Contrast: Ensure sufficient color contrast between text and background for readability.
  • Keyboard Navigation: All interactive elements should be reachable and operable via keyboard.
  • ARIA Labels: Implement ARIA attributes for screen readers to provide context for visually impaired users.

4.5 Error Handling & Validation

  • Clear Error Messages: If an audio upload fails or parameters conflict, provide clear, actionable error messages.
  • Input Validation: Validate text inputs (e.g., character limits for preview text).

4.6 Progressive Disclosure

  • Basic vs. Advanced: Start with essential parameters and offer an "Advanced Settings" toggle to reveal more granular controls, preventing information overload for new users.
  • Multi-Step Flow: A multi-step or tabbed interface helps break down the complex task of voice design into manageable chunks.

4.7 Performance

  • Fast Generation: Optimize the backend for rapid audio generation during preview to ensure a smooth user experience.
  • Responsive UI: The interface should be responsive and perform well across different devices and screen sizes.

By adhering to these detailed specifications, wireframe concepts, color choices, and UX principles, the AI Voice Designer will offer a powerful, intuitive, and enjoyable experience

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
\n\n\n"); 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'\nimport ReactDOM from 'react-dom/client'\nimport App from './App'\nimport './index.css'\n\nReactDOM.createRoot(document.getElementById('root')!).render(\n \n \n \n)\n"); 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'\nimport './App.css'\n\nfunction App(){\n return(\n
\n
\n

"+slugTitle(pn)+"

\n

Built with PantheraHive BOS

\n
\n
\n )\n}\nexport default App\n"); zip.file(folder+"src/index.css","*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;background:#f0f2f5;color:#1a1a2e}\n.app{min-height:100vh;display:flex;flex-direction:column}\n.app-header{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:40px}\nh1{font-size:2.5rem;font-weight:700}\n"); 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)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nnpm run dev\n\`\`\`\n\n## Build\n\`\`\`bash\nnpm run build\n\`\`\`\n\n## Open in IDE\nOpen the project folder in VS Code or WebStorm.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n"); } /* --- 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",'{\n "name": "'+pn+'",\n "version": "0.0.0",\n "type": "module",\n "scripts": {\n "dev": "vite",\n "build": "vue-tsc -b && vite build",\n "preview": "vite preview"\n },\n "dependencies": {\n "vue": "^3.5.13",\n "vue-router": "^4.4.5",\n "pinia": "^2.3.0",\n "axios": "^1.7.9"\n },\n "devDependencies": {\n "@vitejs/plugin-vue": "^5.2.1",\n "typescript": "~5.7.3",\n "vite": "^6.0.5",\n "vue-tsc": "^2.2.0"\n }\n}\n'); zip.file(folder+"vite.config.ts","import { defineConfig } from 'vite'\nimport vue from '@vitejs/plugin-vue'\nimport { resolve } from 'path'\n\nexport default defineConfig({\n plugins: [vue()],\n resolve: { alias: { '@': resolve(__dirname,'src') } }\n})\n"); zip.file(folder+"tsconfig.json",'{"files":[],"references":[{"path":"./tsconfig.app.json"},{"path":"./tsconfig.node.json"}]}\n'); zip.file(folder+"tsconfig.app.json",'{\n "compilerOptions":{\n "target":"ES2020","useDefineForClassFields":true,"module":"ESNext","lib":["ES2020","DOM","DOM.Iterable"],\n "skipLibCheck":true,"moduleResolution":"bundler","allowImportingTsExtensions":true,\n "isolatedModules":true,"moduleDetection":"force","noEmit":true,"jsxImportSource":"vue",\n "strict":true,"paths":{"@/*":["./src/*"]}\n },\n "include":["src/**/*.ts","src/**/*.d.ts","src/**/*.tsx","src/**/*.vue"]\n}\n'); zip.file(folder+"env.d.ts","/// \n"); zip.file(folder+"index.html","\n\n\n \n \n "+slugTitle(pn)+"\n\n\n
\n \n\n\n"); 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'\nimport { createPinia } from 'pinia'\nimport App from './App.vue'\nimport './assets/main.css'\n\nconst app = createApp(App)\napp.use(createPinia())\napp.mount('#app')\n"); var hasApp=Object.keys(extracted).some(function(k){return k.indexOf("App.vue")>=0;}); if(!hasApp) zip.file(folder+"src/App.vue","\n\n\n\n\n"); 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}\n"); 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)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nnpm run dev\n\`\`\`\n\n## Build\n\`\`\`bash\nnpm run build\n\`\`\`\n\nOpen in VS Code or WebStorm.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n"); } /* --- 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",'{\n "name": "'+pn+'",\n "version": "0.0.0",\n "scripts": {\n "ng": "ng",\n "start": "ng serve",\n "build": "ng build",\n "test": "ng test"\n },\n "dependencies": {\n "@angular/animations": "^19.0.0",\n "@angular/common": "^19.0.0",\n "@angular/compiler": "^19.0.0",\n "@angular/core": "^19.0.0",\n "@angular/forms": "^19.0.0",\n "@angular/platform-browser": "^19.0.0",\n "@angular/platform-browser-dynamic": "^19.0.0",\n "@angular/router": "^19.0.0",\n "rxjs": "~7.8.0",\n "tslib": "^2.3.0",\n "zone.js": "~0.15.0"\n },\n "devDependencies": {\n "@angular-devkit/build-angular": "^19.0.0",\n "@angular/cli": "^19.0.0",\n "@angular/compiler-cli": "^19.0.0",\n "typescript": "~5.6.0"\n }\n}\n'); zip.file(folder+"angular.json",'{\n "$schema": "./node_modules/@angular/cli/lib/config/schema.json",\n "version": 1,\n "newProjectRoot": "projects",\n "projects": {\n "'+pn+'": {\n "projectType": "application",\n "root": "",\n "sourceRoot": "src",\n "prefix": "app",\n "architect": {\n "build": {\n "builder": "@angular-devkit/build-angular:application",\n "options": {\n "outputPath": "dist/'+pn+'",\n "index": "src/index.html",\n "browser": "src/main.ts",\n "tsConfig": "tsconfig.app.json",\n "styles": ["src/styles.css"],\n "scripts": []\n }\n },\n "serve": {"builder":"@angular-devkit/build-angular:dev-server","configurations":{"production":{"buildTarget":"'+pn+':build:production"},"development":{"buildTarget":"'+pn+':build:development"}},"defaultConfiguration":"development"}\n }\n }\n }\n}\n'); zip.file(folder+"tsconfig.json",'{\n "compileOnSave": false,\n "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"]},\n "references":[{"path":"./tsconfig.app.json"}]\n}\n'); zip.file(folder+"tsconfig.app.json",'{\n "extends":"./tsconfig.json",\n "compilerOptions":{"outDir":"./dist/out-tsc","types":[]},\n "files":["src/main.ts"],\n "include":["src/**/*.d.ts"]\n}\n'); zip.file(folder+"src/index.html","\n\n\n \n "+slugTitle(pn)+"\n \n \n \n\n\n \n\n\n"); zip.file(folder+"src/main.ts","import { bootstrapApplication } from '@angular/platform-browser';\nimport { appConfig } from './app/app.config';\nimport { AppComponent } from './app/app.component';\n\nbootstrapApplication(AppComponent, appConfig)\n .catch(err => console.error(err));\n"); zip.file(folder+"src/styles.css","* { margin: 0; padding: 0; box-sizing: border-box; }\nbody { font-family: system-ui, -apple-system, sans-serif; background: #f9fafb; color: #111827; }\n"); 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';\nimport { RouterOutlet } from '@angular/router';\n\n@Component({\n selector: 'app-root',\n standalone: true,\n imports: [RouterOutlet],\n templateUrl: './app.component.html',\n styleUrl: './app.component.css'\n})\nexport class AppComponent {\n title = '"+pn+"';\n}\n"); zip.file(folder+"src/app/app.component.html","
\n
\n

"+slugTitle(pn)+"

\n

Built with PantheraHive BOS

\n
\n \n
\n"); 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}\n"); } zip.file(folder+"src/app/app.config.ts","import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';\nimport { provideRouter } from '@angular/router';\nimport { routes } from './app.routes';\n\nexport const appConfig: ApplicationConfig = {\n providers: [\n provideZoneChangeDetection({ eventCoalescing: true }),\n provideRouter(routes)\n ]\n};\n"); zip.file(folder+"src/app/app.routes.ts","import { Routes } from '@angular/router';\n\nexport const routes: Routes = [];\n"); 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)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nng serve\n# or: npm start\n\`\`\`\n\n## Build\n\`\`\`bash\nng build\n\`\`\`\n\nOpen in VS Code with Angular Language Service extension.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n.angular/\n"); } /* --- Python --- */ function buildPython(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^\`\`\`[\w]*\n?/m,"").replace(/\n?\`\`\`$/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("\n"):"# add dependencies here\n"; zip.file(folder+"main.py",src||"# "+title+"\n# Generated by PantheraHive BOS\n\nprint(title+\" loaded\")\n"); zip.file(folder+"requirements.txt",reqsTxt); zip.file(folder+".env.example","# Environment variables\n"); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\npython3 -m venv .venv\nsource .venv/bin/activate\npip install -r requirements.txt\n\`\`\`\n\n## Run\n\`\`\`bash\npython main.py\n\`\`\`\n"); zip.file(folder+".gitignore",".venv/\n__pycache__/\n*.pyc\n.env\n.DS_Store\n"); } /* --- Node.js --- */ function buildNode(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^\`\`\`[\w]*\n?/m,"").replace(/\n?\`\`\`$/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)+"\n"; zip.file(folder+"package.json",pkgJson); var fallback="const express=require(\"express\");\nconst app=express();\napp.use(express.json());\n\napp.get(\"/\",(req,res)=>{\n res.json({message:\""+title+" API\"});\n});\n\nconst PORT=process.env.PORT||3000;\napp.listen(PORT,()=>console.log(\"Server on port \"+PORT));\n"; zip.file(folder+"src/index.js",src||fallback); zip.file(folder+".env.example","PORT=3000\n"); zip.file(folder+".gitignore","node_modules/\n.env\n.DS_Store\n"); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\n\`\`\`\n\n## Run\n\`\`\`bash\nnpm run dev\n\`\`\`\n"); } /* --- 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:"\n\n\n\n\n"+title+"\n\n\n\n"+code+"\n\n\n\n"; zip.file(folder+"index.html",indexHtml); zip.file(folder+"style.css","/* "+title+" — styles */\n*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;background:#fff;color:#1a1a2e}\n"); zip.file(folder+"script.js","/* "+title+" — scripts */\n"); zip.file(folder+"assets/.gitkeep",""); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Open\nDouble-click \`index.html\` in your browser.\n\nOr serve locally:\n\`\`\`bash\nnpx serve .\n# or\npython3 -m http.server 3000\n\`\`\`\n"); zip.file(folder+".gitignore",".DS_Store\nnode_modules/\n.env\n"); } /* ===== 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(/\n{2,}/g,"

"); h+="

"+hc+"

Generated by PantheraHive BOS
"; zip.file(folder+app+".html",h); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\nFiles:\n- "+app+".md (Markdown)\n- "+app+".html (styled HTML)\n"); } 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);}});}