Files
aurora-admin/site/i18n.js
T
aurora-admin f1fbfc2ddb
Regression / regression (push) Canceled after 0s
feat(品牌标识): 几何 K 图标(favicon/顶栏标记/theme-color) + 并行会话成果入库
## 品牌标识(本次会话)

起因:品牌此前没有任何图形标识 —— 唯一 favicon 是内联 data-URI 里的字母「A」,
那是 v2.0.0「Aurora Admin → Kole UI」改名漏掉的一处(PC 顶栏也是「A」,
移动端站已是「K」;移动端文档站则完全没有 favicon)。

- 几何:24 网格三个互不接触的笔画(竖 + 两斜),圆头描边;
  描边 2.25 → 16px 标签页尺寸下正好 1.5px = 规范原文「描边1.5px」
- 取色分两套(刻意):favicon 硬编码品牌蓝/白(渲染在浏览器标签栏,不继承 kole-dark);
  顶栏标记走 currentColor(实测暗色下自动转 rgb(20,22,28))
- 新增 theme-color 双条(light #FFFFFF / dark #1C1F26,取 --kole-color-card-bg)
- 修 site/app.js hero 标语 KOLE ADMIN → KOLE UI(改名变形残留)
- 移动端 7 个模板补 favicon(此前计数 0)

验收:门禁 9 条全 OK(site-routing/site-routes/mobile-docs/mobile-site/isolation/
theme/nav/i18n/icons);PC 回归 1464/1464 · 移动端 807/807,各连跑 8 次一致;
两端 favicon 405 字节逐字节一致;PC 站控制台错误 1→0。

## 并行会话成果(本次一并入库)

- 图标系统:2576 图标(TDesign/Element Plus,MIT)+ 11 端注入 + 5 个构建门禁工具
  + IconPreview 预览页 + ICON-SPEC.md 冻结规格
- 移动端平台:47 组件 × 6 端 + 文档站 53 页 + 隔离门禁
- PC 组件:103 个大后台组件 / 组件11 批次
- uni-app:PC 端试点 + 移动端端实现 + 真实编译验证

## 工程

- .gitignore 补 .scratch/ 与 .zcode-preexisting-*.txt(会话中间产物,实测 9.1MB,不入库)
- CHANGELOG 补品牌标识条目
- ROADMAP 登 S8-P4(品牌标识任务包 + og:image/apple-touch-icon 未做部分)
2026-09-21 10:05:48 +08:00

928 lines
50 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* Kole UI 文档站国际化 (i18n)
*
* 设计取舍:以「中文源串」作为字典键,英文为值。
* 理由:中文是规范原文语言(组件1~10.txt),也是 app.js 里现有的字面量;
* 以源串为键意味着未收录的文案自动回退中文,不会出现空白或 key 泄漏。
* 纯前端、零依赖,与整站零运行时依赖的约束一致。
*
* 用法:T('组件总览') → zh 模式下返回原文,en 模式下返回 'Components'
* 当前语言存 localStorage['kole-lang'],切换后整站重渲染。
*/
(function () {
'use strict';
var EN = {
/* ---------- 快速开始 · npm 安装 ---------- */
'了解如何在本项目中使用 Kole UI 组件:从 npm 私有源安装、引入设计令牌、按端取用组件源码、以及目录与命名约定。':
'Understand how to use Kole UI components: install from the private npm registry, import design tokens, take component sources per stack, plus directory and naming conventions.',
'安装(npm 私有源)':
'Install (private npm registry)',
'本设计系统已发布到自建 Gitea 的 npm registry,<strong>匿名可读、无需登录</strong>。在项目 <code>.npmrc</code> 写一行,让 <code>@root</code> 作用域的包走私有源,其余依赖仍走公共源:':
'This design system is published to a self-hosted Gitea npm registry — <strong>anonymous read, no login needed</strong>. One line in your project <code>.npmrc</code> routes the <code>@root</code> scope to the private registry while every other dependency still resolves from the public one:',
'也可用非 scoped 别名 <code>chunyu-ui</code>(内容完全相同),但必须显式指定源——<code>@名字:registry=</code> 这种写法只对 scoped 包名生效:':
'The non-scoped alias <code>chunyu-ui</code> works too (identical content) but needs the registry given explicitly — the <code>@name:registry=</code> form only applies to scoped package names:',
'按端引入(令牌必须先引)':
'Import per stack (tokens first)',
'79 个组件里有 78 个的样式引用 <code>var(--kole-*)</code> 令牌。漏引令牌不会报错,但会出现「组件渲染出来了、颜色和间距却全丢」——这是接入时最常见的坑。':
'78 of the 79 components reference <code>var(--kole-*)</code> tokens in their styles. Skipping the token import raises no error but leaves components rendered with no colours or spacing — the most common pitfall when wiring this up.',
'Vue 2 用 <code>@root/ui/vue2</code>,需构建链具备 SFC 编译能力(vue-loader 15+ 或 vue-template-compiler)。组件以 <code>.vue</code> / <code>.jsx</code> 源码形式发布,由你项目的构建链编译;<code>react</code> 与 <code>vue</code> 是 peerDependencies,按用到的端安装即可,本包不捆绑框架。':
'For Vue 2 use <code>@root/ui/vue2</code>, which needs SFC compilation in your build chain (vue-loader 15+ or vue-template-compiler). Components ship as <code>.vue</code> / <code>.jsx</code> sources compiled by your own build chain; <code>react</code> and <code>vue</code> are peerDependencies — install only the stack you use, no framework is bundled.',
'所有组件都基于同一份 CSS 变量令牌。用 npm 安装时令牌路径是 <code>@root/ui/tokens/tokens.css</code>;不用 npm 时直接引仓库文件:':
'Every component builds on the same CSS variable tokens. With npm the token path is <code>@root/ui/tokens/tokens.css</code>; without npm, link the repository file directly:',
'按端使用组件(不用 npm)':
'Use components per stack (without npm)',
/* ---------- 顶栏 / 导航 ---------- */
'组件库': 'Components',
'搜索组件…': 'Search…',
'框架': 'Stack',
'技术栈': 'Stack',
'选择技术栈': 'Choose a stack',
/* 平台入口(PC 文档站 ↔ 移动端文档站,2026-09-20 两轴模型) */
'平台': 'Platforms',
'当前': 'Now',
'PC 端组件': 'Web (PC) components',
'移动端组件': 'Mobile components',
'打开移动端组件文档': 'Open the mobile component docs',
'移动端组件文档(独立站)': 'Mobile component docs (separate site)',
'79 个中后台组件 · 5 端': '79 back-office components · 5 ends',
'5 个组件 · 6 端 · 含 uni-app': '5 components · 6 ends · incl. uni-app',
'首页': 'Home',
'组件': 'Components',
'快速开始': 'Getting Started',
'设计规范': 'Design Tokens',
'更新日志': 'Changelog',
'选择你的技术栈,文档将只展示对应框架的内容': 'Pick your stack — the docs will only show files for it',
'搜索组件(中文 / 英文 / slug)': 'Search components (name / slug)',
'界面语言': 'Interface language',
'选择语言': 'Select language',
/* ---------- 版本切换(版本清单见 site/versions.json) ---------- */
'选择版本': 'Select version',
'文档版本': 'Documentation version',
'最新版': 'Latest',
'当前浏览': 'Viewing',
'打开导航菜单': 'Open navigation menu',
'↑↓ 选择': '↑↓ Navigate',
'Enter 跳转': 'Enter Open',
'Esc 关闭': 'Esc Close',
/* ---------- 侧边栏 / 分类 ---------- */
'组件总览': 'All Components',
'通用': 'General',
'导航': 'Navigation',
'数据录入': 'Data Entry',
'数据展示': 'Data Display',
'反馈': 'Feedback',
'工具与系统': 'System',
'未分类': 'Uncategorized',
'本页目录': 'On This Page',
/* ---------- 批次 ---------- */
'核心规范': 'Core',
'第': 'Batch ',
'批': '',
'核心组件': 'Core',
'扩展组件': 'Extension',
'规格批次': 'Spec Batch',
/* ---------- 首页 ---------- */
'Kole UI 组件库': 'Kole UI',
'理性、高效、克制的 B 端中后台设计系统——信息密度适中,层级清晰,交互反馈即时。':
'A rational, efficient and restrained design system for B2B admin panels — moderate information density, clear hierarchy, immediate feedback.',
'浏览组件 →': 'Browse components →',
'场景示范': 'Live Scenario',
'测试总览': 'Test Overview',
'个大类': 'categories',
'端实现': 'platforms',
'份规范': 'spec docs',
'测试页': 'test pages',
'大类': 'Categories',
' 大类。基于 Kole UI 设计系统规范构建,提供 H5 / React / Vue 2 / Vue 3 四端实现。':
' categories. Built on the Kole UI specification with H5 / React / Vue 2 / Vue 3 implementations.',
'核心规范组件': 'Core',
'设计令牌': 'Design Tokens',
'通过率 ': 'Pass rate ',
'headless 回归 ': 'headless regression, ',
'断言通过': 'assertions passed',
'设计原则': 'Design Principles',
'一致优先': 'Consistency First',
'同类组件使用相同的尺寸、颜色与间距,跨页面保持一致体验。':
'Same sizes, colors and spacing across similar components, so the experience holds from page to page.',
'清晰高效': 'Clarity & Efficiency',
'信息层级明确,操作路径最短,避免过度装饰。':
'Explicit hierarchy, shortest path to the action, no decoration for its own sake.',
'反馈及时': 'Immediate Feedback',
'所有操作都有加载、成功、失败三类状态反馈。':
'Every action carries loading, success and failure feedback.',
'无障碍': 'Accessibility',
'满足键盘操作与焦点管理,正文对比度 ≥ 4.5:1。':
'Full keyboard operation with focus management; body text contrast ≥ 4.5:1.',
'定位到本组件的规格原文章节': 'Jump to this component’s spec section',
/* ---------- 总览 ---------- */
'个组件(核心': ' components (core ',
' · 扩展': ' · extension ',
'),覆盖 ': '), covering ',
'。基于 Kole UI 设计系统规范构建,提供 H5 / React / Vue 2 / Vue 3 四端实现。':
'. Built on the Kole UI specification with H5 / React / Vue 2 / Vue 3 implementations.',
'预览': 'Preview',
'加载预览…': 'Loading preview…',
'无匹配组件': 'No matching components',
'无匹配组件(已尝试模糊匹配)': 'No matching components (fuzzy match tried)',
'全部': 'All',
'过滤组件…': 'Filter components…',
/* ---------- 快速开始 ---------- */
'了解如何在本项目中使用 Kole UI 组件:引入设计令牌、按端取用组件源码、以及目录与命名约定。':
'How to use Kole UI in your project: import the tokens, pick component sources per platform, and follow the directory and naming conventions.',
'引入设计令牌': 'Import Design Tokens',
'所有组件都基于同一份 CSS 变量令牌。在使用任何组件前,先在页面中引入令牌文件:':
'Every component shares one set of CSS variable tokens. Import the token file before using any component:',
'如需结构化的令牌数据(供工具消费),可读取同目录的 <code>css.json</code>;聚合组件样式见 <code>components.css</code>。':
'For structured token data (tool consumption), read <code>css.json</code> in the same directory; aggregated component styles live in <code>components.css</code>.',
'按端使用组件': 'Use Components per Platform',
'每个组件在 <code>frameworks/</code> 下有五种形态(H5 / CSS / React / Vue 2 / Vue 3),按你的技术栈取用:':
'Each component ships in five forms under <code>frameworks/</code> (H5 / CSS / React / Vue 2 / Vue 3). Take the one matching your stack:',
'端': 'Platform',
'文件': 'File',
'使用方式': 'How to use',
'直接在浏览器打开即为完整演示页;将结构与内联样式拷贝进你的页面':
'Opens as a complete demo page in the browser; copy the markup and inline styles into your page',
'将 JSX 与 CSS 拷入工程,按需改造数据绑定': 'Copy the JSX and CSS into your project, adapt the data binding as needed',
'Options API 单文件组件,直接注册使用': 'Options API single-file component, register and use directly',
'<script setup> 组合式 API,直接注册使用': '<script setup> Composition API, register and use directly',
'样式令牌': 'Style tokens',
'所有变量以 --kole- 前缀暴露,可整体引入或按需拷贝':
'All variables are exposed with the --kole- prefix; import wholesale or copy as needed',
'目录结构': 'Directory Structure',
'命名约定': 'Naming Conventions',
'组件 slug 为小写(如 button、sidemenu),文件名前缀为 PascalCase(如 SideMenu.vue3.vue)':
'Component slugs are lowercase (button, sidemenu); file name prefixes are PascalCase (SideMenu.vue3.vue)',
'H5 演示页自带演示数据与交互,可直接作为视觉验收基准':
'H5 demo pages ship with sample data and interaction — use them as the visual acceptance baseline',
'组件 ↔ 规格批次 ↔ 实现的权威映射见 .design_library/kole-ui/components/index.json':
'The authoritative component ↔ spec batch ↔ implementation mapping lives in .design_library/kole-ui/components/index.json',
'全部组件默认桌面端优先(最小宽度 1280px),不推荐移动端场景':
'All components are desktop-first (min width 1280px); mobile scenarios are not recommended',
' 条,': ' entries, ',
/* ---------- 更新日志 ---------- */
'按 SemVer 记录的重要变更,与仓库根目录 CHANGELOG.md 同源(构建时自动解析注入)。':
'Notable changes recorded per SemVer, sourced from the repository CHANGELOG.md (parsed and injected at build time).',
'暂无结构化日志数据:请运行 build-site.ps1 重新生成,构建脚本会解析 CHANGELOG.md 并注入 data.js。':
'No structured changelog data yet — run build-site.ps1 to regenerate; the build parses CHANGELOG.md into data.js.',
'更新日志加载中…': 'Loading changelog…',
'重试': 'Retry',
'更新日志加载失败或为空,请检查 site/changelog.json 后重试。':
'The changelog failed to load or is empty. Check site/changelog.json and retry.',
'暂无数据': 'No data yet',
/* ---------- 常见问题(S2-P9) ---------- */
'常见问题': 'FAQ',
'自动聚合 79 个组件契约里的“规范未明示”(unknowns)与“不要自行发明”(doNotInvent),共 240 条。支持按组件浏览与关键词过滤。':
'Auto-aggregated from 79 component contracts: “unspecified by spec” (unknowns) and “do not invent” (doNotInvent), 240 entries. Browse by component or filter by keyword.',
'搜索问题,如:宽度、省略、对齐…': 'Search, e.g. width, ellipsis, alignment…',
'搜索常见问题': 'Search FAQ',
'清空搜索': 'Clear search',
'按 / 聚焦搜索': 'Press / to focus search',
'无匹配问题': 'No matching questions',
'(模糊匹配)': ' (fuzzy match)',
'无匹配问题(已尝试模糊匹配)': 'No matching questions (fuzzy match tried)',
'↑↓ 定位 · Enter 跳转 · Esc 清空': '↑↓ Move · Enter Open · Esc Clear',
'规范未明示': 'Unspecified by spec',
'不要自行发明': 'Do not invent',
'卡片 hover 交互规范': 'Card hover interaction spec',
'卡片网格间距规范': 'Card grid spacing spec',
'不要自行发明(设计边界):': 'Do not invent (design boundary):',
'规范未明示(待确认):': 'Unspecified by spec (needs decision):',
'这类条目不是待实现功能清单,而是明确禁止把实现细节当成设计规范。': 'These are not an implementation backlog; they mark details that must not be presented as design rules.',
'这类条目不是报错,而是规格还没有给出可执行答案,生成前需要补充设计决策。': 'These are not errors; the spec has no executable answer yet and needs a design decision before generation.',
'这是什么意思': 'What does this mean',
'为什么会出现': 'Why is it here',
'需要确认什么': 'What needs deciding',
'指整张卡片在鼠标悬停和键盘聚焦时是否产生反馈,不是卡片内部链接或按钮自己的 hover 状态。': 'Whether the whole card responds to pointer hover and keyboard focus; this is separate from hover on links or buttons inside the card.',
'现有规范只定义了卡片默认低阴影与悬停中阴影,没有定义整卡是否可点击、边框或位移变化、过渡时长、光标和键盘 focus 的完整状态矩阵。': 'The spec only defines low elevation by default and medium elevation on hover; it does not define whether the whole card is clickable or its border, movement, transition, cursor, and keyboard-focus states.',
'需要先确认卡片的交互语义,再补齐 hover、focus-visible、active 和不可交互卡片的状态规则。': 'Confirm the card interaction semantics first, then define hover, focus-visible, active, and non-interactive card states.',
'指同一栅格中相邻卡片之间的 gap,以及不同容器宽度下 gap 是否保持不变。': 'The gap between adjacent cards in one grid, including whether it stays fixed as the container width changes.',
'通用规范只给出组件之间 16px/24px 的间距梯度,CardList 只说明采用栅格,没有给出卡片专用 gap、列数或响应式断点。': 'The general spec only gives a 16px/24px component-spacing scale, while CardList only says to use a grid; no card-specific gap, column count, or responsive breakpoints are defined.',
'需要确认 CardList 的默认 gap、列数和响应式断点后,才能把实现值升级为正式契约。': 'Confirm CardList’s default gap, column count, and responsive breakpoints before promoting an implementation value into the formal contract.',
'不要自行发明(设计边界):': 'Do not invent (design boundary):',
'规范未明示(待确认):': 'Unspecified by spec (needs decision):',
'这类条目不是待实现功能清单,而是明确禁止把实现细节当成设计规范。': 'These are not an implementation backlog; they mark details that must not be presented as design rules.',
'这类条目不是报错,而是规格还没有给出可执行答案,生成前需要补充设计决策。': 'These are not errors; the spec has no executable answer yet and needs a design decision before generation.',
'这是什么意思': 'What does this mean',
'为什么会出现': 'Why is it here',
'需要确认什么': 'What needs deciding',
'命中': 'Matched',
'条,': ' entries, ',
'个组件': ' components',
'共': 'Total ',
'条,': ' entries, ',
'个组件有条目': ' components have entries',
'加载中…': 'Loading…',
'核心组件契约:dims(变体维度)、variants、usage(使用要点)、structure、anatomy、doNot(不发明)、unknowns(未明示);data.js 外壳仅留 hasContract,详情见 site/details/<slug>.json':
'Core component contract: dims, variants, usage, structure, anatomy, doNot, unknowns; data.js keeps only hasContract; see site/details/<slug>.json',
'规格说明加载中…': 'Loading specification…',
'避坑指南加载中…': 'Loading guidelines…',
'设计契约加载中…': 'Loading design contract…',
'何时使用': 'When to Use',
'本组件暂无独立规格说明,参见 ': 'No standalone spec for this component; see ',
'代码演示': 'Demos',
'基础用法': 'Basic Usage',
'完整的组件演示,包含常用状态与场景。': 'A complete component demo covering common states and scenarios.',
/* P21 逐示例卡片:一个使用场景 = 一块预览 + 一块调用代码 */
'每个使用场景对应一块预览与一块调用代码。': 'Each usage scenario has its own preview and calling code.',
'示例加载中…': 'Loading examples…',
'复制代码': 'Copy code',
'打开完整演示页': 'Open the full demo page',
'逐字取自演示页': 'Verbatim from the demo page',
'演示数据 + API 表': 'Demo data + API table',
'依据 API 表推导': 'Derived from the API table',
'该场景的演示脚本依赖整页布局,此预览为整页形态': 'This scenario’s demo script depends on the full-page layout, so the preview shows the whole page',
'预览为 H5 形态(各端实现视觉一致);代码按「':
'The preview is the H5 form (all platforms render identically); code defaults to “',
'」默认选中,可切到其它端对照。': '” and can be switched to other platforms for comparison.',
'视觉演示为 H5 形态(各端实现视觉一致);下方代码与资源已按「':
'The visual demo is the H5 form (all platforms render identically); the code and resources below are filtered to “',
'」过滤。': '”.',
'组件 API 规范': 'Component API',
'组件 API': 'API',
'无障碍与键盘交互': 'Accessibility & Keyboard',
'无障碍指引': 'Accessibility',
'设计避坑指南 (Do\'s & Don\'ts)': 'Do’s & Don’ts',
'设计避坑': 'Guidelines',
'设计契约': 'Design Contract',
'实现资源': 'Implementation',
'相关组件': 'Related Components',
'按「相似功能 / 常搭配使用」维度整理,点击跳转。':
'Grouped by “similar function / often used together” — click to jump.',
'同属': 'Same category: ',
'分类': '',
'遵循 W3C WAI-ARIA 规范,组件内置标准键盘交互与屏幕阅读器无障碍支持。':
'Follows W3C WAI-ARIA: standard keyboard interaction and screen reader support are built in.',
'属性 (Props)': 'Props',
'事件 (Events / Emits)': 'Events / Emits',
'插槽 (Slots)': 'Slots',
'参数名': 'Prop',
'事件名': 'Event',
'插槽名': 'Slot',
'类型': 'Type',
'默认值': 'Default',
'必填': 'Required',
'可选': 'Optional',
'回调参数': 'Callback args',
'按键': 'Key',
'交互说明': 'Interaction',
'将焦点移入当前组件或在可聚焦子项间依次流转':
'Move focus into this component, or cycle through its focusable children',
'反向移动焦点到上一个交互元素': 'Move focus back to the previous interactive element',
'触发按钮点击动作,执行绑定的业务逻辑': 'Activate the button and run its bound logic',
'确认输入内容或提交当前表单': 'Confirm input or submit the current form',
'清除当前临时输入或收起下拉联想菜单': 'Clear the current input or collapse the suggestion menu',
'展开或收起下拉候选列表': 'Expand or collapse the dropdown list',
'在下拉选项菜单中高亮切换候选项目': 'Move the highlight between dropdown options',
'收起下拉菜单并保持输入框焦点': 'Collapse the dropdown and keep focus in the input',
'快捷关闭当前弹窗并还原底层焦点': 'Close the current dialog and restore the underlying focus',
'Tab (循环锁定)': 'Tab (focus trap)',
'弹窗激活时,焦点锁定在弹窗内部,不会跳出到蒙层外部背景':
'While a dialog is open, focus stays trapped inside it and cannot escape to the background',
'在导航标签项或步骤之间切换激活状态': 'Switch the active state between tabs or steps',
'快速定位到首个或末尾标签项': 'Jump to the first or last tab',
'在数据行或树形节点之间上下导航': 'Navigate up and down between rows or tree nodes',
'快速切换当前行或节点的勾选状态': 'Toggle the checked state of the current row or node',
'✅ 推荐做法 (Do)': '✅ Do',
'❌ 避免反模式 (Don\'t)': '❌ Don’t',
'契约 JSON ✓': 'Contract JSON ✓',
'API 源码提炼': 'API from source',
'该组件暂无契约 JSON,API 表由 5 端源码自动提炼':
'No contract JSON for this component; the API table is extracted from the 5 platform sources',
'测试页 →': 'Test page →',
'场景速览(': 'Scenarios (',
' 个典型用法)': ' typical usages)',
'当前框架:<strong>': 'Current stack: <strong>',
'</strong> —— 仅展示该端需要的文件。切换框架请使用顶部选择器。':
'</strong> — only files needed by this platform are shown. Use the top selector to switch.',
'新窗口打开': 'Open in new tab',
'大小': 'Size',
'操作': 'Action',
'查看其他 ': 'View the other ',
' 个端的文件': ' platform files',
'查看源码': 'View source',
'打开该端独立组件页': 'Open the standalone component page for this platform',
'变体维度': 'Variant Dimensions',
'代表变体': 'Representative Variants',
'使用要点': 'Usage Hints',
'结构规格': 'Structure',
'结构解剖': 'Anatomy',
'不要自行发明:': 'Do not invent:',
'规范未明示(待补充):': 'Undefined by spec (to be clarified):',
'上一篇': 'Previous',
'下一篇': 'Next',
'同属弹层家族,按承载内容与打断强度选择': 'Same overlay family — pick by content and interruption level',
'数据列表的不同形态,按层级与信息量选择': 'Different forms of data lists — pick by hierarchy and density',
'操作触发与选项切换的相近形态': 'Related forms for triggering actions and switching options',
'输入类组件,按提示方式与约束选择': 'Input components — pick by hint style and constraints',
'选择类组件,按层级深度与数量选择': 'Selection components — pick by depth and count',
'数值输入的相近形态': 'Related numeric input forms',
'卡片式选项与开关组合': 'Card-style options and switch groups',
'流程与视图组织的相近形态': 'Related forms for organising flows and views',
/* ---------- 代码区控制条 / 在线测试 ---------- */
'显示代码': 'Show code',
'隐藏代码': 'Hide code',
'在线测试': 'Playground',
'在新页面打开在线测试:任意修改 H5 源码,实时预览效果(不影响源文件)':
'Open the playground in a new page: edit the H5 source freely and preview live (source file untouched)',
'图标预览': 'Icon gallery',
'浏览全部图标:网格 + 搜索 + 点击复制名称或 SVG 代码':
'Browse every icon: grid + search + click to copy the name or the SVG code',
'复制源码': 'Copy source',
'复制': 'Copy',
'已复制 ✓': 'Copied ✓',
/* ---------- 主题面板 ---------- */
'主题定制': 'Theme',
'重置': 'Reset',
'复制覆盖代码': 'Copy override CSS',
'覆盖代码可直接粘贴到令牌文件之后,即完成整站换色。':
'Paste the override CSS after the token file to recolor the whole site.',
'主题模式': 'Theme mode',
'当前选中': 'Selected',
'实际生效': 'Active now',
'日间模式': 'Light mode',
'夜间模式': 'Dark mode',
'自动模式': 'System mode',
'{m}(当前:{e})': '{m} (now: {e})',
'深色 / 浅色模式切换': 'Toggle dark / light mode',
'回到顶部': 'Back to top',
'品牌主色': 'Brand',
'主色悬停': 'Brand hover',
'主色点击': 'Brand active',
'主色浅背景': 'Brand tint',
'科技蓝': 'Tech Blue',
'青碧': 'Cyan',
'极夜紫': 'Polar Violet',
'暖橙': 'Warm Orange',
'绯红': 'Crimson',
'松石绿': 'Turquoise',
/* ---------- 设计规范页 ---------- */
'设计规范': 'Design Tokens',
'Kole UI 设计系统的全部设计令牌,共 <strong>': 'All design tokens of the Kole UI system — <strong>',
'</strong> 项。所有组件均基于这些令牌构建,来源 <code>colors_and_type.css</code>。':
'</strong> in total. Every component is built on these tokens, sourced from <code>colors_and_type.css</code>.',
'色彩 · 品牌色': 'Color · Brand',
'色彩 · 背景与表面': 'Color · Background & Surface',
'色彩 · 文字色': 'Color · Text',
'色彩 · 边框': 'Color · Border',
'色彩 · 语义色': 'Color · Semantic',
'色彩 · 遮罩与焦点': 'Color · Overlay & Focus',
'含状态色与外发光': 'with state colors and focus ring',
'字体': 'Typography',
'字体族 Kole 123': 'Family Kole 123',
'Kole 字体示例': 'Kole sample',
'间距(4px 基准)': 'Spacing (4px base)',
'圆角': 'Radius',
'阴影(3 层克制投影)': 'Shadow (3 restrained levels)',
'控件高度': 'Control Height',
'令牌导出': 'Token Export',
'令牌可导出为三种标准格式,供设计工具与其它工程直接消费。文件由 <code>build-site.ps1</code> 在构建时生成,与上方展示的取值始终同源。':
'Tokens export to three standard formats for design tools and other projects. Files are generated by <code>build-site.ps1</code> at build time, always in sync with the values shown above.',
'CSS 自定义属性': 'CSS Custom Properties',
'直接 @import 或复制 :root 变量块': 'Import directly or copy the :root block',
'Design Tokens 社区组标准($value / $type)': 'W3C Design Tokens Community Group standard ($value / $type)',
'Tokens Studio 插件可直接导入': 'Importable by the Tokens Studio plugin',
/* ---------- 搜索 / 其他 ---------- */
'页面没切换': 'Page did not change',
'数据加载失败:site/data.js 缺失或为空。请先在仓库根目录运行 build-site.ps1 重新生成。':
'Failed to load data: site/data.js is missing or empty. Run build-site.ps1 in the repository root to regenerate.',
/* ---------- 文件类型 ---------- */
'H5 静态页': 'H5 page',
'样式表': 'Stylesheet',
'React 组件': 'React component',
'Vue 2 组件': 'Vue 2 component',
'Vue 3 组件': 'Vue 3 component',
/* ---------- 事件/插槽说明 ---------- */
'回调触发事件 (Event callback)': 'Event callback',
'子节点内容 (children)': 'Child content (children)',
'双向绑定更新事件 (v-model)': 'Two-way binding update (v-model)',
'组件交互触发事件': 'Emitted on component interaction',
'交互回调触发事件': 'Emitted on interaction callback',
'默认插槽(组件文本或主体内容)': 'Default slot (component text or body content)',
' 自定义扩展插槽': ' Custom extension slot',
/* ---------- 表格表头(属性/事件/插槽/按键表) ---------- */
'<thead><tr><th>参数名</th><th>说明</th><th>类型</th><th>默认值</th><th>必填</th></tr></thead>':
'<thead><tr><th>Prop</th><th>Description</th><th>Type</th><th>Default</th><th>Required</th></tr></thead>',
'<thead><tr><th>事件名</th><th>说明</th><th>回调参数</th></tr></thead>':
'<thead><tr><th>Event</th><th>Description</th><th>Callback args</th></tr></thead>',
'<thead><tr><th>插槽名</th><th>说明</th></tr></thead>':
'<thead><tr><th>Slot</th><th>Description</th></tr></thead>',
'<thead><tr><th style="width:160px">按键</th><th>交互说明</th></tr></thead>':
'<thead><tr><th style="width:160px">Key</th><th>Interaction</th></tr></thead>',
'<thead><tr><th style="width:26%">资源</th><th style="width:38%">路径</th><th>说明</th></tr></thead><tbody></tbody>':
'<thead><tr><th style="width:26%">Resource</th><th style="width:38%">Path</th><th>Description</th></tr></thead><tbody></tbody>',
'<thead><tr><th style="width:30%">字段</th><th>内容</th></tr></thead><tbody></tbody>':
'<thead><tr><th style="width:30%">Field</th><th>Contents</th></tr></thead><tbody></tbody>',
'<span class="badge-req">必填</span>': '<span class="badge-req">Required</span>',
'<span class="badge-opt">可选</span>': '<span class="badge-opt">Optional</span>',
/* ---------- 零散片段 ---------- */
'断言通过': 'assertions passed',
'预览': 'Preview',
'全部 (': 'All (',
'共 <strong>': '',
'</strong> 个组件(核心 <strong>': ' components (core ',
'</strong> · 扩展 <strong>': ' · extension ',
'</strong>),覆盖 ': '), covering ',
'大类。基于 Kole UI 设计系统规范构建,提供 H5 / React / Vue 2 / Vue 3 四端实现。':
' categories. Built on the Kole UI specification with H5 / React / Vue 2 / Vue 3 implementations.',
'色彩 · ': 'Color · ',
' 个组件': ' components',
'组件': 'Components',
/* ---------- 设计规范色彩分组 ---------- */
'品牌色': 'Brand',
'背景与表面': 'Background & Surface',
'文字色': 'Text',
'边框': 'Border',
'语义色': 'Semantic',
'遮罩与焦点': 'Overlay & Focus',
/* ---------- 设计避坑(按钮/输入/表格/弹窗/通用) ---------- */
'主行动区原则上只保留一个 Primary 主按钮': 'Keep only one Primary button per primary action area',
'危险破坏性操作配合二次确认弹窗使用': 'Pair destructive actions with a confirmation dialog',
'加载中状态下设置 disabled 避免二次误触': 'Set disabled while loading to prevent double submission',
'避免在同一行并列 3 个以上相同颜色的主按钮': 'Avoid three or more same-colored primary buttons in one row',
'避免在表单提交操作中使用弱化文字按钮': 'Avoid subdued text buttons for form submission',
'不要在非页面跳转场景滥用链接按钮': 'Do not overuse link buttons outside navigation',
'输入框建议配合明确的 Label 或 Placeholder': 'Pair inputs with an explicit label or placeholder',
'密码及敏感凭据字段提供显隐切换图标': 'Provide a show/hide toggle for passwords and credentials',
'必填项在标签旁显式标注红星 (*)': 'Mark required fields with a red asterisk (*) next to the label',
'避免仅依赖 Placeholder 传达关键业务提示': 'Do not rely on the placeholder alone to convey critical information',
'避免移动端使用过长不可换行的输入区域': 'Avoid long non-wrapping input areas on mobile',
'不要在禁用态下保留光标闪烁效果': 'Do not keep a blinking caret in the disabled state',
'列数较多(≥8列)时开启固定列与横向滚动': 'Enable fixed columns and horizontal scrolling at 8+ columns',
'长列表数据采用分页或虚拟滚动承载': 'Carry long lists with pagination or virtual scrolling',
'空数据状态提供具体的引导图文': 'Provide concrete guidance for the empty state',
'避免单元格无限制换行撑大表格高度': 'Avoid unbounded cell wrapping inflating row height',
'避免全表无边框导致复杂数据对比混淆': 'Avoid a fully borderless table where dense data blurs together',
'不要在无分页情况下一次性渲染数百行 DOM': 'Do not render hundreds of rows without pagination',
'弹窗宽度应适配内容复杂度,标准为 520px': 'Size the dialog to the content; 520px is the standard width',
'重要输入表单弹窗阻止点击蒙层空白处误关闭': 'Block mask-click dismissal for important form dialogs',
'弹窗关闭后应将焦点自动交还触发按钮': 'Return focus to the trigger button after the dialog closes',
'避免多层弹窗连续嵌套破坏视觉层级': 'Avoid deeply nested dialogs that break the visual hierarchy',
'避免在弹窗内塞入两屏以上的长篇表单': 'Avoid cramming more than two screens of form into a dialog',
'不要无确定按钮直接让用户点击右上角叉号关闭': 'Do not force users to close via the corner X without a confirm button',
'优先遵循 Kole UI 统一设计令牌体系': 'Prefer the unified Kole UI token system',
'保持组件语义化标签,便于辅助工具识别': 'Keep semantic markup so assistive tools can interpret it',
'复杂业务合理组合基础原子组件': 'Compose complex business UI from the base atomic components',
'避免自行通过 style 强行覆盖组件内边距': 'Avoid forcibly overriding component padding via inline style',
'避免自创非常规控件高度破坏栅格对齐': 'Avoid custom control heights that break grid alignment',
'不要移除原生的键盘焦点可视化轮廓': 'Do not remove the native keyboard focus outline',
'以下为通用键盘交互基线建议,具体组件是否支持弹窗、焦点锁定或方向键导航,请以实现与契约说明为准。':
'Generic keyboard interaction baselines below. Check the implementation and contract for dialog, focus-trapping or arrow-key support.',
'弹窗类组件建议将焦点保持在弹窗内部,实际行为以实现为准':
'Dialog-like components are expected to keep focus inside; check the implementation for actual behavior',
'部分反馈组件支持快捷关闭,实际行为以实现为准':
'Some feedback components support quick dismissal; check the implementation for actual behavior',
'H5 演示源码加载失败,请检查网络或稍后重试。':
'Failed to load the H5 demo source. Check the network connection and retry later.',
'搜索组件': 'Search components',
/* ---------- 快速开始 · 全局配置 / 收尾(文档站内容改造,S6-P37) ---------- */
'本节将介绍如何在项目中使用 Kole UI。按下面的顺序走一遍,即可完成从安装到渲染出第一个组件的全过程;每一步都给出可直接拷贝的命令或代码。':
'This section shows how to use Kole UI in your project. Follow the steps in order to go from installation to rendering your first component — every step comes with a command or snippet you can copy as-is.',
'安装:从自建 Gitea 的 npm 私有源取包,或直接取仓库源码':
'Install: from the self-hosted Gitea npm registry, or straight from the repository sources',
'引入设计令牌:颜色、字号、间距、圆角都以 --kole-* 变量暴露':
'Import design tokens: colours, type scale, spacing and radii are all exposed as --kole-* variables',
'按端取用组件:H5 / CSS / React / Vue 2 / Vue 3 五端同源':
'Take components per stack: one source, five targets (H5 / CSS / React / Vue 2 / Vue 3)',
'全局配置:覆盖令牌做主题定制、开启暗色模式':
'Global configuration: override tokens to theme, switch on dark mode',
'目录结构与命名约定,以及接下来该看什么':
'Directory layout, naming conventions, and where to go next',
'没有包管理器也能用:所有实现都是可读的源码文件,拷进工程即可。每个组件在 <code>frameworks/</code> 下有五种形态(H5 / CSS / React / Vue 2 / Vue 3),同一组件在五端的结构与类名一致,按你的技术栈取用:':
'No package manager required: every implementation is a readable source file you can copy into your project. Each component ships in five forms under <code>frameworks/</code> (H5 / CSS / React / Vue 2 / Vue 3) with matching structure and class names across targets:',
'引入方式:全量与按需':
'Importing: whole set vs. on demand',
'本系统不区分「完整安装」与「按需引入」两套包——组件以源码文件发布,取哪几个文件就是引入哪几个组件。要一次拿到全部组件样式,用聚合文件 <code>components.css</code>;只要某几个组件,就拷对应实现文件加一份令牌文件。':
'There is no separate "full install" and "on-demand" package — components ship as source files, so importing a component means taking its files. For every component style at once use the aggregate <code>components.css</code>; for a few components just copy those implementations plus one token file.',
'全局配置(主题与暗色模式)':
'Global configuration (theme and dark mode)',
'定制主题不需要构建插件、也不需要主题包:改主题就是改令牌值。在你自己项目的作用域里重定义 <code>--kole-*</code> 变量即可——组件样式读的是同一批变量,改完立即生效。':
'Theming needs no build plugin and no theme package: a theme is a set of token values. Redefine <code>--kole-*</code> variables in your own scope — component styles read the same variables, so changes apply immediately.',
'暗色模式走同一套令牌:令牌文件里已经写好 <code>html.kole-dark</code> 组,给根元素加上这个类名即可整体反色,不需要为暗色重写任何组件样式。是否跟随系统由宿主决定——本站顶栏的「自动模式」默认开启,用 <code>matchMedia("(prefers-color-scheme: dark)")</code> 判断后加类;用户手动选日间或夜间后,这个选择会覆盖系统并记在 localStorage 的 <code>kole-mode</code> 键里。':
'Dark mode runs on the same token set: the token file already ships an <code>html.kole-dark</code> group, so adding that class to the root element inverts the whole system — no dark-specific component styles needed. Whether to follow the OS is up to the host: this site starts in "auto" mode, which adds the class after testing <code>matchMedia("(prefers-color-scheme: dark)")</code>; an explicit light or dark choice overrides the OS and is remembered in the <code>kole-mode</code> key of localStorage.',
'令牌全量清单见 <code>colors_and_type.css</code>(75 个唯一令牌名,暗色组在原文件内重定义),结构化数据见同目录的 <code>css.json</code>。本站顶栏「主题定制」面板里的每一处调整,都会实时生成对应的覆盖代码。':
'The full token list lives in <code>colors_and_type.css</code> (75 unique token names; the dark group redefines them in the same file) with structured data in <code>css.json</code> beside it. Every adjustment in the top bar\'s theme panel generates the matching override code.',
'开始使用':
'Getting started',
'到这里环境已经搭好了,接下来挑组件写页面即可。四个常用的下一步:':
'Your environment is ready — pick components and start building pages. Four useful next steps:',
'79 个组件按分类列出':
'All 79 components, grouped by category',
'挑组件:每个卡片可在线预览,点进去看演示与 API':
'Pick components: every card previews live; open one for demos and API',
'用户管理页':
'User management page',
'模板页库':
'Page Templates',
'5 个典型后台页面,展示组件在真实业务里的组合方式。全部只用本库令牌与组件样式,复制即可作为项目起点。':
'Five typical admin pages showing how components combine in real workflows. Built only from this library\u2019s tokens and component styles — copy one as your project starting point.',
'登录页':
'Login',
'表单校验 · 提交反馈':
'Form validation · submit feedback',
'数据看板':
'Dashboard',
'指标卡 · 图表面板 · 概览表格':
'Metric cards · chart panel · overview table',
'订单列表':
'Order list',
'筛选 · 表格 · 批量操作 · 分页':
'Filters · table · bulk actions · pagination',
'系统设置':
'Settings',
'分区表单 · 开关组 · 保存反馈':
'Sectioned form · switch group · save feedback',
'用户管理':
'User management',
'表格 · 弹窗 · 消息反馈':
'Table · modal · message feedback',
'看组合:真实管理页面里组件的搭配方式':
'See composition: how components combine in a real admin page',
'未明示项与实现差异':
'Undocumented points and implementation gaps',
'避坑:规格没写、实现有分歧的地方都在这':
'Avoid pitfalls: everything the spec leaves open and where implementations differ',
'颜色 / 字号 / 间距 / 圆角 / 阴影':
'Colour / type scale / spacing / radius / shadow',
'定口径:令牌的取值来源与使用场景':
'Settle the rules: where token values come from and when to use them',
'开发指南':
'Guide',
'规格':
'Spec',
'命名':
'Naming',
'源码':
'Source',
'规格未明示':
'Not stated in the spec',
'取值:':
'Values: ',
'按 API 命名释义(非规格原文)':
'Gloss of the API name (not spec wording)',
'来源:组件源码注释':
'Source: component source comment',
'说明列出处:<strong>规格</strong>为规格原文分条(悬停看原文)、<strong>命名</strong>为 API 名称释义、<strong>源码</strong>为组件源码注释;三者都没有的条目显式标注「规格未明示」——':
'Where the Description column comes from: <strong>Spec</strong> quotes the spec line by line (hover to read it), <strong>Naming</strong> glosses the API name, <strong>Source</strong> cites a source comment. Rows with none of the three are marked "Not stated in the spec" —',
'里按组件汇总了这些空缺。':
' collects these gaps per component.',
/* ---------- 组件 API 表 · 属性说明(出处可溯的说明列,S6-P37) ---------- */
'unit':
'Unit',
'内容':
'Content',
'内边距':
'Inner padding',
'分隔符':
'Separator',
'列数':
'Column count',
'列配置':
'Column config',
'占位提示文本':
'Placeholder text',
'双向绑定值':
'Two-way bound value',
'取值范围':
'Value range',
'取消按钮文本':
'Cancel button text',
'员工数据':
'Employee data',
'品牌标识':
'Brand identity',
'国际区号列表':
'Country/region code list',
'图标':
'Icon',
'图片列表':
'Image list',
'头像地址':
'Avatar source',
'字号':
'Font size',
'字段配置':
'Field config',
'字符长度':
'Character length',
'名称':
'Name',
'尺寸':
'Size',
'色调':
'Tone',
'是否持续旋转':
'Continuously spinning',
'已选中项':
'Selected keys',
'弹出位置':
'Popup placement',
'当前激活项':
'Active key',
'快捷预设':
'Presets',
'打开方式':
'Link target',
'持续时间':
'Duration',
'描述文本':
'Description text',
'提示文案':
'Hint text',
'操作文本':
'Action text',
'数据源':
'Data source',
'数据项':
'Items',
'文本':
'Text',
'文案映射':
'Text map',
'方向':
'Direction',
'旋转角度':
'Rotation angle',
'是否允许半选':
'Allow half selection',
'是否全屏':
'Fullscreen',
'是否加载中':
'Loading state',
'是否只读':
'Read-only',
'是否可折叠':
'Collapsible',
'是否可搜索':
'Searchable',
'是否可新增':
'Addable',
'是否可清空':
'Clearable',
'是否可点击':
'Clickable',
'是否可筛选':
'Filterable',
'是否可见':
'Visible',
'是否可选择':
'Selectable',
'是否处于错误态':
'Error state',
'是否多选':
'Multiple selection',
'是否带阴影':
'Shadowed',
'是否折叠':
'Collapsed',
'是否掩码显示':
'Masked display',
'是否提供不再询问':
'Offer "do not ask again"',
'是否显示全选':
'Show select-all',
'是否显示刻度':
'Show ticks',
'是否显示强度':
'Show strength meter',
'是否显示数值文案':
'Show value label',
'是否显示文本':
'Show text',
'是否显示环形进度':
'Show ring progress',
'是否显示输入框':
'Show input',
'是否显示边框':
'Show border',
'是否深色外观':
'Dark appearance',
'是否激活':
'Active',
'是否禁用':
'Disabled',
'是否自动播放':
'Autoplay',
'是否行内展示':
'Inline display',
'是否隐藏底部操作区':
'Hide footer actions',
'最大值':
'Max value',
'最小值':
'Min value',
'标签字段':
'Label field',
'标签文本':
'Label text',
'标识字段':
'Id field',
'标题':
'Title',
'模式':
'Mode',
'次要文本':
'Secondary text',
'步长':
'Step',
'步骤数据':
'Steps data',
'汇总列':
'Summary column',
'汇总配置':
'Summary config',
'滚动偏移(避开吸顶高度)':
'Scroll offset (clear sticky header)',
'点击遮罩是否可关闭':
'Close on mask click',
'状态':
'State',
'用户列表':
'Users',
'百分比':
'Percentage',
'省份数据':
'Province data',
'确定按钮文本':
'Confirm button text',
'确认按钮文案':
'Confirm button label',
'确认按钮样式':
'Confirm button style',
'空态提示文本':
'Empty-state text',
'索引':
'Index',
'绑定值':
'Bound value',
'行唯一键':
'Row key',
'行数据':
'Row data',
'表情图标':
'Emoji icon',
'触发阈值':
'Trigger threshold',
'趋势值':
'Trend value',
'趋势文案':
'Trend label',
'轮播间隔':
'Autoplay interval',
'选项数据':
'Options',
'错误提示':
'Error message',
'错误提示文本':
'Error text',
'间距':
'Gap',
'颜色':
'Colour',
'骨架块配置':
'Skeleton block config',
'默认展开项':
'Default expanded keys',
/* ---------- 组件 API 表 · 事件说明(按 emit 调用点生成,S6-P37) ---------- */
'值变化时触发':
'Fires when the value changes',
'关闭时触发':
'Fires on close',
'出错时触发':
'Fires on error',
'刷新时触发':
'Fires on refresh',
'勾选状态变化时触发':
'Fires when the checked state changes',
'取消操作时触发':
'Fires on cancel',
'失去焦点时触发':
'Fires on blur',
'排序变化时触发':
'Fires when sorting changes',
'提交时触发':
'Fires on submit',
'点击「发消息」时触发':
'Fires on "Send message"',
'点击「查看详情」时触发':
'Fires on "View details"',
'点击「返回首页」时触发':
'Fires on "Back to home"',
'点击导出按钮时触发':
'Fires on export',
'点击操作按钮时触发':
'Fires on action button click',
'点击数据行时触发':
'Fires on row click',
'点击新增标签时触发':
'Fires on add-tab click',
'点击时触发':
'Fires on click',
'点击次要操作按钮时触发':
'Fires on secondary action click',
'点击步骤节点时触发':
'Fires on step click',
'点击确认按钮时触发':
'Fires on confirm click',
'点击遮罩时触发':
'Fires on mask click',
'确认操作时触发':
'Fires on confirm',
'移除标签页时触发':
'Fires when a tab is removed',
'获得焦点时触发':
'Fires on focus',
'进入编辑时触发':
'Fires on entering edit mode',
'选中某一项时触发':
'Fires when an item is selected',
'选中项变化时触发':
'Fires when the selection changes',
'重试时触发':
'Fires on retry',
'复制时触发':
'Fires on copy',
'重置时触发':
'Fires on reset',
'页码变化时触发':
'Fires when the page changes',
'每页条数变化时触发':
'Fires when page size changes',
'显示时触发':
'Fires on show',
'隐藏时触发':
'Fires on hide',
'展开时触发':
'Fires on expand',
'加载时触发':
'Fires on load',
'变体':
'Variant',
'链接地址':
'Link URL',
'是否选中':
'Checked',
'总数':
'Total',
'数量':
'Count',
'资源地址':
'Resource URL',
'提示浮层内容':
'Tooltip content',
'是否展开':
'Expanded',
};
var LANG_KEY = 'kole-lang';
var lang = 'zh';
try {
var saved = localStorage.getItem(LANG_KEY);
if (saved === 'en' || saved === 'zh') lang = saved;
} catch (e) { /* ignore */ }
/* 翻译:未收录的源串原样返回(中文),避免出现空白或 key 泄漏 */
function T(s) {
if (lang !== 'en') return s;
return Object.prototype.hasOwnProperty.call(EN, s) ? EN[s] : s;
}
function getLang() { return lang; }
function setLang(next) {
if (next !== 'en' && next !== 'zh') return;
lang = next;
try { localStorage.setItem(LANG_KEY, lang); } catch (e) { /* ignore */ }
document.documentElement.setAttribute('lang', lang === 'en' ? 'en' : 'zh-CN');
}
/* 覆盖率自检:开发期可用来发现漏翻的文案 */
function coverage(strings) {
var hits = strings.filter(function (s) { return Object.prototype.hasOwnProperty.call(EN, s); });
return { total: strings.length, translated: hits.length, missing: strings.filter(function (s) { return !Object.prototype.hasOwnProperty.call(EN, s); }) };
}
window.AA_I18N = { T: T, getLang: getLang, setLang: setLang, coverage: coverage, dict: EN };
document.documentElement.setAttribute('lang', lang === 'en' ? 'en' : 'zh-CN');
})();