Domain Strategy Planner
Run ID: 69cbe18361b1021a29a8d1c52026-03-31Domain Management
PantheraHive BOS
BOS Dashboard

AI-powered domain strategy analysis, renewal planning, and DNS configuration guide

Domain Strategy Planner: Portfolio Scan Results & Initial Analysis

Workflow Step: domaintrackerscan_portfolio

Description: Comprehensive analysis of your existing domain portfolio, identifying key attributes, potential risks, and strategic opportunities.


1. Executive Summary

This report presents the initial scan of your domain portfolio, providing a foundational understanding of your digital asset landscape. We've identified key registration details, expiration statuses, registrar diversity, and DNS configurations. The scan highlights critical areas requiring immediate attention, such as upcoming expirations and inconsistent management practices, while also laying the groundwork for strategic consolidation and optimization in the subsequent steps.

2. Simulated Domain Portfolio Scan Results

Below is a detailed overview of your identified domain assets. Please note that for this initial simulation, we have generated example data to illustrate the type of information gathered. In a live execution, this table would be populated with your actual domain data.

| Domain Name | Registrar | Registration Date | Expiration Date | Auto-Renew | WHOIS Privacy | DNS Servers (Nameservers) | Status | Notes |

| :----------------------- | :------------------ | :---------------- | :-------------- | :--------- | :------------ | :------------------------------ | :---------- | :--------------------------------------- |

| examplecorp.com | GoDaddy | 2015-03-10 | 2025-03-10 | Enabled | Yes | ns1.exampledns.com, ns2.exampledns.com | Active | Primary brand domain |

| examplecorp.net | GoDaddy | 2016-07-22 | 2024-07-22 | Enabled | Yes | ns1.exampledns.com, ns2.exampledns.com | Active | Secondary brand domain |

| examplecorp-solutions.com | Namecheap | 2018-01-15 | 2024-06-01 | Disabled | Yes | ns1.namecheaphosting.com, ns2.namecheaphosting.com | Active | Upcoming expiration, auto-renew disabled |

| examplecorp-blog.info | 1&1 IONOS | 2017-09-01 | 2023-11-15 | Disabled | No | ns1.ionos.com, ns2.ionos.com | Expired | Potential legacy asset, no privacy |

| examplecorp.io | Cloudflare Registrar | 2023-05-20 | 2025-05-20 | Enabled | Yes | ns1.cloudflare.com, ns2.cloudflare.com | Active | New project, using Cloudflare DNS |

| examplecorp.co.uk | 123-Reg | 2019-11-05 | 2024-11-05 | Enabled | Yes | ns1.123-reg.co.uk, ns2.123-reg.co.uk | Active | Geo-specific domain |

| marketing-campaign.com | Google Domains | 2022-04-12 | 2024-08-12 | Disabled | Yes | ns1.googledomains.com, ns2.googledomains.com | Active | Temporary campaign, auto-renew disabled |

3. Portfolio Overview & Key Metrics

Based on the simulated scan, here's a high-level summary of your domain portfolio:

  • Total Domains Scanned: 7
  • Active Domains: 6
  • Expired Domains: 1 (examplecorp-blog.info)
  • Domains with Auto-Renew Enabled: 4 (57%)
  • Domains with Auto-Renew Disabled: 3 (43%)
  • Domains with WHOIS Privacy Enabled: 6 (86%)
  • Domains with WHOIS Privacy Disabled: 1 (14%)
  • Number of Unique Registrars: 5 (GoDaddy, Namecheap, 1&1 IONOS, Cloudflare Registrar, 123-Reg, Google Domains)
  • Upcoming Expirations (within 6 months): 3 (examplecorp.net, examplecorp-solutions.com, marketing-campaign.com)
  • Primary DNS Providers Identified: exampledns, Namecheap Hosting, IONOS, Cloudflare, 123-Reg, Google Domains

4. Detailed Analysis & Observations

4.1. Expiration Management & Risk Assessment

  • Critical Risk: examplecorp-solutions.com has an upcoming expiration on 2024-06-01 and auto-renew is disabled. This is a high-priority item as failure to renew could lead to loss of the domain and associated services.
  • Moderate Risk: examplecorp.net (expiring 2024-07-22) and marketing-campaign.com (expiring 2024-08-12) also have upcoming expirations. While examplecorp.net has auto-renew enabled, marketing-campaign.com does not. Proactive review is recommended for both.
  • Expired Domain: examplecorp-blog.info expired on 2023-11-15. This domain is currently in a redemption or grace period, or has already been released. Immediate action is required to either recover it (if still possible and desired) or confirm its permanent release from your portfolio.

4.2. Registrar Diversity & Management Overhead

  • Observation: Your portfolio is spread across 5 different registrars (GoDaddy, Namecheap, 1&1 IONOS, Cloudflare Registrar, Google Domains).
  • Implication: This diversity can lead to increased administrative overhead, fragmented billing, varying security practices, and potential for missed renewals due to managing multiple dashboards and notification systems.
  • Opportunity: Consolidating domains under fewer, preferred registrars can streamline management, improve security posture, and potentially reduce costs.

4.3. DNS Configuration & Performance

  • Observation: DNS services are also fragmented across multiple providers, often tied to their respective registrars (e.g., GoDaddy's DNS, Namecheap's DNS, Cloudflare DNS, Google Domains DNS, 123-Reg DNS, IONOS DNS).
  • Implication: Inconsistent DNS management can lead to varying performance, complexity in updating records, and potential security vulnerabilities if not all DNS providers offer advanced features (e.g., DNSSEC, DDoS protection).
  • Opportunity: Centralizing DNS management with a robust, performant, and secure provider (like Cloudflare, AWS Route 53, or Google Cloud DNS) can enhance reliability, speed, and security across your entire domain portfolio.

4.4. WHOIS Privacy & Security

  • Observation: One domain, examplecorp-blog.info, does not have WHOIS privacy enabled.
  • Implication: Lack of WHOIS privacy exposes the domain owner's personal or organizational contact information, making them susceptible to spam, phishing attempts, and unwanted solicitations.
  • Recommendation: Unless there's a specific legal requirement (e.g., for certain TLDs or business types), WHOIS privacy should be enabled for all domains to protect sensitive information.

5. Initial Recommendations & Actionable Insights

Based on this preliminary scan, we recommend the following immediate actions:

  1. Address Critical Expirations:

* Immediately review examplecorp-solutions.com: Determine if this domain is still critical for your operations. If so, enable auto-renew and manually renew it as soon as possible.

* Investigate examplecorp-blog.info: Confirm if this expired domain is still needed. If not, ensure it is fully decommissioned from your records. If it is needed, explore options for recovery with 1&1 IONOS.

* Review marketing-campaign.com: Decide if this campaign domain needs to be renewed. If so, enable auto-renew or plan for manual renewal.

  1. Enhance Security Posture:

* Enable WHOIS Privacy: For examplecorp-blog.info (if recovered) and any future domains, ensure WHOIS privacy is enabled by default to protect your contact information.

  1. Strategic Registrar Consolidation (Planning Phase):

* Identify Preferred Registrar(s): Begin evaluating your existing registrars and identify 1-2 preferred providers that offer competitive pricing, robust features, and excellent support.

* Plan Transfers: For domains managed by less preferred registrars, start planning the transfer process to consolidate them under your chosen provider(s). This will be further detailed in Step 2.

  1. Centralize DNS Management (Planning Phase):

* Evaluate Centralized DNS Providers: Research options for a unified DNS management solution that can handle all your domains efficiently and securely.

* Plan DNS Migration: Prepare for migrating your domain's nameservers to a central DNS provider. This will be further detailed in Step 2.

6. Next Steps: Strategic Planning & Implementation

The insights from this portfolio scan will now feed into the next phase of the "Domain Strategy Planner" workflow: domainstrategyplan_optimization.

In the next step, we will:

  • Develop a detailed domain renewal strategy including auto-renewal policies and budget forecasting.
  • Outline a plan for registrar consolidation, including cost-benefit analysis and migration steps.
  • Propose a centralized DNS management strategy, focusing on improved performance, security (DNSSEC), and ease of management.
  • Provide guidance on domain acquisition and divestiture strategies.
  • Generate a comprehensive action plan with timelines and responsibilities.
domaintracker Output

Domain Strategy Planner: Comprehensive Analysis & Action Plan

Date: October 26, 2023

Prepared For: Valued Customer

Prepared By: PantheraHive AI


Executive Summary

This report provides a comprehensive analysis of your current domain portfolio, strategic recommendations for optimizing domain management, enhancing security, and improving DNS configuration. Our findings indicate opportunities to streamline renewal processes, fortify your online presence against evolving threats, and leverage your domain assets more effectively for brand protection and digital strategy.

Key recommendations include implementing robust auto-renewal protocols, consolidating domain registrars where beneficial, enforcing advanced email authentication (DMARC), and regularly auditing your domain portfolio for strategic alignment and potential divestment. By adopting these recommendations, you can achieve greater operational efficiency, reduce risk, and strengthen your overall digital infrastructure.


1. Domain Portfolio Overview & Health Check

A healthy and well-managed domain portfolio is fundamental to your online identity and operational continuity. This section provides an overview of typical portfolio characteristics and key health metrics.

1.1 Current Portfolio Summary (Illustrative Data)

  • Total Domains: 25 (e.g., yourbrand.com, yourbrand.net, yourbrand-services.com, yourbrand-asia.com, yourbrand.io, yourbrandapp.com)
  • Primary TLDs: .com (50%), .net (15%), .org (10%), .io (10%), .co (5%), Other new gTLDs (10%)
  • Registrars Utilized: 3 (e.g., GoDaddy, Namecheap, Cloudflare Registrar)
  • Average Domain Age: 5 years
  • Domains with WHOIS Privacy: 70%
  • Domains with Auto-Renewal Enabled: 60%
  • Domains Expiring in Next 90 Days: 3 (e.g., yourbrand.io, yourbrand-asia.com, yourbrandapp.com)

1.2 Domain Health Metrics & Key Findings

| Metric | Status/Insight | Recommendation

domain_strategy_planner.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);}});}