prototype
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePrototype
原型设计
Design in the browser. Produce branded, high-fidelity HTML for each page — real fonts, real colors, real copy — and iterate on it directly with the user until they approve. The output is self-contained static HTML.
This is the stage where visual design decisions happen: type scale, spacing, proportions, button sizing, visual weight, section rhythm.
在浏览器中进行设计。为每个页面生成品牌化高保真HTML——使用真实字体、真实色彩、真实文案——并直接与用户迭代直至其批准。输出为独立的静态HTML文件。
这是做出视觉设计决策的阶段:字体层级、间距、比例、按钮尺寸、视觉权重、区块节奏。
When to use this skill
何时使用该技能
- The user is ready to design visuals — type scale, spacing, proportions, layout, visual weight.
- The user asks to change, refine, review, critique, or iterate on visual styling or any file under .
stardust/prototypes/**/*.html - The user types , or asks to "design the page" after briefings are ready.
/stardust:prototype
- 用户准备进行视觉设计——字体层级、间距、比例、布局、视觉权重。
- 用户要求修改、优化、评审、点评或迭代视觉样式,或修改路径下的任意文件。
stardust/prototypes/**/*.html - 用户输入,或在briefings准备完成后要求“设计页面”。
/stardust:prototype
Do NOT use this skill
请勿使用该技能
- For page copy — copy is owned by . Propose a writeback to
briefingsif the user wants to save a new headline.briefings/{page}.md - For brand voice or identity decisions (colors, typography system, tone). Hand off to .
brand - For grey structural wireframes. Hand off to .
wireframes - To build EDS blocks or production HTML. Prototype stops at static HTML — EDS implementation is a separate downstream effort.
- 处理页面文案——文案由负责。如果用户希望保存新标题,建议写入
briefings。briefings/{page}.md - 处理品牌语音或标识决策(色彩、排版系统、风格)。移交至处理。
brand - 处理灰色结构线框。移交至处理。
wireframes - 构建EDS组件或生产环境HTML。原型设计仅止步于静态HTML——EDS实现是独立的下游工作。
Pre-flight
预检查
Run the procedure in first.
../_shared/preflight.md先执行中的流程。
../_shared/preflight.mdContract
约定
Needs (reads if present):
stardust/brand-profile.json- (including optional
stardust/briefings/{page}.mdand# Copy)# Imagery stardust/wireframes/{page}.html.impeccable.md
Produces:
- (self-contained, branded, desktop fidelity)
stardust/prototypes/{page}.html
If missing:
- No brand-profile.json → synthesize a neutral brand shape (system-ui fonts, mono palette, straight voice). Stamp provenance in the design's .
<head> - No briefing → prompt the user for a one-line page intent; synthesize a minimal briefing (in memory only, unless the user says "save it"); stamp provenance.
- Briefing has no → generate on-brand copy following
# Copyvoice rules andbrand-profile.json. Stamp provenance per section..impeccable.md - No wireframe → shape structure from the briefing directly.
- No → use brand-profile defaults only.
.impeccable.md
需要(如有则读取):
stardust/brand-profile.json- (包含可选的
stardust/briefings/{page}.md和# Copy部分)# Imagery stardust/wireframes/{page}.html.impeccable.md
生成:
- (独立、品牌化、桌面端保真度)
stardust/prototypes/{page}.html
若缺失:
- 无brand-profile.json → 生成中性品牌风格(system-ui字体、单色调色板、简洁风格)。在设计的中标记来源。
<head> - 无briefing → 提示用户提供一行页面目标;生成极简briefing(仅存于内存,除非用户要求“保存”);标记来源。
- Briefing无部分 → 遵循
# Copy的风格规则和brand-profile.json生成符合品牌的文案。按区块标记来源。.impeccable.md - 无wireframe → 直接根据briefing构建结构。
- 无→ 仅使用brand-profile默认设置。
.impeccable.md
Copy Ownership
文案归属
The briefing is the source of truth for copy.
- If a section has in the briefing, use those strings verbatim. Never rewrite.
# Copy - If a section has no , generate on-brand copy and record provenance (per-section, in the
# Copyprovenance block — e.g.<head>).hero.headline: synthesized - Never auto-write generated copy back to the briefing. If the user asks ("also save this to the briefing") perform a single, targeted writeback and report what changed.
briefing是文案的唯一来源。
- 若区块在briefing中有部分,严格使用原文。绝不改写。
# Copy - 若区块无部分,生成符合品牌的文案,并在
# Copy的来源块中记录(例如<head>)。hero.headline: synthesized - 绝不自动将生成的文案写回briefing。如果用户要求(“也将此保存到briefing”),执行单次定向写入并报告修改内容。
Phase 0: Setup
阶段0:设置
Two setup questions before rendering begins. Ask both once per session (not per page). When the skill is re-invoked on an existing project, read answers from the last prototype's provenance block if present; re-ask only if any answer is missing.
开始渲染前需确认两个设置问题。每个会话询问一次(而非每页)。当技能在现有项目中重新调用时,若存在上一个原型的来源块则读取答案;仅当答案缺失时重新询问。
0a · Variant count
0a · 变体数量
Ask the designer to confirm, with 2 as the default:
"I'll produce 2 variants of each prototype so you can compare — confirm, or give a different number (1–4)?"
Wait for the designer's answer. Accept:
- ,
"ok","confirm", Enter,"yes"→ 2 variants (default)"2" - → single variant
1 - or
3→ that many variants4 - Any other input → re-ask once with the valid options
Default to 2 when:
-
The designer skips or accepts the default
-
The skill is invoked as part of an automated pipeline with no explicit variant count
-
1 variant — produce.
stardust/prototypes/{page}.html -
N ≥ 2 variants — the skill produces,
{page}-a.html, …{page}-b.html, each exploring a distinct design direction. Pick directions along axes that are load-bearing for this brand (e.g. if the brand voice is unsettled, vary type-voice; if the palette is rich, vary color-energy). Canonical axes to pick from:{page}-{letter}.html- type-voice — editorial serif-forward ↔ software sans-forward
- density — airy/spacious ↔ catalog/compressed
- color-energy — restrained/ink-led ↔ saturated/surface-led
- imagery-role — decorative/background ↔ content/lead
-
Record the chosen direction per file as a one-line comment inside the prototype's provenance block (e.g.).
variant_direction: "editorial, Fraunces-forward, quiet"
请设计师确认,默认值为2:
“我将为每个原型生成2个变体供您比较——请确认,或提供其他数字(1–4)?”
等待设计师回复。接受以下输入:
- ,
"ok","confirm", 回车,"yes"→ 2个变体(默认)"2" - → 单个变体
1 - 或
3→ 对应数量的变体4 - 其他输入 → 重新询问一次并说明有效选项
在以下情况默认使用2:
-
设计师跳过或接受默认值
-
技能作为自动化流程的一部分被调用,未明确指定变体数量
-
1个变体 — 生成。
stardust/prototypes/{page}.html -
N ≥ 2个变体 — 技能生成,
{page}-a.html, …{page}-b.html,每个变体探索不同的设计方向。选择对该品牌至关重要的维度(例如,若品牌风格尚未确定,可改变字体风格;若调色板丰富,可改变色彩活力)。可选择的标准维度:{page}-{letter}.html- type-voice — 偏向编辑衬线体 ↔ 偏向软件无衬线体
- density — 宽松/开阔 ↔ 紧凑/密集
- color-energy — 克制/墨色主导 ↔ 饱和/色彩主导
- imagery-role — 装饰/背景 ↔ 内容/主导
-
在每个原型的来源块中添加一行注释记录所选方向(例如)。
variant_direction: "editorial, Fraunces-forward, quiet"
0b · Imagery mode
0b · 图片模式
Ask: "For images in the prototype, do you want: (a) branded placeholder rectangles — fast, offline, free, or (b) real generated images? If (b), you'll need to pick a model and point me at a credential."
Default to (a) placeholders when the user skips, the skill runs in full-pipeline auto-approve mode, or no credential is available.
If the user picks (b) generated, ask two follow-ups:
-
"Which image model?" — the assistant presents options based on what's installed. Currently known providers:
Answer Provider Model Credential env var geminiGoogle Gemini 3 Pro Image Preview GOOGLE_API_KEYfluxfal.ai FLUX Schnell FAL_KEYimagenGoogle Vertex Imagen 3 GOOGLE_APPLICATION_CREDENTIALSdalleOpenAI DALL-E 3 OPENAI_API_KEY -
"Where's the credential?" — accept any of:
- → the credential is already exported as the env var from the table above
env - A file path ending in → the skill reads the env var from that file (do NOT echo the key to the designer; just read it in memory)
.env - A raw token → the skill treats the string as the key value and uses it only for this session (do not write it to disk)
Record the imagery mode in each prototype's provenance block:
html
<!-- stardust:provenance
imagery_mode: placeholder
...
-->or, when generation was used:
html
<!-- stardust:provenance
imagery_mode: generated
imagery_provider: gemini
imagery_credential_source: /Users/paolo/excat/az-sitebuilder/.env
imagery_generated_at: 2026-04-24T15:12:00Z
images: [
{ section: "hero", path: "images/landing-hero.png", prompt_hash: "abc123" },
...
]
-->Never log the actual key value anywhere — not in provenance, not in terminal output, not in error messages.
询问:“对于原型中的图片,您希望:(a) 品牌化占位矩形——快速、离线、免费;或(b) 真实生成的图片?如果选(b),您需要选择一个模型并提供凭证。”
当用户跳过、技能在全流程自动批准模式下运行,或无可用凭证时,默认选择**(a) 占位符**。
如果用户选择**(b) 生成图片**,需跟进两个问题:
-
“选择哪个图片模型?” — 助手根据已安装的选项提供选择。当前已知提供商:
回复 提供商 模型 凭证环境变量 geminiGoogle Gemini 3 Pro Image Preview GOOGLE_API_KEYfluxfal.ai FLUX Schnell FAL_KEYimagenGoogle Vertex Imagen 3 GOOGLE_APPLICATION_CREDENTIALSdalleOpenAI DALL-E 3 OPENAI_API_KEY -
“凭证在哪里?” — 接受以下任意形式:
- → 凭证已导出为上表中的环境变量
env - 以结尾的文件路径 → 技能从该文件读取环境变量(绝不向设计师回显密钥;仅在内存中读取)
.env - 原始令牌 → 技能将该字符串视为密钥值,仅在本次会话中使用(不写入磁盘)
在每个原型的来源块中记录图片模式:
html
<!-- stardust:provenance
imagery_mode: placeholder
...
-->或使用生成图片时:
html
<!-- stardust:provenance
imagery_mode: generated
imagery_provider: gemini
imagery_credential_source: /Users/paolo/excat/az-sitebuilder/.env
imagery_generated_at: 2026-04-24T15:12:00Z
images: [
{ section: "hero", path: "images/landing-hero.png", prompt_hash: "abc123" },
...
]
-->绝不记录实际密钥值——无论是在来源块、终端输出还是错误消息中。
Imagery-mode consequences for Phase 2
图片模式对阶段2的影响
- placeholder → Phase 2 renders branded placeholder rectangles per design-guide.md Imagery section, option (b).
- generated → Phase 2 invokes the skill (from
ai-image-generator,eds-site-builder, orsumiplugin — whichever is registered) with the chosen provider + credential, passing the briefing'stestingdirection + brand# Imageryrules per section. Generated images land atphotography. Prototype HTMLstardust/prototypes/images/{page}-{section}.pngpoints at those relative paths.<img src>
Fallback behaviour when but the generation fails:
imagery_mode = generated- Retry once with a slightly simplified prompt
- On second failure, fall back to a branded placeholder for that specific image slot (not the whole page)
- Stamp and the failed-slot list in the provenance block so the designer knows which slots to retry later
imagery_fallback: true - Continue rendering the prototype — do not abort the whole page over one failed image
- placeholder → 阶段2根据design-guide.md Imagery部分选项(b)渲染品牌化占位矩形。
- generated → 阶段2调用技能(来自
ai-image-generator,eds-site-builder, 或sumi插件——以已注册的为准),使用所选提供商+凭证,传入briefing的testing方向+品牌# Imagery规则(按区块)。生成的图片保存至photography。原型HTML的stardust/prototypes/images/{page}-{section}.png指向这些相对路径。<img src>
当但生成失败时的 fallback 行为:
imagery_mode = generated- 使用略微简化的提示重试一次
- 若第二次失败,为该特定图片位置回退到品牌化占位符(而非整个页面)
- 在来源块中标记及失败位置列表,以便设计师知晓后续需重试的位置
imagery_fallback: true - 继续渲染原型——不因一张图片失败而中止整个页面
Phase 1: Plan
阶段1:规划
For each briefing:
- Load structural input:
- If exists, use it as the section order and layout reference.
stardust/wireframes/{page}.html - If not, plan the sections from the briefing:
- If the plugin is installed (
impeccableis registered), delegate to/impeccable shape./impeccable shape - Otherwise, use the "For wireframe section planning" pattern in . Per
../_shared/fallback-brainstorm.md, impeccable fallback runs silently.../_shared/soft-deps.md
- If the
- If
- For each section, check the briefing's :
# Copy- Present → use verbatim. Do not rewrite under any feedback loop unless the user explicitly says to change the words in the briefing.
- Absent → generate on-brand copy; add the slot to the design's provenance block (e.g. ).
hero.headline: synthesized - Never write generated copy back to the briefing automatically. Offer: "Want me to also save these lines to the briefing?" after the first render — act only on explicit confirmation.
- Re-read the briefing's section — follow source hints; otherwise generate branded placeholders.
# Imagery
针对每个briefing:
- 加载结构输入:
- 若存在,将其作为区块顺序和布局参考。
stardust/wireframes/{page}.html - 若不存在,根据briefing规划区块:
- 若已安装插件(已注册
impeccable),委托给/impeccable shape处理。/impeccable shape - 否则,使用中的“For wireframe section planning”模式。根据
../_shared/fallback-brainstorm.md,impeccable回退将静默运行。../_shared/soft-deps.md
- 若已安装
- 若
- 针对每个区块,检查briefing的部分:
# Copy- 存在 → 严格使用原文。除非用户明确要求修改briefing中的文字,否则在任何反馈循环中都不得改写。
- 不存在 → 生成符合品牌的文案;将该位置添加到设计的来源块中(例如)。
hero.headline: synthesized - 绝不自动将生成的文案写回briefing。首次渲染后可询问:“需要我将这些内容保存到briefing吗?”——仅在明确确认后执行。
- 重新阅读briefing的部分——遵循来源提示;否则生成品牌化占位符。
# Imagery
Phase 2: Render (Branded Mode)
阶段2:渲染(品牌模式)
Render each design as a self-contained HTML file at desktop fidelity (1440px design target):
- Brand fonts via or
@importto web fonts.<link> - Brand colors for surfaces, text, CTAs, and accents per color roles. Derive the page ground from the brand palette — do NOT default to cream (or any rebrand: vellum, kami, bone, ivory, eggshell). See
brand-profile.json§ 2.5 Ground-color seed.../_shared/divergence-toolkit.md - Real component styles — button patterns, border-radius, motifs from the brand profile.
- Real copy — briefing verbatim, or on-brand generated copy.
# Copy - Images — briefing sources, or branded placeholders.
# Imagery - CSS custom properties in that expose type scale, spacing, max-width, section padding, button proportions. These values are the authoritative desktop tokens — any downstream translation (to EDS CSS, another framework, a design handoff) reads them from here.
:root - Preserve ,
data-section,data-intentattributes from the wireframe so downstream stages can read structure.data-layout - Provenance block — if any input was synthesized (brand, briefing, wireframe, or any slot), include a
# Copycomment as the first child of<!-- stardust:provenance ... -->per<head>. List each synthesized input and, for copy, each synthesized slot.../_shared/skill-contract.md
Write to (single-variant mode) or for each variant (multi-variant mode). In multi-variant mode, each file is rendered independently — variants share the briefing's copy and the brand tokens, but differ on the design-direction axes chosen in Phase 0.
stardust/prototypes/{page}.htmlstardust/prototypes/{page}-{letter}.htmlFollow the rendering rules in design-guide.md.
将每个设计渲染为独立的HTML文件,达到桌面端保真度(设计目标为1440px):
- 品牌字体通过或
@import引入Web字体。<link> - 品牌色彩根据的色彩角色设置背景、文本、CTA和强调色。从品牌调色板推导页面底色——绝不默认使用米白色(或任何类似名称:vellum、kami、bone、ivory、eggshell)。参见
brand-profile.json第2.5节“底色种子”。../_shared/divergence-toolkit.md - 真实组件样式——按钮样式、圆角、品牌配置文件中的装饰元素。
- 真实文案——briefing的原文,或符合品牌的生成文案。
# Copy - 图片——briefing的来源,或品牌化占位符。
# Imagery - 中的CSS自定义属性,暴露字体层级、间距、最大宽度、区块内边距、按钮比例。这些值是权威的桌面端令牌——任何下游转换(到EDS CSS、其他框架、设计交付)都从此处读取。
:root - 保留线框中的,
data-section,data-intent属性,以便下游阶段读取结构。data-layout - 来源块——若任何输入为生成内容(品牌、briefing、线框或任何位置),需在
# Copy的第一个子元素中添加<head>注释,遵循<!-- stardust:provenance ... -->。列出每个生成的输入,对于文案,列出每个生成的位置。../_shared/skill-contract.md
写入(单变体模式)或(多变体模式下的每个变体)。在多变体模式下,每个文件独立渲染——变体共享briefing的文案和品牌令牌,但在阶段0选择的设计维度上有所不同。
stardust/prototypes/{page}.htmlstardust/prototypes/{page}-{letter}.html遵循design-guide.md中的渲染规则。
Phase 3: Serve
阶段3:展示
Prototypes are self-contained HTML files. Open each file in the designer's default browser immediately after writing per Opening HTML artifacts. Do not require the designer to open the files manually.
../_shared/skill-contract.md-
Single variant:on macOS (
open "stardust/prototypes/<page>.html"on Linux). Tell the user: "Your prototype is open."xdg-open -
Multiple variants: open each variant file at the same time so the designer can flip between browser tabs. Then present the comparison table:
Variant Direction Key visual move Risk a editorial, Fraunces-forward oversized serif headline, narrow measure may read as too quiet for a tech audience b software-catalog, Inter-dense table-led hero, hard geometric rhythm may read as cold without warm imagery ... ... ... ... Ask the user: "Which variant should we take forward?" Wait for an explicit answer (,a, ...) before moving on.b
If the designer needs a real HTTP origin (fetch, service workers, absolute asset URLs), additionally run in the background and tell them the URL — but keep the browser-open via first, which handles 95% of cases via the protocol.
python3 -m http.server 8000 --directory stardust/prototypeshttp://localhost:8000/<page>.htmlopenfile://In pipeline-automation mode (no designer present), skip the open.
原型为独立的HTML文件。写入完成后立即在设计师的默认浏览器中打开每个文件,遵循中的“Opening HTML artifacts”部分。无需设计师手动打开文件。
../_shared/skill-contract.md-
单变体:在macOS上执行(Linux上为
open "stardust/prototypes/<page>.html")。告知用户:“您的原型已打开。”xdg-open -
多变体:同时打开每个变体文件,以便设计师在浏览器标签页之间切换。然后展示对比表格:
变体 方向 核心视觉调整 风险 a editorial, Fraunces-forward 超大衬线标题,窄版布局 对技术受众而言可能过于平淡 b software-catalog, Inter-dense 表格主导的hero区块,硬朗几何节奏 若无暖色调图片可能显得冰冷 ... ... ... ... 询问用户:“我们应该推进哪个变体?” 在继续前等待明确回复(,a, ...)。b
如果设计师需要真实的HTTP源(fetch、服务工作者、绝对资源URL),额外在后台运行,并告知用户的URL——但首先通过打开浏览器,这能通过协议处理95%的场景。
python3 -m http.server 8000 --directory stardust/prototypeshttp://localhost:8000/<page>.htmlopenfile://在流程自动化模式下(无设计师参与),跳过打开步骤。
Phase 4: Iterate in the Browser
阶段4:在浏览器中迭代
This is a design loop, not a one-shot render. Expect multiple rounds.
In multi-variant mode, iterate only on the variant the user named (e.g. ). Unchosen variants stay on disk as a design-history reference; do not delete or rename them without the user's explicit ask. Every subsequent iteration request refers implicitly to the chosen variant until the user picks a different one.
landing-b.htmlCommon feedback and how to handle it:
- "Headlines are too big/small" → Adjust custom properties, re-render, refresh.
--heading-* - "Section feels cramped" → Adjust or per-section spacing, re-render.
--section-padding - "Button needs more weight" → Adjust button padding/font-size/weight in the design CSS.
- "Try a different accent color" → Swap the CSS variable value; do not edit unless the user wants to make it the new brand default.
brand-profile.json - "This section should feel quieter" → Adjust typographic weight or surface color on that specific section.
Every iteration updates the file under review — in single-variant mode, or for the variant the user named in multi-variant mode. Re-open the file in the browser after every iteration so the designer sees the change immediately (browsers with live-reload will pick up the change on re-open; otherwise the user may need to refresh). Keep iterating until they approve.
stardust/prototypes/{page}.htmlstardust/prototypes/{page}-{letter}.htmlBefore asking the user to look at a new iteration, run a critique:
If the plugin is installed ( is registered), use it. Otherwise, apply the rubric in . Per , impeccable fallback runs silently.
impeccable/impeccable critique../_shared/fallback-critique.md../_shared/soft-deps.md这是一个设计循环,而非一次性渲染。预计会有多轮迭代。
在多变体模式下,仅对用户指定的变体进行迭代(例如)。未被选中的变体保留在磁盘上作为设计历史参考;除非用户明确要求,否则不得删除或重命名。在用户选择其他变体之前,所有后续迭代请求默认指向已选中的变体。
landing-b.html常见反馈及处理方式:
- “标题太大/太小” → 调整自定义属性,重新渲染并刷新。
--heading-* - “区块感觉太拥挤” → 调整或区块内间距,重新渲染。
--section-padding - “按钮需要更突出” → 在设计CSS中调整按钮内边距/字体大小/字重。
- “尝试不同的强调色” → 替换CSS变量值;除非用户希望将其设为新的品牌默认值,否则不得编辑。
brand-profile.json - “这个区块应该更简洁” → 调整该特定区块的排版字重或背景色。
每次迭代都会更新正在评审的文件——单变体模式下为,多变体模式下为用户指定的。每次迭代后重新在浏览器中打开文件,以便设计师立即看到变化(支持实时重载的浏览器会在重新打开时识别变化;否则用户可能需要刷新)。持续迭代直至用户批准。
stardust/prototypes/{page}.htmlstardust/prototypes/{page}-{letter}.html在让用户查看新迭代版本前,先进行评审:
若已安装插件(已注册),使用该插件。否则,应用中的评估标准。根据,impeccable回退将静默运行。
impeccable/impeccable critique../_shared/fallback-critique.md../_shared/soft-deps.mdPhase 5: Approval Gate
阶段5:批准节点
Hard gate in interactive mode — do not proceed until the user approves each prototype.
Pipeline automation: When invoked as part of a full pipeline run, auto-approve after two critique passes and continue.
When the user approves:
- Confirm all prototypes are saved under .
stardust/prototypes/*.html - Tell the user: "Prototypes approved. Run to see your next step."
/stardust
交互模式下的强制节点——在用户批准每个原型前不得继续。
流程自动化:当作为全流程运行的一部分被调用时,经过两次评审后自动批准并继续。
当用户批准时:
- 确认所有原型已保存至。
stardust/prototypes/*.html - 告知用户:“原型已批准。运行查看下一步操作。”
/stardust
Why Prototypes Are Static HTML
为何原型采用静态HTML
Prototypes are platform-agnostic — they could in principle feed any downstream build later (EDS, a different SSG, a different CMS). They are pure HTML + CSS judgment calls.
Keeping prototypes static and platform-free means:
- Visual design can be iterated freely without implementation complications.
- Any downstream translation (to EDS CSS, to a framework component library, etc.) is mechanical, not judgmental.
- The prototype layer is portable across target platforms.
原型是平台无关的——原则上可用于任何下游构建(EDS、其他静态站点生成器、其他CMS)。它们是纯HTML + CSS的决策成果。
保持原型为静态且独立于平台意味着:
- 视觉设计可自由迭代,无需考虑实现复杂度。
- 任何下游转换(到EDS CSS、框架组件库等)都是机械性的,而非决策性的。
- 原型层可在不同目标平台间移植。
Artifacts Written
生成的产物
| File | Description |
|---|---|
| Branded, high-fidelity static HTML per page — self-contained, platform-independent. Single-variant mode. |
| One file per variant ( |
| 文件 | 描述 |
|---|---|
| 每个页面的品牌化高保真静态HTML——独立、平台无关。单变体模式。 |
| 当用户要求2–4个变体时,每个变体对应一个文件( |