popiart-server
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

783 lines
33 KiB

document.addEventListener("DOMContentLoaded", function () {
const sourceMap = captureSourceMap();
let currentLocale = getInitialLocale();
let heroRotationTimer = null;
const copyMessages = {
zh: { copy: "复制", copied: "已复制", failed: "复制失败" },
en: { copy: "Copy", copied: "Copied", failed: "Copy failed" }
};
const enTranslations = {
"common.nav.home": "Home",
"common.nav.docs": "Docs",
"common.nav.skills": "Skills",
"common.nav.console": "Console",
"common.nav.pricing": "Pricing",
"common.login": "Sign in",
"common.logout": "Sign out",
"index.meta.title": "Popi.art SkillHub",
"index.meta.description": "Static bilingual prototype for Popi.art SkillHub, written from popiartcli and Popiart_skillhub.",
"index.hero.catalogCard": `
<div class="eyebrow">OFFICIAL SKILLHUB</div>
<h3>Official skill catalog</h3>
<p>
The public registry comes from <code>Popiart_skillhub</code>. It currently exposes 59 skills across image, video, and audio.
</p>
`,
"index.hero.baselineCard": `
<div class="eyebrow">RUNTIME BASELINE</div>
<h4>3 official runtime baselines</h4>
<p>text2image / img2img / image2video</p>
`,
"index.hero.mcpCard": `
<div class="eyebrow">MCP</div>
<h4>discoverable tool surface</h4>
<p>list_skills / run_skill / get_job / pull_artifact</p>
`,
"index.hero.showcaseCard": `
<div class="eyebrow">SHOWCASE</div>
<h4>PopiStudio Alice</h4>
<p>The character-consistency showcase skill is already visible in the public catalog.</p>
`,
"index.hero.copy": `
<div class="eyebrow">POP I . ART</div>
<h1>Creator skill entry for <span>Coding Agents</span></h1>
<p>
<code>popiartcli</code> owns the unified CLI entrypoint, auth, skill discovery, run, jobs, artifacts, and MCP discoverability; <code>Popiart_skillhub</code> owns the public catalog and skill descriptions.
</p>
<div class="hero-actions">
<a class="button button-primary" href="./skillhub_docs.html">Quick start</a>
<a class="button button-secondary" href="./skillhub_skills.html">Browse skills</a>
</div>
<div class="hero-proof">
<span class="pill">59 public skills</span>
<span class="pill">Image / Video / Audio</span>
<span class="pill" data-hero-phrases='["text2image · img2img","image2video · text2video","tts · stt · dubbing","bootstrap · mcp · artifacts"]'>text2image · img2img</span>
</div>
`,
"index.surfaces.heading": `
<div class="eyebrow">PRODUCT SURFACES</div>
<h2>Today’s product surface is grounded in <span>CLI + SkillHub</span></h2>
<p>The homepage is organized around real command surfaces, catalog facts, and execution boundaries instead of vague product copy.</p>
`,
"index.surfaces.metricTotal": "public skills",
"index.surfaces.metricAudio": "audio skills",
"index.surfaces.metricImage": "image skills",
"index.surfaces.metricVideo": "video skills",
"index.scenarios.heading": `
<div class="eyebrow">SCENARIOS</div>
<h2>High-value scenarios extracted from the catalog</h2>
<p>These names stay close to the real skill ids, categories, and capabilities in <code>Popiart_skillhub</code>.</p>
`,
"index.scenarios.card1": `
<div class="eyebrow">IMAGE</div>
<h3>Text2Image</h3>
<p>Built around <code>popiskill-image-text2image-*</code> for prompt-driven image generation, character sheets, three-view, and stylized artwork.</p>
<a class="scene-link" href="./skillhub_skills.html">View image skills</a>
`,
"index.scenarios.card2": `
<div class="eyebrow">IMAGE</div>
<h3>Img2Img</h3>
<p>Includes baseline image editing, localized retouching, and the PopiStudio Alice consistency showcase workflow.</p>
<a class="scene-link" href="./skillhub_skills.html">View img2img</a>
`,
"index.scenarios.card3": `
<div class="eyebrow">VIDEO</div>
<h3>Image2Video</h3>
<p>One of the official runtime baselines, ideal for turning still frames into short teasers and motion clips.</p>
<a class="scene-link" href="./skillhub_skills.html">View video skills</a>
`,
"index.scenarios.card4": `
<div class="eyebrow">VIDEO</div>
<h3>Text2Video</h3>
<p>The catalog already includes text2video definitions across kling, sora2pro, and studio-oriented variants.</p>
<a class="scene-link" href="./skillhub_skills.html">View text2video</a>
`,
"index.scenarios.card5": `
<div class="eyebrow">AUDIO</div>
<h3>TTS / Voice</h3>
<p>Covers doubao, ima-studio, multimodel, and voice-engineer style speech output workflows.</p>
<a class="scene-link" href="./skillhub_skills.html">View audio skills</a>
`,
"index.scenarios.card6": `
<div class="eyebrow">AUDIO</div>
<h3>STT / Dubbing</h3>
<p>The catalog already includes local speech recognition, video transcription, translation, and localization-related skills.</p>
<a class="scene-link" href="./skillhub_skills.html">View STT & dubbing</a>
`,
"index.scenarios.card7": `
<div class="eyebrow">MCP</div>
<h3>Agent Discoverability</h3>
<p><code>popiart mcp serve / print-config / doctor</code> already forms a practical tool surface for agent integration.</p>
<a class="scene-link" href="./skillhub_docs.html">Read MCP docs</a>
`,
"index.scenarios.card8": `
<div class="eyebrow">BOOTSTRAP</div>
<h3>Bootstrap & Seed Skills</h3>
<p>The CLI generates discoverability assets and merges bundled seed skills into the query path.</p>
<a class="scene-link" href="./skillhub_docs.html">View bootstrap</a>
`,
"index.flow.heading": `
<div class="eyebrow">INTEGRATION FLOW</div>
<h2>Real integration flow</h2>
<p>No invented commands. The first-screen product story follows the commands already implemented in <code>popiartcli</code>.</p>
`,
"index.flow.step1": `
<div class="step-number">01</div>
<h3>Install the CLI</h3>
<p>Supports Homebrew, install.sh, PowerShell, and source build. The main distribution path is the Go CLI.</p>
`,
"index.flow.step2": `
<div class="step-number">02</div>
<h3>Bootstrap the agent</h3>
<p>Use <code>bootstrap --discoverable</code> to generate shell completion, MCP config snippets, and seed skill profile assets.</p>
`,
"index.flow.step3": `
<div class="step-number">03</div>
<h3>Auth & discover</h3>
<p>Sign in with the product-layer key, then use <code>skills list/get/schema</code> to discover merged remote and local skills.</p>
`,
"index.flow.step4": `
<div class="step-number">04</div>
<h3>Run / Jobs / Artifacts</h3>
<p>Tasks always return a <code>job_id</code>, long jobs are polled, and outputs are recovered through <code>artifacts pull</code>.</p>
`,
"index.cta.text": `
<div class="eyebrow">NEXT STEP</div>
<strong>Continue to docs, skills, and the console prototype</strong>
`,
"index.footer.title": "Popi.art SkillHub Static Prototype",
"index.footer.subtitle": "Content is rewritten from <code>popiartcli</code> and <code>Popiart_skillhub</code>, with layout references from <code>open-claw</code>.",
"docs.meta.title": "Popi.art Docs",
"docs.meta.description": "Bilingual static documentation prototype for Popi.art CLI and SkillHub.",
"docs.heading": `
<div class="eyebrow">DOCUMENTATION</div>
<h2>Documentation written from the <span>real CLI surface</span></h2>
<p>This page is sourced from the <code>popiartcli</code> README, current status notes, and command tree. It does not invent future commands.</p>
`,
"docs.toc": `
<div class="eyebrow">ON THIS PAGE</div>
<ul class="toc-list">
<li><a href="#install">Install</a></li>
<li><a href="#quick-start">Quick start</a></li>
<li><a href="#commands">Commands</a></li>
<li><a href="#mcp">MCP</a></li>
<li><a href="#baseline">Runtime baseline</a></li>
</ul>
`,
"docs.install": `
<div class="eyebrow">INSTALL</div>
<h3>Installation methods</h3>
<p>The current <code>popiartcli</code> README explicitly lists Homebrew, curl/install.sh, PowerShell, and source build as supported install paths.</p>
<div class="code-block">
<div class="code-head">
<span>Homebrew</span>
<button class="button copy-button" data-copy-target="docs-install-brew" type="button">Copy</button>
</div>
<pre><code id="docs-install-brew">brew tap wtgoku-create/popi
brew install wtgoku-create/popi/popiart
popiart bootstrap --agent codex --discoverable</code></pre>
</div>
<div class="code-block">
<div class="code-head">
<span>Source Build</span>
<button class="button copy-button" data-copy-target="docs-install-source" type="button">Copy</button>
</div>
<pre><code id="docs-install-source">git clone https://github.com/wtgoku-create/popiartcli.git
cd popiartcli
go install ./cmd/popiart
popiart --help</code></pre>
</div>
`,
"docs.quickstart": `
<div class="eyebrow">QUICK START</div>
<h3>Quick start</h3>
<p>The smallest closed loop is: install the CLI, sign in, discover a skill, run a task, poll jobs, and pull artifacts.</p>
<div class="code-block">
<div class="code-head">
<span>Quick Start</span>
<button class="button copy-button" data-copy-target="docs-quick-start" type="button">Copy</button>
</div>
<pre><code id="docs-quick-start">popiart auth login --key pk-...
popiart skills list --tag image
popiart run popiskill-image-text2image-basic-v1 --input @params.json --wait
popiart jobs get job_xxx
popiart artifacts pull art_xxx</code></pre>
</div>
`,
"docs.coreCommands": `
<div class="eyebrow">COMMAND GROUP</div>
<h3>Core commands</h3>
<ul class="meta-list">
<li><strong>auth</strong> manages auth state and API keys</li>
<li><strong>skills</strong> discovers, installs, and inspects skill schemas</li>
<li><strong>run</strong> invokes a skill and returns a <code>job_id</code></li>
<li><strong>jobs</strong> queries and waits for job status</li>
<li><strong>artifacts</strong> pulls job outputs</li>
</ul>
`,
"docs.platformCommands": `
<div class="eyebrow">COMMAND GROUP</div>
<h3>Platform commands</h3>
<ul class="meta-list">
<li><strong>budget</strong> shows token usage and remaining budget</li>
<li><strong>project</strong> manages the current project context</li>
<li><strong>models</strong> inspects routing and direct inference capability</li>
<li><strong>bootstrap</strong> generates local discoverability assets</li>
<li><strong>update</strong> downloads new releases from GitHub Releases</li>
</ul>
`,
"docs.mcp": `
<div class="eyebrow">MCP</div>
<h3>Implemented MCP discoverability</h3>
<p>The repo already implements <code>popiart mcp serve / print-config / doctor</code> and exposes a practical agent-facing tool surface.</p>
<div class="code-block">
<div class="code-head">
<span>MCP</span>
<button class="button copy-button" data-copy-target="docs-mcp" type="button">Copy</button>
</div>
<pre><code id="docs-mcp">popiart mcp serve --describe
popiart mcp print-config
popiart mcp doctor
popiart bootstrap --agent codex --discoverable</code></pre>
</div>
<ul class="meta-list meta-list-spaced">
<li><strong>Implemented tools:</strong> list_skills, get_skill, run_skill, get_job, wait_job, pull_artifact</li>
<li><strong>Not done yet:</strong> MCP resources / prompts / sampling</li>
</ul>
`,
"docs.baseline": `
<div class="eyebrow">RUNTIME BASELINE</div>
<h3>Current official runtime baseline</h3>
<p>The current status notes for <code>popiartcli</code> explicitly treat only three skills as the official runtime baseline. They are the best candidates for homepage and console defaults.</p>
<ul class="meta-list meta-list-spaced">
<li><strong>popiskill-image-text2image-basic-v1</strong></li>
<li><strong>popiskill-image-img2img-basic-v1</strong></li>
<li><strong>popiskill-video-image2video-basic-v1</strong></li>
</ul>
`,
"docs.footer.title": "Popi.art Docs Prototype",
"docs.footer.subtitle": "Documentation is rewritten from the <code>popiartcli</code> README, command tree, and current-status notes.",
"login.meta.title": "Popi.art Login",
"login.meta.description": "Static bilingual login prototype for Popi.art.",
"login.form": `
<div class="eyebrow">SIGN IN</div>
<h2>Sign in with the product-layer key</h2>
<p>The real auth model in <code>popiartcli</code> is a PopiArt product-layer key, not a raw OpenAI, Gemini, Sora, or other provider key pasted into the client.</p>
<div class="auth-form">
<div class="field">
<label for="api-key">PopiArt API Key</label>
<input id="api-key" type="text" placeholder="pk-..." />
</div>
<div class="field">
<label for="endpoint">Endpoint</label>
<input id="endpoint" type="text" value="https://api.creatoragentos.io/v1" />
</div>
<div class="helper-text">The real CLI command is <code>popiart auth login --key pk-...</code>.</div>
<div class="hero-actions">
<button class="button button-primary" type="button">Validate and sign in</button>
<a class="button button-secondary" href="./skillhub_docs.html">Read CLI docs</a>
</div>
</div>
`,
"login.why": `
<div class="eyebrow">WHY THIS MODEL</div>
<h3>Unified gateway boundary</h3>
<p><code>popiartcli</code> is the local entrypoint, <code>popiartServer</code> is the product backend, and <code>PopiNewAPI</code> is the model gateway. Provider keys do not enter the CLI.</p>
`,
"login.after": `
<div class="eyebrow">AFTER LOGIN</div>
<h3>What you can do after sign-in</h3>
<ul class="meta-list">
<li><strong>Discover</strong>: inspect merged remote and local skills</li>
<li><strong>Run</strong>: start a skill execution and get a <code>job_id</code></li>
<li><strong>Artifacts</strong>: pull job outputs</li>
<li><strong>MCP</strong>: generate discoverability config and run doctor</li>
</ul>
`,
"login.store": `
<div class="eyebrow">STORE</div>
<h3>How local credentials are stored</h3>
<p>Saved keys go into <code>~/.popiart/config.json</code>, and can be overridden by <code>POPIART_KEY</code> or <code>POPIART_TOKEN</code>.</p>
`,
"login.footer.title": "Popi.art Login Prototype",
"login.footer.subtitle": "The login model follows <code>popiart auth login --key</code> instead of inventing a separate account system.",
"pricing.meta.title": "Popi.art Pricing",
"pricing.meta.description": "Static bilingual pricing prototype for Popi.art credits and usage.",
"pricing.heading": `
<div class="eyebrow">PRICING</div>
<h2>Buy more <span>Credits</span></h2>
<p>The static pricing page follows the credits structure of <code>open-claw</code>, while capability names come from <code>popiartcli</code> and <code>Popiart_skillhub</code>.</p>
`,
"pricing.packs": `
<div class="eyebrow eyebrow-soft">CREDIT PACKS</div>
<h3>Choose a credit pack after login</h3>
<p>This static prototype only demonstrates the information architecture. Real pricing, recharge, balance, and billing should come from <code>popiartServer</code>.</p>
<div class="credits-tier-list">
<div class="credits-tier">
<div>
<strong>Starter Pack</strong>
<span>200 Credits / for quick starts and single demos</span>
</div>
<em>¥29</em>
</div>
<div class="credits-tier">
<div>
<strong>Creator Pack</strong>
<span>1000 Credits / for day-to-day run, jobs, and artifacts workflows</span>
</div>
<em>¥99</em>
</div>
<div class="credits-tier">
<div>
<strong>Studio Pack</strong>
<span>5000 Credits / for multi-project or higher-frequency agent usage</span>
</div>
<em>¥399</em>
</div>
</div>
<div class="hero-actions">
<a class="button button-primary" href="./skillhub_login.html">Buy after login</a>
<a class="button button-secondary" href="./skillhub_docs.html">Read docs</a>
</div>
`,
"pricing.usage": `
<div class="eyebrow">CREDIT USAGE</div>
<h3>Static usage examples by capability</h3>
<p>Capability names and categories follow the current catalog. Credit numbers are placeholders for the static prototype and should later come from the real billing table.</p>
<div class="usage-columns">
<div class="usage-group">
<h4>Image tools</h4>
<div class="usage-list">
<div class="usage-item">
<div>
<strong>popiskill-image-text2image-basic-v1</strong>
<span>Generate images from text prompts</span>
</div>
<em>4 Credits/image</em>
</div>
<div class="usage-item">
<div>
<strong>popiskill-image-img2img-basic-v1</strong>
<span>Edit an existing image</span>
</div>
<em>2 Credits/image</em>
</div>
<div class="usage-item">
<div>
<strong>popiskill-image-img2img-edit-v1</strong>
<span>Local editing with multi-image references</span>
</div>
<em>3 Credits/image</em>
</div>
<div class="usage-item">
<div>
<strong>popiskill-image-text2image-character-sheet-v1</strong>
<span>Character sheets and multi-view generation</span>
</div>
<em>6 Credits/image</em>
</div>
</div>
</div>
<div class="usage-group">
<h4>Video & audio tools</h4>
<div class="usage-list">
<div class="usage-item">
<div>
<strong>popiskill-video-image2video-basic-v1</strong>
<span>Generate video from a starting image</span>
</div>
<em>20 Credits / 5s</em>
</div>
<div class="usage-item">
<div>
<strong>popiskill-video-text2video-studio-v1</strong>
<span>Generate video clips from text</span>
</div>
<em>25 Credits / 5s</em>
</div>
<div class="usage-item">
<div>
<strong>popiskill-video-avatar-talking-head-v1</strong>
<span>Talking-head and avatar-driven video</span>
</div>
<em>18 Credits / 5s</em>
</div>
<div class="usage-item">
<div>
<strong>popiskill-audio-tts-multimodel-v1</strong>
<span>Multi-model speech generation</span>
</div>
<em>3 Credits / run</em>
</div>
</div>
</div>
</div>
`,
"pricing.faqHeading": `
<div class="eyebrow">FAQ</div>
<h2>Frequently asked questions</h2>
`,
"pricing.faq1": `
<h3>Can credit packs stack?</h3>
<p>The static prototype assumes packs can stack into the same product-layer account. Real validity and stacking rules should come from the billing service.</p>
`,
"pricing.faq2": `
<h3>Can all 59 skills in SkillHub run immediately?</h3>
<p>No. The current CLI status notes explicitly treat only 3 skills as the official runtime baseline. Everything else still depends on server-side registration and routing.</p>
`,
"pricing.faq3": `
<h3>Can usage continue after credits run out?</h3>
<p>The static prototype currently assumes you need to purchase another credits pack. If monthly plans or bundled quotas are added later, the billing layer should define the rule.</p>
`,
"pricing.faq4": `
<h3>Why use a product-layer key instead of a provider key?</h3>
<p><code>popiartcli</code> should not hold raw upstream provider keys. Those keys belong behind the gateway and product backend boundary.</p>
`,
"pricing.footer.title": "Popi.art Pricing Prototype",
"pricing.footer.subtitle": "Pricing copy is organized around product-layer value and avoids exposing provider details directly.",
"skills.meta.title": "Popi.art Skills",
"skills.meta.description": "Static bilingual skill catalog prototype for Popi.art SkillHub.",
"skills.heading": `
<div class="eyebrow">SKILL CATALOG</div>
<h2>Turn <span>Popiart_skillhub</span> directly into a product catalog</h2>
<p>The directory structure comes from <code>index.json</code>, and detail structure comes from each <code>skills/*/SKILL.md</code> instead of a separate hand-written layer.</p>
`,
"skills.metrics.origin": "popiart origin skills",
"skills.metrics.upstream": "upstream reference skill",
"skills.metrics.showcase": "showcase skills",
"skills.metrics.baseline": "runtime baseline",
"skills.pills.naming": "Naming: popiskill-<category>-<capability>-<slug>-v<major>",
"skills.pills.categories": "Categories: image / video / audio / meta",
"skills.pills.source": "Source: index.json + SKILL.md",
"skills.featuredHeading": `
<div class="eyebrow">FEATURED</div>
<h2>Featured skills</h2>
`,
"skills.card1": `
<div class="skill-card-top">
<span class="badge badge-primary">IMAGE</span>
<span class="badge badge-success">BASELINE</span>
</div>
<h3>popiskill-image-text2image-basic-v1</h3>
<p>One of the official runtime baselines and the most natural default capability to highlight on the homepage and in the console.</p>
<ul class="meta-list">
<li><strong>Capability:</strong> text2image</li>
<li><strong>Origin:</strong> popiart</li>
<li><strong>Display:</strong> text-to-image</li>
</ul>
`,
"skills.card2": `
<div class="skill-card-top">
<span class="badge badge-primary">IMAGE</span>
<span class="badge badge-success">BASELINE</span>
</div>
<h3>popiskill-image-img2img-basic-v1</h3>
<p>The baseline image-editing path and a key entrypoint from the static catalog into actual editable workflows.</p>
<ul class="meta-list">
<li><strong>Capability:</strong> img2img</li>
<li><strong>Origin:</strong> popiart</li>
<li><strong>Display:</strong> image editing</li>
</ul>
`,
"skills.card3": `
<div class="skill-card-top">
<span class="badge badge-primary">VIDEO</span>
<span class="badge badge-success">BASELINE</span>
</div>
<h3>popiskill-video-image2video-basic-v1</h3>
<p>The strongest public example skill on the current video path for a runnable product showcase.</p>
<ul class="meta-list">
<li><strong>Capability:</strong> image2video</li>
<li><strong>Origin:</strong> popiart</li>
<li><strong>Display:</strong> image-to-video</li>
</ul>
`,
"skills.card4": `
<div class="skill-card-top">
<span class="badge badge-primary">IMAGE</span>
<span class="badge badge-warning">SHOWCASE</span>
</div>
<h3>popiskill-image-img2img-popistudio-alice-showcase-v1</h3>
<p>A fixed-reference Alice consistency showcase workflow, suitable for demos and proof frames.</p>
<ul class="meta-list">
<li><strong>Capability:</strong> img2img</li>
<li><strong>Showcase:</strong> true</li>
<li><strong>Display:</strong> PopiStudio Alice</li>
</ul>
`,
"skills.card5": `
<div class="skill-card-top">
<span class="badge badge-primary">VIDEO</span>
<span class="badge badge-warning">SHOWCASE</span>
</div>
<h3>popiskill-video-image2video-popistudio-alice-showcase-v1</h3>
<p>Extends the Alice showcase from a single frame into a teaser-style motion clip, which makes it ideal for homepage marketing.</p>
<ul class="meta-list">
<li><strong>Capability:</strong> image2video</li>
<li><strong>Showcase:</strong> true</li>
<li><strong>Display:</strong> Alice teaser</li>
</ul>
`,
"skills.card6": `
<div class="skill-card-top">
<span class="badge badge-primary">AUDIO</span>
<span class="badge badge-success">CATALOG</span>
</div>
<h3>popiskill-audio-tts-multimodel-v1</h3>
<p>The presence of many audio skills makes it clear the site cannot be designed only around images and video.</p>
<ul class="meta-list">
<li><strong>Capability:</strong> tts</li>
<li><strong>Category:</strong> audio</li>
<li><strong>Display:</strong> multi-model TTS</li>
</ul>
`,
"skills.detail": `
<div class="eyebrow">DETAIL EXAMPLE</div>
<h3>What a skill detail page should look like</h3>
<p>From <code>SKILL.md</code> you can reliably extract frontmatter descriptions, recommended usage, discouraged usage, required inputs, workflow, command patterns, payload templates, and artifact handling.</p>
<ul class="meta-list meta-list-spaced-lg">
<li><strong>Use when:</strong> demo frame / proof frame / character consistency</li>
<li><strong>Do not use:</strong> text-only / batch / long-form video</li>
<li><strong>Required input:</strong> scene_prompt</li>
<li><strong>Optional:</strong> shot_type / camera / mood / aspect_ratio</li>
</ul>
`,
"skills.command": `
<div class="eyebrow">REAL COMMAND</div>
<h3>Alice showcase command pattern</h3>
<div class="code-block">
<div class="code-head">
<span>Skill Run</span>
<button class="button copy-button" data-copy-target="skills-alice-run" type="button">Copy</button>
</div>
<pre><code id="skills-alice-run">popiart run popiskill-image-img2img-popistudio-alice-showcase-v1 \
--input @params.json \
--wait</code></pre>
</div>
`,
"skills.footer.title": "Popi.art Skill Catalog Prototype",
"skills.footer.subtitle": "Skill-page fields are designed from <code>index.json</code> and <code>SKILL.md</code>, and can later connect directly to the remote registry.",
"console.meta.title": "Popi.art Console",
"console.meta.description": "Static bilingual console prototype for Popi.art.",
"console.heading": `
<h1>Console</h1>
<p>Manage product-layer keys, inspect credit usage, and install the CLI quickly.</p>
`,
"console.stat1": `
<div class="console-stat-label">Remaining credits</div>
<strong>0</strong>
<span>Total 0 credits</span>
`,
"console.stat2": `
<div class="console-stat-label">Used</div>
<strong>0</strong>
<span>Accumulated this month</span>
`,
"console.stat3": `
<div class="console-stat-label">Calls</div>
<strong>0</strong>
<span>CLI / API calls this month</span>
`,
"console.apiHeading": "<h2>API keys</h2>",
"console.secrets": `
<div class="secret-row">
<div class="secret-copy">
<div class="secret-label">POPIART_KEY</div>
<div class="secret-value" id="console-key-value">pk_559196••••••••••••••••••••••••</div>
</div>
<button class="button button-secondary" data-copy-target="console-key-value" type="button">Copy</button>
</div>
<div class="secret-divider"></div>
<div class="secret-row">
<div class="secret-copy">
<div class="secret-label">POPIART_TOKEN</div>
<div class="secret-value" id="console-endpoint-value">pk_559196••••••••••••••••••••••••</div>
</div>
<button class="button button-secondary" data-copy-target="console-endpoint-value" type="button">Copy</button>
</div>
`,
"console.installHeading": "<h2>Quick install command</h2>",
"console.installCard": `
<div class="code-head">
<span>Quick Install</span>
<button class="button copy-button" data-copy-target="console-install-command" type="button">Copy</button>
</div>
<pre><code id="console-install-command">brew tap wtgoku-create/popi
brew install wtgoku-create/popi/popiart
export POPIART_KEY="pk_559196_demo"
export POPIART_ENDPOINT="https://api.creatoragentos.io/v1"
popiart bootstrap --agent codex --discoverable</code></pre>
`,
"console.footer.title": "Popi.art Console Prototype",
"console.footer.subtitle": "The console layout is heavily inspired by <code>open-claw</code>, while config fields and install commands are rewritten from <code>popiartcli</code>."
};
bindLocaleToggles();
applyLocale(currentLocale);
function captureSourceMap() {
const map = {};
document.querySelectorAll("[data-i18n]").forEach(function (node) {
map[node.getAttribute("data-i18n")] = node.textContent;
});
document.querySelectorAll("[data-i18n-html]").forEach(function (node) {
map[node.getAttribute("data-i18n-html")] = node.innerHTML.trim();
});
document.querySelectorAll("[data-i18n-content]").forEach(function (node) {
map[node.getAttribute("data-i18n-content")] = node.getAttribute("content") || "";
});
return map;
}
function getInitialLocale() {
try {
const url = new URL(window.location.href);
const param = url.searchParams.get("lang");
if (param === "en" || param === "zh") {
return param;
}
} catch (error) {
// Ignore URL parsing failures for unusual environments.
}
try {
const stored = window.localStorage.getItem("popiart_locale");
if (stored === "en" || stored === "zh") {
return stored;
}
} catch (error) {
// Ignore storage failures.
}
return "zh";
}
function resolveTranslation(key, locale) {
if (locale === "en" && Object.prototype.hasOwnProperty.call(enTranslations, key)) {
return enTranslations[key];
}
return sourceMap[key];
}
function applyLocale(locale) {
currentLocale = locale;
document.documentElement.lang = locale === "en" ? "en" : "zh-CN";
try {
window.localStorage.setItem("popiart_locale", locale);
} catch (error) {
// Ignore storage failures.
}
try {
const url = new URL(window.location.href);
url.searchParams.set("lang", locale);
window.history.replaceState({}, "", url.toString());
} catch (error) {
// Ignore history update failures.
}
document.querySelectorAll("[data-i18n]").forEach(function (node) {
const value = resolveTranslation(node.getAttribute("data-i18n"), locale);
if (typeof value === "string") {
node.textContent = value;
}
});
document.querySelectorAll("[data-i18n-html]").forEach(function (node) {
const value = resolveTranslation(node.getAttribute("data-i18n-html"), locale);
if (typeof value === "string") {
node.innerHTML = value;
}
});
document.querySelectorAll("[data-i18n-content]").forEach(function (node) {
const value = resolveTranslation(node.getAttribute("data-i18n-content"), locale);
if (typeof value === "string") {
node.setAttribute("content", value);
}
});
document.querySelectorAll("[data-locale-toggle]").forEach(function (node) {
node.textContent = locale === "zh" ? "EN" : "中文";
node.setAttribute("aria-label", locale === "zh" ? "Switch to English" : "切换到中文");
});
bindCopyButtons();
initRotatingHero();
}
function bindLocaleToggles() {
document.querySelectorAll("[data-locale-toggle]").forEach(function (node) {
node.onclick = function (event) {
event.preventDefault();
applyLocale(currentLocale === "zh" ? "en" : "zh");
};
});
}
function bindCopyButtons() {
const messages = copyMessages[currentLocale] || copyMessages.zh;
document.querySelectorAll("[data-copy-target]").forEach(function (button) {
button.onclick = async function () {
const targetId = button.getAttribute("data-copy-target");
const target = targetId ? document.getElementById(targetId) : null;
if (!target) {
return;
}
const original = button.textContent || messages.copy;
try {
await navigator.clipboard.writeText(target.textContent || "");
button.textContent = messages.copied;
} catch (error) {
button.textContent = messages.failed;
}
window.setTimeout(function () {
button.textContent = original;
}, 1400);
};
});
}
function initRotatingHero() {
if (heroRotationTimer) {
window.clearInterval(heroRotationTimer);
heroRotationTimer = null;
}
const rotating = document.querySelector("[data-hero-phrases]");
if (!rotating) {
return;
}
let phrases = [];
try {
phrases = JSON.parse(rotating.getAttribute("data-hero-phrases") || "[]");
} catch (error) {
phrases = [];
}
if (phrases.length > 1) {
let index = 0;
heroRotationTimer = window.setInterval(function () {
index = (index + 1) % phrases.length;
rotating.textContent = phrases[index];
}, 2400);
}
}
});