diff --git a/docs/HANDOVER-20260801.md b/docs/HANDOVER-20260801.md new file mode 100644 index 0000000..a739e12 --- /dev/null +++ b/docs/HANDOVER-20260801.md @@ -0,0 +1,54 @@ +# 工作交接(2026-08-01 第二轮) + +> 新会话续作入口:先读本文件,再按「六、下一步」继续。历史交接见 `docs/HANDOVER-usage-billing.md`(账单功能,已发布完)。 + +## 一、当前未完成任务(按优先级) + +1. **官网截图归档**(`docs/screenshots/site-2026-08-01/`,14 张 Snipaste 图): + - **当前模型无视觉输入,无法识图**——需用户在会话里切换到支持视觉的模型后逐个查看 + - 确认每张对应界面 → 按官网区块重命名(hero / feature-usage / kimi-oauth / settings…) + - 注意:`.gitignore` 忽略 `Snipaste_*.png`,这些图不进 git,归档目录也只是暂存 +2. **官网规划待拍板**(`docs/WEBSITE-PLAN.md` v2,3 项待定): + - 素材时机:等 v0.7.0 稳定版(推荐)还是用当前 v0.6.x 截图 + - 技术栈:Vite + React + Tailwind(已写入方案,等确认) + - 推荐链接:官网页脚放基元律动等推荐链接,还是不放 + +## 二、v0.6.7 发布状态详情(已完成) + +- **提交**:`ce28252` feat: Kimi 设备授权登录(应用内置 kimi login)+ 外链打开统一走 Rust 命令(v0.6.7) +- **版本**:三处 0.6.7(package.json / Cargo.toml / tauri.conf.json),`check-version.sh 0.6.7` 通过 +- **两仓库**:origin(git.codingplan.site/admin/KimiCodeSwitch)+ github(billowliu2/KimiSwitch)的 main / Dev_20260801 / tag v0.6.7 全部同步 +- **私有库 Release**:https://git.codingplan.site/admin/KimiCodeSwitch/releases/tag/v0.6.7(MSI 6.9MB) +- **GitHub Release**:https://github.com/billowliu2/KimiSwitch/releases/tag/v0.6.7(三平台构建成功,6 个产物齐全,已转正式) +- **本地包**:`src-tauri/target/release/bundle/{nsis,msi}/Kimi Switch_0.6.7_*` +- **v0.6.7 功能**:Kimi 设备授权登录(Device Code Flow,等同 `kimi login`)——`kimi_oauth_start` / `kimi_oauth_poll` 命令 + `KimiOAuthDialog` 前端;授权页/设置页外链统一改走 Rust `open_external_url` 命令(JS 插件版 openUrl 在此环境静默失败,已弃用) + +## 三、关键环境与凭据获取 + +- **代理**:git 全局 `http.proxy=http://127.0.0.1:7897`;推 origin 需 `git -c http.proxy= push` 绕过(schannel 握手失败);调 GitHub API 必须 `-x http://127.0.0.1:7897` +- **GitHub API token**:`printf "protocol=https\nhost=github.com\n\n" | git credential fill` → password 行(临时文件 /tmp/ghcred.txt 可能已失效,重新获取) +- **私有库 API 凭据**:同上 host=git.codingplan.site(/tmp/pcred.txt) +- **models.dev 同步**:`npm run fetch-models-dev`(脚本自动读 git http.proxy 走代理);打包前 `pretauri` 钩子自动同步;离线时用本地已提交 `src/lib/models-dev.json` + last-good 备份恢复 +- **版本发布流程**:check-version → tauri build → commit → 推两仓库 → 私有库 API 建 Release+传 MSI → 推 github tag → CI 完成转正式 + +## 四、官网规划要点(docs/WEBSITE-PLAN.md v2) + +- 定位:多供应商统一管理 + 用量监控(非 Kimi 单一产品) +- 部署:仅 GitHub Pages(**私有库 Gitea Pages 实测未启用**,勿再做镜像方案) +- 技术栈:Vite + React + Tailwind(独立 `website/` 子目录) +- 结构:Hero(供应商列表截图)→ 功能 6 卡 → 性能 → 更新 → 隐私 → 平台 → CTA +- 素材:真实截图+动图;性能指标需实测后如实写 + +## 五、已有交接/文档 + +- `docs/HANDOVER-usage-billing.md`:账单查询功能全量交接(已随 v0.6.4-v0.6.6 发布) +- `docs/USAGE-QUERY-ADAPTATION.md`:账单查询调研 +- `docs/WEBSITE-PLAN.md`:官网规划 v2 +- `docs/screenshots/site-2026-08-01/`:14 张待归档产品截图(需视觉模型) + +## 六、下一步 TODO + +1. 查看后台轮询结果(`TaskList` / `TaskOutput` 或读 `/tasks`):v0.6.7 GitHub CI 完成后转正式 Release +2. 用户切视觉模型后:识图 → 重命名归档 14 张截图 → 更新素材清单 +3. 用户对 3 个待拍板项确认后更新 WEBSITE-PLAN.md +4. 后续:官网 M0-M4 里程碑(等拍板 + 稳定版) diff --git a/docs/WEBSITE-PLAN.md b/docs/WEBSITE-PLAN.md new file mode 100644 index 0000000..4fcb708 --- /dev/null +++ b/docs/WEBSITE-PLAN.md @@ -0,0 +1,138 @@ +# KimiSwitch 官网建设规划(Landing Page)v4 + +> 状态:方案 v4 定稿(待启动实现)。参考对象:[KimiCodeBar 官网](https://xifandev.github.io/KimiCodeBar/)(GitHub Pages 单页营销站)。 +> v4 变更:3 项待拍板全部定案(素材用 v0.6.7 / 技术栈 Vite+React+Tailwind / 推荐链接页脚);素材完整度 ~95%;性能实测数据已写入(WS 93 MB / Private 34 MB)。 + +## 一、目标与定位 + +为 KimiSwitch 打造一个**单页营销官网(landing page)**: +- 展示核心卖点:**多 LLM 供应商统一管理 + 一键切换 + 用量/账单监控**(主角,不是单一 Kimi 产品) +- 建立可信度:开源(MIT)、隐私(本地存储)、官方直连 +- 提供下载入口:Windows 安装包(GitHub Releases + 私有库 Releases) +- 引流与推广:推荐链接低调放页脚(不喧宾夺主) + +## 二、参考拆解:KimiCodeBar 官网结构 + +| 区块 | 内容 | 可借鉴点 | 是否照搬 | +| --- | --- | --- | --- | +| Hero | 实时用量卡片 + 主标题 + CTA | 产品实拍做主视觉 | 部分(见 3.1) | +| Features | "为 Kimi Code 而生":轻量菜单栏 | 一句话定位 + 简短特性 | 是 | +| Kimi Login | 一键授权登录 / API Key 切换 | 认证方式展示 | **否**(降级为功能卡) | +| Performance | Swift 原生、内存 30-50MB、任务管理器对比图 | 硬指标 + 对比图 | 是(指标需实测) | +| Auto Update | 自动探测更新、一键安装 | 功能卖点 | 是 | +| Showcase | 明暗双主题截图 | 真实截图轮播 | 是 | +| Privacy | 本地存储 / 官方直连 / 开源可审计 | 三卡片信任区 | 是 | +| Platforms | macOS 已发布 / Windows 开发中 | 平台状态 | 是(镜像反转) | +| 尾屏 CTA | 强行动号召 + 下载按钮 | 是 | 是 | + +风格特征:深色主题、大字号排版、真实截图/动图、数据指标卡片、滚动锚点导航。 + +## 三、KimiSwitch 官网结构规划(修订版) + +### 3.1 Hero +- 主标题:**"一个应用,管理你所有的 AI 供应商"**(主)+ 副标题"一键切换 · 用量监控 · 账单一目了然" +- 主视觉:**主界面供应商列表 + 切换**截图(核心差异点,非用量卡片——用量卡是 KimiCodeBar 的产品本体,不是我们的) +- CTA:下载 Windows 版(主)+ 查看 GitHub 源码(次) + +### 3.2 功能区块(6 卡,一屏一组) +1. **多供应商管理**:Kimi / 智谱 / MiniMax / DeepSeek / OpenRouter / 基元律动等预设,一键添加与切换 +2. **用量与账单监控**:套餐类(5 小时 / 每周用量)+ 按量余额(models.dev 真实价格计算成本)卡片直显 +3. **Kimi 一键授权登录**:内置设备码授权(等同 `kimi login`),浏览器授权即用、自动续期 ← **Kimi 相关只此一张卡** +4. **配置用量查询**:全屏配置页、NewAPI 模板、超时/自动刷新、测试查询 +5. **智能模型发现**:模型能力 / 上下文自动同步 models.dev +6. **自动更新**:检查更新(私有库优先、GitHub 回退),一键下载安装 + +### 3.3 认证方式区块 +- **删除**独立大区块。Kimi 授权并入 3.2 功能卡 3;API Key 方式在主界面截图里自然体现(普通供应商编辑 API Key 输入框) + +### 3.4 性能 / 技术区块 +- Tauri + Rust 内核 + WebView2;常驻托盘 +- 实测(28 核 Windows,用户运行 v0.6.7): + - **Working Set 93 MB / Private WS 34 MB**(程序空闲态) + - 52 线程 / 1086 句柄;CPU 空闲 0%,查询时短暂升高 + - 对比 KimiCodeBar(Swift)自报 38 MB —— Tauri 因 WebView2 内核偏重是事实,**不作"碾压"话术** +- 配任务管理器对比图(M2 实测打安装包时补) + +### 3.5 更新区块 +- 检查更新:私有库优先 → GitHub 回退;一键下载 / 安装(截图展示设置面板更新区) + +### 3.6 隐私与信任区块(三卡片) +- 本地存储:配置与用量仅存本机(`~/.kimi-switch` / config.toml) +- 官方直连:账单查询直连各厂商官方 API +- 开源可审计:MIT 全量开源(GitHub) + +### 3.7 平台与下载 +- **Windows:已发布**(.msi / .exe)——主推平台 +- macOS / Linux:规划中(GitHub Actions 已能构建,但未正式适配/发布,如实标注"开发中") +- 下载入口:GitHub Releases 为主 + **私有库 Releases 链接**(国内下载快) + +### 3.8 尾屏 CTA +- **"现在就把所有供应商,放进一个应用"** + 下载按钮 + 当前版本号(构建时注入) + +## 四、视觉与交互方向 + +- 深色为主(对齐 app)、大字号对比排版、圆角卡片、品牌蓝紫渐变(`#3b82f6 → #8b5cf6`) +- 素材:真实截图 + 动图,避免插画风 +- 动效:滚动渐入、数字滚动、截图 hover 缩放,克制 +- 响应式:桌面优先,移动端可看结构与下载按钮 + +## 五、技术选型与部署(已收敛) + +| 项 | 方案 | 说明 | +| --- | --- | --- | +| 技术栈 | **Vite + React + Tailwind**(与主应用技能栈一致) | 定案;后续扩展英文版/多页顺 | +| 构建 | 独立工程 `website/` 子目录,`vite build` 产物纯静态 | 与 tauri 构建隔离 | +| 部署 | **仅 GitHub Pages**(`gh-pages` 分支或独立 repo) | 私有库 Pages **确认未启用**,不做镜像 | +| 域名 | `https://billowliu2.github.io/KimiSwitch/`(默认) | 自定义域名待定 | +| CI | GitHub Actions:website 变更自动构建 → 部署 gh-pages | 独立 workflow | +| 下载链接 | 构建时注入**版本号常量**(v0.6.x),链接指向 GitHub + 私有库 Releases | 发版时改一个常量,不做脚本自动化 | +| SEO | meta description / OG 分享图 / favicon(用 `public/kimi.svg`) | 补进 M1 | + +## 六、素材清单(已就位 ✅) + +- [x] app 主界面截图 ×5:供应商列表(hero)、编辑基本信息、模型映射、Kimi OAuth 对话框、Kimi OAuth 授权成功页 +- [x] 用量仪表盘截图 ×4:浅色/深色/完整版/每日详情 +- [x] 会话管理截图 ×2:浅色/深色 +- [x] 编辑器截图 ×3:基本信息、模型映射、配置 JSON +- [x] 设置弹窗截图 ×1(更新区+超链接+关于) +- [x] 配置用量查询截图 ×1(OAuth 托管模板/变量/超时/测试结果) +- [x] 选择预设供应商截图 ×1(22 个预设卡片) +- [x] 套餐用量卡片特写 ×1(5h/7天) +- [x] kimi CLI 模型选择 TUI ×1(辅助素材) +- [x] 性能实测指标:WS 93 MB / Private 34 MB / 52 threads / 1086 handles +- [ ] 任务管理器对比图(M2 阶段补:打安装包后跑 5-10 分钟采样,含对比标注) +- [ ] OG 分享图(M1 阶段用 hero.png 合成 1200×630) +- [ ] 版本号与下载链接注入(构建常量) + +## 七、里程碑(绑定稳定版) + +1. **M0 前提**:app 进入稳定版(**建议 v0.7.0 发布后**)——截图/动图才不过时 +2. **M1 结构骨架**:布局 + 导航 + 区块占位 + SEO/meta(1 天) +3. **M2 内容填充**:文案定稿 + 截图/动图就位(1-2 天) +4. **M3 打磨上线**:动效、响应式、GitHub Pages 部署、下载链接注入(1 天) +5. **M4 持续维护**:发版时更新版本号/截图(随 Release 流程) + +## 八、不做的事(当前阶段) + +- 不做多语言(先中文,英文版按需) +- 不做博客 / 文档站(README / docs 已有) +- 不做在线购买 / 支付(免费开源) +- 不采集统计埋点(与隐私定位一致) +- **不做私有库 Pages 镜像**(服务器未启用该功能) + +## 九、已定案(原 3 项待拍板) + +1. **素材时机** ✅ **用当前 v0.6.7**(用户确认,不等 v0.7.0) +2. **技术栈** ✅ **Vite + React + Tailwind**(与主应用技能栈一致) +3. **推荐链接** ✅ **页脚放 6 个供应商官网**(KimiSwitch 已全部内置): + + | # | 供应商 | 推荐文案 | 链接 | + |---|---|---|---| + | 1 | **Kimi** | 完成 Kimi 注册,你我都能 100% 拿奖,最高可得 1 年会员等值权益 | https://kimi-bot.com/activities/zh-cn/invite/share?scenario=invite&from=share_poster&invitation_code=6UJX7J | + | 2 | **智谱 GLM** | 我正在智谱大模型开放平台 BigModel.cn 上打造 AI 应用,智谱新一代旗舰模型 GLM-5.2 已上线,在推理、代码、智能体综合能力达到开源模型 SOTA 水平,通过我的邀请链接注册即可获得 2000 万 Tokens 大礼包,期待和你一起在 BigModel 上畅享卓越模型能力 | https://www.bigmodel.cn/invite?icode=mQwTVj1MeLnqI2wa7Ivg7unfet45IvM%2BqDogImfeLyI%3D | + | 3 | **DeepSeek** | (无推荐链接,官方平台) | https://platform.deepseek.com | + | 4 | **OpenCodeGo** | (无特定文案,官方推荐链接) | https://opencode.ai/go?ref=DFCNADQCEM | + | 5 | **MiniMax** | 🚀 MiniMax Token Plan 订阅一份套餐,解锁最新模型 — 前沿 Coding 能力、1M 超长上下文、原生多模态,图文音视频共用套餐额度。🎁 邀友双赢福利 好友订阅享 9 折 + Builder 权益,邀请人得 10% 返利 + 社区特权!立即订阅 | https://platform.minimaxi.com/subscribe/token-plan?code=GmmZA629b5&source=link | + | 6 | **基元律动** | (无特定文案,新供应商推荐链接) | https://tokenrhythm.studio/i/rf_tr_v0QXuBTzyl3-bJOS2uFFPg6x | + +> 方案 v4 定稿,可启动 M1(结构骨架 + SEO)。 diff --git a/docs/screenshots/site-2026-08-01/dashboard-daily-detail.png b/docs/screenshots/site-2026-08-01/dashboard-daily-detail.png new file mode 100644 index 0000000..4cdd922 Binary files /dev/null and b/docs/screenshots/site-2026-08-01/dashboard-daily-detail.png differ diff --git a/docs/screenshots/site-2026-08-01/dashboard-dark-full.png b/docs/screenshots/site-2026-08-01/dashboard-dark-full.png new file mode 100644 index 0000000..cc45476 Binary files /dev/null and b/docs/screenshots/site-2026-08-01/dashboard-dark-full.png differ diff --git a/docs/screenshots/site-2026-08-01/dashboard-dark.png b/docs/screenshots/site-2026-08-01/dashboard-dark.png new file mode 100644 index 0000000..d645c97 Binary files /dev/null and b/docs/screenshots/site-2026-08-01/dashboard-dark.png differ diff --git a/docs/screenshots/site-2026-08-01/dashboard-light.png b/docs/screenshots/site-2026-08-01/dashboard-light.png new file mode 100644 index 0000000..6cbe85a Binary files /dev/null and b/docs/screenshots/site-2026-08-01/dashboard-light.png differ diff --git a/docs/screenshots/site-2026-08-01/edit-provider-basic-managed.png b/docs/screenshots/site-2026-08-01/edit-provider-basic-managed.png new file mode 100644 index 0000000..dc939ae Binary files /dev/null and b/docs/screenshots/site-2026-08-01/edit-provider-basic-managed.png differ diff --git a/docs/screenshots/site-2026-08-01/edit-provider-json.png b/docs/screenshots/site-2026-08-01/edit-provider-json.png new file mode 100644 index 0000000..c5514ce Binary files /dev/null and b/docs/screenshots/site-2026-08-01/edit-provider-json.png differ diff --git a/docs/screenshots/site-2026-08-01/edit-provider-model-mapping.png b/docs/screenshots/site-2026-08-01/edit-provider-model-mapping.png new file mode 100644 index 0000000..6806742 Binary files /dev/null and b/docs/screenshots/site-2026-08-01/edit-provider-model-mapping.png differ diff --git a/docs/screenshots/site-2026-08-01/hero.png b/docs/screenshots/site-2026-08-01/hero.png new file mode 100644 index 0000000..82c996b Binary files /dev/null and b/docs/screenshots/site-2026-08-01/hero.png differ diff --git a/docs/screenshots/site-2026-08-01/kimi-cli-select-model.png b/docs/screenshots/site-2026-08-01/kimi-cli-select-model.png new file mode 100644 index 0000000..35f99cd Binary files /dev/null and b/docs/screenshots/site-2026-08-01/kimi-cli-select-model.png differ diff --git a/docs/screenshots/site-2026-08-01/kimi-oauth-dialog.png b/docs/screenshots/site-2026-08-01/kimi-oauth-dialog.png new file mode 100644 index 0000000..65fdd35 Binary files /dev/null and b/docs/screenshots/site-2026-08-01/kimi-oauth-dialog.png differ diff --git a/docs/screenshots/site-2026-08-01/kimi-oauth-success-webpage.png b/docs/screenshots/site-2026-08-01/kimi-oauth-success-webpage.png new file mode 100644 index 0000000..c28d7ee Binary files /dev/null and b/docs/screenshots/site-2026-08-01/kimi-oauth-success-webpage.png differ diff --git a/docs/screenshots/site-2026-08-01/kimi-plan-quota-card.png b/docs/screenshots/site-2026-08-01/kimi-plan-quota-card.png new file mode 100644 index 0000000..4e80326 Binary files /dev/null and b/docs/screenshots/site-2026-08-01/kimi-plan-quota-card.png differ diff --git a/docs/screenshots/site-2026-08-01/preset-picker.png b/docs/screenshots/site-2026-08-01/preset-picker.png new file mode 100644 index 0000000..89ee350 Binary files /dev/null and b/docs/screenshots/site-2026-08-01/preset-picker.png differ diff --git a/docs/screenshots/site-2026-08-01/sessions-dark.png b/docs/screenshots/site-2026-08-01/sessions-dark.png new file mode 100644 index 0000000..9df07bc Binary files /dev/null and b/docs/screenshots/site-2026-08-01/sessions-dark.png differ diff --git a/docs/screenshots/site-2026-08-01/sessions-light.png b/docs/screenshots/site-2026-08-01/sessions-light.png new file mode 100644 index 0000000..252ffca Binary files /dev/null and b/docs/screenshots/site-2026-08-01/sessions-light.png differ diff --git a/docs/screenshots/site-2026-08-01/settings.png b/docs/screenshots/site-2026-08-01/settings.png new file mode 100644 index 0000000..6573022 Binary files /dev/null and b/docs/screenshots/site-2026-08-01/settings.png differ diff --git a/docs/screenshots/site-2026-08-01/usage-config-page.png b/docs/screenshots/site-2026-08-01/usage-config-page.png new file mode 100644 index 0000000..5168943 Binary files /dev/null and b/docs/screenshots/site-2026-08-01/usage-config-page.png differ diff --git a/website/.gitignore b/website/.gitignore new file mode 100644 index 0000000..98de87d --- /dev/null +++ b/website/.gitignore @@ -0,0 +1,5 @@ +node_modules/ +dist/ +*.tsbuildinfo +vite.config.js +vite.config.d.ts diff --git a/website/README.md b/website/README.md new file mode 100644 index 0000000..a183f16 --- /dev/null +++ b/website/README.md @@ -0,0 +1,37 @@ +# KimiSwitch 官网(M1:结构骨架 + SEO) + +独立 Vite + React + Tailwind 工程,与主 Tauri 应用隔离。 + +## 开发 + +```bash +cd website +npm install +npm run dev # http://localhost:5173/KimiSwitch/ +``` + +## 构建 + +```bash +npm run build # tsc + vite build → dist/ +npm run preview # 本地预览生产产物 +``` + +## 部署 + +GitHub Pages(项目仓库 Pages):设置 → Pages → Source: `gh-pages` 分支 / root。 + +Vite `base` 已配置为 `/KimiSwitch/`(仓库子路径),构建产物可直接发布到 `gh-pages` 分支根目录。 + +```bash +# 推送 dist/ 到 gh-pages 分支(任选方式:gh-pages 包 / git subtree) +npx gh-pages -d dist +``` + +## 里程碑 + +- ✅ **M1**(当前):结构骨架 + SEO(meta、关键词、语义化) +- ⏭ **M2**:截图填充(替换 17 张归档素材占位) +- ⏭ **M3**:打磨动效 + 响应式 + GitHub Pages 部署 + OG 图合成 + +参考 `docs/WEBSITE-PLAN.md` v4。 \ No newline at end of file diff --git a/website/index.html b/website/index.html new file mode 100644 index 0000000..3780887 --- /dev/null +++ b/website/index.html @@ -0,0 +1,94 @@ + + + + + + + + + Kimi Switch — 多 LLM 供应商统一管理 · 用量监控 · 账单一目了然 + + + + + + + + + + + + + + + + + + + + + + + +
+ + + \ No newline at end of file diff --git a/website/package-lock.json b/website/package-lock.json new file mode 100644 index 0000000..06e9f0a --- /dev/null +++ b/website/package-lock.json @@ -0,0 +1,2832 @@ +{ + "name": "kimiswitch-website", + "version": "0.6.7", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "kimiswitch-website", + "version": "0.6.7", + "dependencies": { + "@fontsource/fira-code": "^5.3.0", + "@fontsource/inter": "^5.3.0", + "@phosphor-icons/react": "^2.1.10", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-router-dom": "^7.18.2" + }, + "devDependencies": { + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "@vitejs/plugin-react": "^4.3.1", + "autoprefixer": "^10.4.20", + "postcss": "^8.4.41", + "tailwindcss": "^3.4.10", + "typescript": "^5.5.4", + "vite": "^5.4.2" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz", + "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.8", + "@babel/types": "^7.29.8", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz", + "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.8" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz", + "integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz", + "integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz", + "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.8", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.8", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.8", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@fontsource/fira-code": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@fontsource/fira-code/-/fira-code-5.3.0.tgz", + "integrity": "sha512-EJL968RJRkakubAj/coU8pSUaeTE5UNoRjtzAr6kGiSZ3jWuN8/AKWHwym/PFUaQL1q7IL/H+EXs4358YhrTBQ==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, + "node_modules/@fontsource/inter": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-5.3.0.tgz", + "integrity": "sha512-RofMylZmjlJEfELXeNHFWBRcSs75rGU/6bV2S2jfnvv/3rPXPGe0LgUJTklcHZ9lM4OZmAVFhcJPnACfb91A3g==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/lzma-linux-x64-gnu": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz", + "integrity": "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@phosphor-icons/react": { + "version": "2.1.10", + "resolved": "https://registry.npmjs.org/@phosphor-icons/react/-/react-2.1.10.tgz", + "integrity": "sha512-vt8Tvq8GLjheAZZYa+YG/pW7HDbov8El/MANW8pOAz4eGxrwhnbfrQZq0Cp4q8zBEu8NIhHdnr+r8thnfRSNYA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">= 16.8", + "react-dom": ">= 16.8" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.27", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", + "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.4.tgz", + "integrity": "sha512-RrPokAb7dmbxFoeO3TloqHyOjgye8RkBhSqmp4aJMIex4c9r46ZstPnleDQOq1t46VOVjwIuwNogIqbodV1Vvg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.4.tgz", + "integrity": "sha512-JKuJc+pnpks2pjy7L/N3v/cAkZxYlnmuZoD840ldbMI5KDbC4iO9NKwPKYdjYFCMAIIlBzYSFHxIJVYzRo2/8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.4.tgz", + "integrity": "sha512-krw5uS2STmvJ02x0uTXHbqQNuz+9eZ1iw+qXk9dmW2gvV4jV7O2hEoOnuhFrpOPiel1mBFtqbxYZZtC46hXLOw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.4.tgz", + "integrity": "sha512-wsTxtgApb4PrOsNJIm0FZ1h3WvCC+k9uxLJ4ad75hgoS4NiRes2SoJFlDAyMwiUY8IssDqGcHbXuN0sx1tfF1A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.4.tgz", + "integrity": "sha512-GUOnQlyZe3yAXhWOtOMsn5Qkrv5E5mZXa0thbARWi5Ei2szlVXJFQhddZ4HbAzh8q92w5twp+CQvs/eFanz9YQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.4.tgz", + "integrity": "sha512-/Y7f3QuxjzPKsjA/rfEDa3+0vXqyjmJ50Ln8dPpCmWkKTrUoWHG1cWhTqaAMLob2m2nESWuC7yGrREz019Ztqg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.4.tgz", + "integrity": "sha512-81wiiX3v7aqy+T+bT61TJ78yJjRquqFFTTbAPt08imfQQzkPIW8t6aJbkTagtCCrXMNc9D66+geqlK7ydLPNqA==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.4.tgz", + "integrity": "sha512-9kmDIvNZqdoHOBZgNtpTBeLWYO/LVipM3H/j62P8848/l/VPEQL6N3uxU9pvP1oZAsXyC2MEnFP3ovRjo7WYNQ==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.4.tgz", + "integrity": "sha512-CcnXHWnXg69g+DX5VWL3FHts3qMRN2uVEHX+BZvGLdd07/gXkn3ePjYtO1LDJvxkGKVHMclKBRa1QUTH+6toYQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.4.tgz", + "integrity": "sha512-iFOibiHnTRuhrWLlRsOQFdZJJIa7S8OwkneJr4ocALP16u5yk6lWLINFwhHaEqBFMsKDUZofLkGos7+CPzGB3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.4.tgz", + "integrity": "sha512-XnWYMI7euHlb5a871xPja+Gm7DRCFU+FGRrtS2sMq9N8FvqtpagUy6gD4YOemC5MRk9xbh8+jYMEJbigFQwsgA==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.4.tgz", + "integrity": "sha512-qGDAlO0U8xedCcsdRm9oaoQY8DAx/QT7uIxJWhCdx0ceIWX783UC9QSYkdpzAe29wNiVfp24+bZdQmn49o45SQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.4.tgz", + "integrity": "sha512-ru4H6ezD7ysA5EiEK6qkkaEb4modH8CTej6kUy/gQi20u3kB3G7Zn8snXXkeJSCOFKG/rbPPtM/+9Wgas1961w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.4.tgz", + "integrity": "sha512-2W4MO5WQVJnbJaZdvDb9rhBDuFU1nKIepPFpJUBsTh2k1YY2g+ODViaWuyOAjQ5cOP7NvrvLzt3wvHOoiAvc7w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.4.tgz", + "integrity": "sha512-+fxjfuoAmVMCYV5QyjoIpu0cp5DOiOTeqYFk1AVaxGr+/ravWLX89XfQmptsoWcaVy/TGf2hexzbUOrCQIL1CQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.4.tgz", + "integrity": "sha512-jTn8JfHGL4djjFxPuM06LmNUJDsst2jeVlsd9OmIH6zc5sC9K6rIuO4YajXatLUpBmBKl6b35ro1QZocLi+tcA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.4.tgz", + "integrity": "sha512-oCJCJL4pXsoDcP2QZ+JVlPTIRc6266zsIaeJJsWImmF7HO0W8nb6HuSgZlMWxJwaPf8ehbSw8yo0EUw925hKsA==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.4.tgz", + "integrity": "sha512-W69hukhZ3KKNRCaMIEzKvcFye42hh0FE1+YoYaf5+Ikacuftoco6yO/xouz0hc5d5W/s3yBro5jRiuEE/Q5vUw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.4.tgz", + "integrity": "sha512-qiXbGG2jkjXhzXpsFZSR2Xpb8DN/UaxYsbb/STbuR/6fpaDgRmmaq1B/LmtF2wQFOFOSsK2jdE0RZ3a0zHn4QA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.4.tgz", + "integrity": "sha512-nWeM//hxv8mIo6jD7Hu4o48DVmV9pbV6gsKaWU+4NFyqHoPKwrkRiZGLKUhOBk8qNmDmpwFtPKg80Bo/Tn4xiQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.4.tgz", + "integrity": "sha512-s62SQ/vgsRSvMwDkOEfTqfgASF0f26ZNaQuTA6Aok5lrikf89yI2W0gFHvZb2Jpgc6N8JnOKZgCK2iciO3CsxQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.4.tgz", + "integrity": "sha512-J6wGf8TVGbXJq+HH+ttTvrcfNKPbuZecV6KT1B8I18BC5IURUh5kl4Yl5OEP5eFIUoI5BWxCsyYMhFsDx8kekw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.4.tgz", + "integrity": "sha512-zmfrQd/0wu6oJs8Vq8KwY/YtsKSsLtKe/HwAP4Wqy8LhWjeT55fHRAkOhYQ12wI3ayS4Tt12d5CDRD7N96SAYQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.4.tgz", + "integrity": "sha512-qPzHqdj9rfUD+w79dtE07zi/kFwKyCJqplp5K5ygeLTp7jLpAoc16OAH39HSmRC9UpozaecsleI8uAdEj6v2yw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.4.tgz", + "integrity": "sha512-zD6NdeWEByGE9QF9vCrlJ5YQB4oq9q91kPZS37Jwj5hOkvR1lTBSpsKhKDw4IJtbQ35LsTS1HD9DZYGKIshU1Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.31", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.31.tgz", + "integrity": "sha512-vfEqpXTvwT91yhmwdfouStN2hSKwTvyRs8qpLfADyrq/kxDw0hZM7Wk9Ug1FELj8hIby+S/+kQCSRFF32nv2Qw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", + "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.27", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true, + "license": "MIT" + }, + "node_modules/autoprefixer": { + "version": "10.5.4", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.4.tgz", + "integrity": "sha512-MaU0U/za7N3r6brxD4YB/l4NSrFzLPlANv6wEuQVaIPlD3L4W9rFcQPbL/EilY9BHhHvhfcz3gInDLrEtWT4EA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.6", + "caniuse-lite": "^1.0.30001806", + "fraction.js": "^5.3.4", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.11.9", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.9.tgz", + "integrity": "sha512-cp447VUsGS07+n1Dqf7YSQ8maeJrjEhaDxTm1ZefbqDtypHBC5GzGMQbklR6IPR13Y8OAJRHZWEMtZipJLCttg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.7.tgz", + "integrity": "sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.44", + "caniuse-lite": "^1.0.30001806", + "electron-to-chromium": "^1.5.393", + "node-releases": "^2.0.51", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001806", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz", + "integrity": "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.399", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.399.tgz", + "integrity": "sha512-lEcqhErbHjXRvd41rnWLpzbyU/IXfIYo7QwaFWmxGeLiLyY2TBCdHnWY88vB+p3ubnihRypDm66panXl7TylLA==", + "dev": true, + "license": "ISC" + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fraction.js": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", + "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.51", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz", + "integrity": "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss": { + "version": "8.5.25", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.25.tgz", + "integrity": "sha512-DTPx3RWSSnWyzLxQnlH0rJP+EW5ekl16ZU4/psbIhA0e53kJfdgaN5vKM+xP7yJtXVu+nfdVFmlgFDEKAe4Pyw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.16", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz", + "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz", + "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.1.1" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.4.tgz", + "integrity": "sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-router": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.18.2.tgz", + "integrity": "sha512-aUVMjFm3GAPTTZL7oYr5E7ETiqfQCHRLH+B+5afnICvf0r7kkK4eR6SMuwbSTJw/7t+12khT/Kahij49fqOCIg==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.18.2.tgz", + "integrity": "sha512-AIKJ/jgGlFb3EbfCXk5Gzshiwt+l3mqbCrNjmEWMMjqQxNJ3svBa6bgzFyCC2Sw3RA0VWF1kg3uQf2OFhxb8hw==", + "license": "MIT", + "dependencies": { + "react-router": "7.18.2" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.4.tgz", + "integrity": "sha512-RXOqwaPsBGjMNMa4sQjDjHieHEZDFoj/Rdr46l2MU5DfEs16wHJPC2RPTPHWhNl+M3aI472LLqFkFKut4SblOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@napi-rs/lzma-linux-x64-gnu": "1.5.1", + "@rollup/rollup-android-arm-eabi": "4.62.4", + "@rollup/rollup-android-arm64": "4.62.4", + "@rollup/rollup-darwin-arm64": "4.62.4", + "@rollup/rollup-darwin-x64": "4.62.4", + "@rollup/rollup-freebsd-arm64": "4.62.4", + "@rollup/rollup-freebsd-x64": "4.62.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.4", + "@rollup/rollup-linux-arm-musleabihf": "4.62.4", + "@rollup/rollup-linux-arm64-gnu": "4.62.4", + "@rollup/rollup-linux-arm64-musl": "4.62.4", + "@rollup/rollup-linux-loong64-gnu": "4.62.4", + "@rollup/rollup-linux-loong64-musl": "4.62.4", + "@rollup/rollup-linux-ppc64-gnu": "4.62.4", + "@rollup/rollup-linux-ppc64-musl": "4.62.4", + "@rollup/rollup-linux-riscv64-gnu": "4.62.4", + "@rollup/rollup-linux-riscv64-musl": "4.62.4", + "@rollup/rollup-linux-s390x-gnu": "4.62.4", + "@rollup/rollup-linux-x64-gnu": "4.62.4", + "@rollup/rollup-linux-x64-musl": "4.62.4", + "@rollup/rollup-openbsd-x64": "4.62.4", + "@rollup/rollup-openharmony-arm64": "4.62.4", + "@rollup/rollup-win32-arm64-msvc": "4.62.4", + "@rollup/rollup-win32-ia32-msvc": "4.62.4", + "@rollup/rollup-win32-x64-gnu": "4.62.4", + "@rollup/rollup-win32-x64-msvc": "4.62.4", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "license": "MIT" + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sucrase": { + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", + "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "tinyglobby": "^0.2.11", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.19.tgz", + "integrity": "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.7", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite": { + "version": "5.4.21", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", + "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + } + } +} diff --git a/website/package.json b/website/package.json new file mode 100644 index 0000000..92569c2 --- /dev/null +++ b/website/package.json @@ -0,0 +1,29 @@ +{ + "name": "kimiswitch-website", + "private": true, + "version": "0.6.7", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@fontsource/fira-code": "^5.3.0", + "@fontsource/inter": "^5.3.0", + "@phosphor-icons/react": "^2.1.10", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-router-dom": "^7.18.2" + }, + "devDependencies": { + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "@vitejs/plugin-react": "^4.3.1", + "autoprefixer": "^10.4.20", + "postcss": "^8.4.41", + "tailwindcss": "^3.4.10", + "typescript": "^5.5.4", + "vite": "^5.4.2" + } +} diff --git a/website/postcss.config.js b/website/postcss.config.js new file mode 100644 index 0000000..fbe14a4 --- /dev/null +++ b/website/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; \ No newline at end of file diff --git a/website/public/kimi.svg b/website/public/kimi.svg new file mode 100644 index 0000000..19f6884 --- /dev/null +++ b/website/public/kimi.svg @@ -0,0 +1,13 @@ + + + + + + + + + K + + + \ No newline at end of file diff --git a/website/public/logos/deepseek.svg b/website/public/logos/deepseek.svg new file mode 100644 index 0000000..3fc2302 --- /dev/null +++ b/website/public/logos/deepseek.svg @@ -0,0 +1 @@ +DeepSeek \ No newline at end of file diff --git a/website/public/logos/glm.svg b/website/public/logos/glm.svg new file mode 100644 index 0000000..f1b5845 --- /dev/null +++ b/website/public/logos/glm.svg @@ -0,0 +1 @@ + diff --git a/website/public/logos/kimi.svg b/website/public/logos/kimi.svg new file mode 100644 index 0000000..ec5db53 --- /dev/null +++ b/website/public/logos/kimi.svg @@ -0,0 +1 @@ +Kimi \ No newline at end of file diff --git a/website/public/logos/minimax.svg b/website/public/logos/minimax.svg new file mode 100644 index 0000000..2a60bd4 --- /dev/null +++ b/website/public/logos/minimax.svg @@ -0,0 +1 @@ +Minimax \ No newline at end of file diff --git a/website/public/logos/opencode.svg b/website/public/logos/opencode.svg new file mode 100644 index 0000000..804d177 --- /dev/null +++ b/website/public/logos/opencode.svg @@ -0,0 +1,4 @@ + + + + diff --git a/website/public/logos/tokenrhythm.svg b/website/public/logos/tokenrhythm.svg new file mode 100644 index 0000000..ba208d0 --- /dev/null +++ b/website/public/logos/tokenrhythm.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/website/public/logos/zhipu.svg b/website/public/logos/zhipu.svg new file mode 100644 index 0000000..0c6e61c --- /dev/null +++ b/website/public/logos/zhipu.svg @@ -0,0 +1 @@ +Zhipu \ No newline at end of file diff --git a/website/public/og.png b/website/public/og.png new file mode 100644 index 0000000..e561ada Binary files /dev/null and b/website/public/og.png differ diff --git a/website/public/robots.txt b/website/public/robots.txt new file mode 100644 index 0000000..278e730 --- /dev/null +++ b/website/public/robots.txt @@ -0,0 +1,4 @@ +User-agent: * +Allow: / + +Sitemap: https://billowliu2.github.io/KimiSwitch/sitemap.xml \ No newline at end of file diff --git a/website/public/screenshots/dashboard-daily-detail.png b/website/public/screenshots/dashboard-daily-detail.png new file mode 100644 index 0000000..4cdd922 Binary files /dev/null and b/website/public/screenshots/dashboard-daily-detail.png differ diff --git a/website/public/screenshots/dashboard-dark-full.png b/website/public/screenshots/dashboard-dark-full.png new file mode 100644 index 0000000..cc45476 Binary files /dev/null and b/website/public/screenshots/dashboard-dark-full.png differ diff --git a/website/public/screenshots/dashboard-dark.png b/website/public/screenshots/dashboard-dark.png new file mode 100644 index 0000000..d645c97 Binary files /dev/null and b/website/public/screenshots/dashboard-dark.png differ diff --git a/website/public/screenshots/dashboard-light.png b/website/public/screenshots/dashboard-light.png new file mode 100644 index 0000000..6cbe85a Binary files /dev/null and b/website/public/screenshots/dashboard-light.png differ diff --git a/website/public/screenshots/edit-provider-basic-managed.png b/website/public/screenshots/edit-provider-basic-managed.png new file mode 100644 index 0000000..dc939ae Binary files /dev/null and b/website/public/screenshots/edit-provider-basic-managed.png differ diff --git a/website/public/screenshots/edit-provider-json.png b/website/public/screenshots/edit-provider-json.png new file mode 100644 index 0000000..c5514ce Binary files /dev/null and b/website/public/screenshots/edit-provider-json.png differ diff --git a/website/public/screenshots/edit-provider-model-mapping.png b/website/public/screenshots/edit-provider-model-mapping.png new file mode 100644 index 0000000..6806742 Binary files /dev/null and b/website/public/screenshots/edit-provider-model-mapping.png differ diff --git a/website/public/screenshots/hero.png b/website/public/screenshots/hero.png new file mode 100644 index 0000000..82c996b Binary files /dev/null and b/website/public/screenshots/hero.png differ diff --git a/website/public/screenshots/kimi-cli-select-model.png b/website/public/screenshots/kimi-cli-select-model.png new file mode 100644 index 0000000..35f99cd Binary files /dev/null and b/website/public/screenshots/kimi-cli-select-model.png differ diff --git a/website/public/screenshots/kimi-oauth-dialog.png b/website/public/screenshots/kimi-oauth-dialog.png new file mode 100644 index 0000000..65fdd35 Binary files /dev/null and b/website/public/screenshots/kimi-oauth-dialog.png differ diff --git a/website/public/screenshots/kimi-oauth-success-webpage.png b/website/public/screenshots/kimi-oauth-success-webpage.png new file mode 100644 index 0000000..c28d7ee Binary files /dev/null and b/website/public/screenshots/kimi-oauth-success-webpage.png differ diff --git a/website/public/screenshots/kimi-plan-quota-card.png b/website/public/screenshots/kimi-plan-quota-card.png new file mode 100644 index 0000000..4e80326 Binary files /dev/null and b/website/public/screenshots/kimi-plan-quota-card.png differ diff --git a/website/public/screenshots/preset-picker.png b/website/public/screenshots/preset-picker.png new file mode 100644 index 0000000..89ee350 Binary files /dev/null and b/website/public/screenshots/preset-picker.png differ diff --git a/website/public/screenshots/sessions-dark.png b/website/public/screenshots/sessions-dark.png new file mode 100644 index 0000000..9df07bc Binary files /dev/null and b/website/public/screenshots/sessions-dark.png differ diff --git a/website/public/screenshots/sessions-light.png b/website/public/screenshots/sessions-light.png new file mode 100644 index 0000000..252ffca Binary files /dev/null and b/website/public/screenshots/sessions-light.png differ diff --git a/website/public/screenshots/settings.png b/website/public/screenshots/settings.png new file mode 100644 index 0000000..6573022 Binary files /dev/null and b/website/public/screenshots/settings.png differ diff --git a/website/public/screenshots/usage-config-page.png b/website/public/screenshots/usage-config-page.png new file mode 100644 index 0000000..5168943 Binary files /dev/null and b/website/public/screenshots/usage-config-page.png differ diff --git a/website/public/sitemap.xml b/website/public/sitemap.xml new file mode 100644 index 0000000..28e0e8d --- /dev/null +++ b/website/public/sitemap.xml @@ -0,0 +1,38 @@ + + + + https://billowliu2.github.io/KimiSwitch/ + weekly + 1.0 + + + https://billowliu2.github.io/KimiSwitch/#/features + monthly + 0.8 + + + https://billowliu2.github.io/KimiSwitch/#/showcase + monthly + 0.8 + + + https://billowliu2.github.io/KimiSwitch/#/performance + monthly + 0.7 + + + https://billowliu2.github.io/KimiSwitch/#/changelog + weekly + 0.7 + + + https://billowliu2.github.io/KimiSwitch/#/download + weekly + 0.9 + + + https://github.com/billowliu2/KimiSwitch + weekly + 0.8 + + diff --git a/website/src/App.tsx b/website/src/App.tsx new file mode 100644 index 0000000..52b988f --- /dev/null +++ b/website/src/App.tsx @@ -0,0 +1,52 @@ +import { useEffect } from "react"; +import { Route, Routes, useLocation } from "react-router-dom"; +import Nav from "./components/Nav"; +import Hero from "./sections/Hero"; +import Features from "./sections/Features"; +import Changelog from "./sections/Changelog"; +import Download from "./sections/Download"; +import Privacy from "./sections/Privacy"; +import CTA from "./sections/CTA"; +import Footer from "./components/Footer"; + +function ScrollToTop() { + const { pathname } = useLocation(); + useEffect(() => { + window.scrollTo(0, 0); + }, [pathname]); + return null; +} + +const homePage = ( + <> + + + +); + +export default function App() { + return ( +
+
+ ); +} diff --git a/website/src/components/Footer.tsx b/website/src/components/Footer.tsx new file mode 100644 index 0000000..20c70a8 --- /dev/null +++ b/website/src/components/Footer.tsx @@ -0,0 +1,105 @@ +import { recommendLinks } from "../data/recommendLinks"; +import { useLang } from "../i18n"; +import { asset } from "../lib/asset"; + +/** Map recommendLink.name → logo file in public/logos (only when we have one). */ +const logoFor: Record = { + "Kimi": "logos/kimi.svg", + "智谱 GLM": "logos/glm.svg", + "DeepSeek": "logos/deepseek.svg", + "OpenCodeGo": "logos/opencode.svg", + "MiniMax": "logos/minimax.svg", + "基元律动": "logos/tokenrhythm.svg", +}; + +export default function Footer() { + const { t } = useLang(); + return ( + + ); +} diff --git a/website/src/components/Nav.tsx b/website/src/components/Nav.tsx new file mode 100644 index 0000000..37b874b --- /dev/null +++ b/website/src/components/Nav.tsx @@ -0,0 +1,68 @@ +import { NavLink } from "react-router-dom"; +import { useLang } from "../i18n"; +import { asset } from "../lib/asset"; + +export default function Nav() { + const { lang, setLang, t } = useLang(); + const links = [ + { to: "/", label: t.nav.home, end: true }, + { to: "/features", label: t.nav.features }, + { to: "/changelog", label: t.nav.changelog }, + { to: "/download", label: t.nav.download }, + ]; + return ( +
+
+ + Kimi Switch logo + Kimi Switch + + +
+ + + {t.nav.downloadBtn} + +
+
+
+ ); +} diff --git a/website/src/components/SectionShell.tsx b/website/src/components/SectionShell.tsx new file mode 100644 index 0000000..20487c7 --- /dev/null +++ b/website/src/components/SectionShell.tsx @@ -0,0 +1,40 @@ +import { useInView } from "../hooks"; +import type { ReactNode } from "react"; + +interface SectionShellProps { + id: string; + title: string; + subtitle?: string; + children: ReactNode; +} + +export default function SectionShell({ id, title, subtitle, children }: SectionShellProps) { + const [ref, inView] = useInView(); + return ( +
+
+
+

+ {title} +

+ {subtitle && ( +

{subtitle}

+ )} +
+ {children} +
+
+ ); +} diff --git a/website/src/data/recommendLinks.ts b/website/src/data/recommendLinks.ts new file mode 100644 index 0000000..b45b13d --- /dev/null +++ b/website/src/data/recommendLinks.ts @@ -0,0 +1,31 @@ +export interface RecommendLink { + name: string; + url: string; +} + +export const recommendLinks: RecommendLink[] = [ + { + name: "Kimi", + url: "https://kimi-bot.com/activities/zh-cn/invite/share?scenario=invite&from=share_poster&invitation_code=6UJX7J", + }, + { + name: "智谱 GLM", + url: "https://www.bigmodel.cn/invite?icode=s2o6ZfY5VjEPIJj05K%2BhW2czbXFgPRGIalpycrEwJ28%3D", + }, + { + name: "DeepSeek", + url: "https://platform.deepseek.com", + }, + { + name: "OpenCodeGo", + url: "https://opencode.ai/go?ref=DFCNADQCEM", + }, + { + name: "MiniMax", + url: "https://platform.minimaxi.com/subscribe/token-plan?code=GmmZA629b5&source=link", + }, + { + name: "基元律动", + url: "https://tokenrhythm.studio/i/rf_tr_v0QXuBTzyl3-bJOS2uFFPg6x", + }, +]; diff --git a/website/src/hooks.ts b/website/src/hooks.ts new file mode 100644 index 0000000..899b4e3 --- /dev/null +++ b/website/src/hooks.ts @@ -0,0 +1,44 @@ +import { useEffect, useRef, useState } from "react"; + +/** Fires once when the element scrolls into view. */ +export function useInView( + options: IntersectionObserverInit = { threshold: 0.15 }, +) { + const ref = useRef(null); + const [inView, setInView] = useState(false); + + useEffect(() => { + const node = ref.current; + if (!node || inView) return; + const io = new IntersectionObserver(([entry]) => { + if (entry.isIntersecting) { + setInView(true); + io.disconnect(); + } + }, options); + io.observe(node); + return () => io.disconnect(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [inView]); + + return [ref, inView] as const; +} + +/** Animates a numeric value once `trigger` flips to true. */ +export function useCountUp(target: number, trigger: boolean, durationMs = 900) { + const [value, setValue] = useState(0); + useEffect(() => { + if (!trigger) return; + const start = performance.now(); + const easeOut = (t: number) => 1 - Math.pow(1 - t, 3); + let raf = 0; + const tick = (now: number) => { + const p = Math.min(1, (now - start) / durationMs); + setValue(target * easeOut(p)); + if (p < 1) raf = requestAnimationFrame(tick); + }; + raf = requestAnimationFrame(tick); + return () => cancelAnimationFrame(raf); + }, [target, trigger, durationMs]); + return value; +} diff --git a/website/src/i18n.tsx b/website/src/i18n.tsx new file mode 100644 index 0000000..e61029f --- /dev/null +++ b/website/src/i18n.tsx @@ -0,0 +1,575 @@ +import { + createContext, + useContext, + useEffect, + useState, + type ReactNode, +} from "react"; + +export type Lang = "zh" | "en"; + +const zh = { + nav: { + home: "首页", + features: "功能", + showcase: "演示", + performance: "性能", + changelog: "更新日志", + download: "下载", + downloadBtn: "下载 v0.6.7", + }, + hero: { + badge: "开源 MIT · Windows 10 / 11", + titleBefore: "统一管理你的", + titleAccent: "AI 供应商", + titleAfter: "", + subtitle: + "一键切换 Kimi / 智谱 GLM / MiniMax / DeepSeek / OpenRouter / 基元律动,用量与账单一目了然。", + download: "免费下载", + source: "查看源码", + stats: [ + { value: "22", label: "预设供应商" }, + { value: "5910", label: "模型价格库" }, + { value: "100%", label: "开源免费" }, + ], + }, + features: { + title: "核心功能", + subtitle: "从多供应商管理到用量监控,一站搞定。", + items: [ + { + id: "multi-provider", + title: "多供应商管理", + desc: "Kimi / 智谱 GLM / MiniMax / DeepSeek / OpenRouter / 基元律动等 22 个预设,一键添加与切换。", + img: "screenshots/preset-picker.png", + }, + { + id: "custom-provider", + title: "自定义供应商", + desc: "自定义 Base URL / API Key / 模型映射,支持 JSON 高级编辑。", + img: "screenshots/edit-provider-basic-managed.png", + }, + { + id: "usage", + title: "用量与账单监控", + desc: "套餐类 5 小时 / 每周用量 + 按量余额,models.dev 真实价格计算成本,卡片直显。", + img: "screenshots/dashboard-light.png", + }, + { + id: "sessions", + title: "会话管理", + desc: "跨供应商浏览、搜索与恢复历史会话。", + img: "screenshots/sessions-light.png", + }, + { + id: "kimi-auth", + title: "Kimi 一键授权登录", + desc: "应用内置设备码授权(等同 kimi login),浏览器授权即用,15 分钟过期自动续期。", + img: "screenshots/kimi-oauth-dialog.png", + }, + { + id: "usage-config", + title: "配置用量查询", + desc: "全屏配置页:NewAPI 中转站模板、超时时间、自动刷新间隔、测试查询。", + img: "screenshots/usage-config-page.png", + }, + { + id: "model-discovery", + title: "智能模型发现", + desc: "模型能力 / 上下文大小自动从 models.dev 同步,构建时自动拉取,5910 模型覆盖。", + img: "screenshots/kimi-cli-select-model.png", + }, + { + id: "auto-update", + title: "自动更新", + desc: "自动检测新版本,一键下载安装,始终保持最新。", + img: "screenshots/settings.png", + }, + ], + }, + showcase: { + title: "界面演示", + subtitle: "真实界面截图,所见即所得。", + items: [ + { + src: "screenshots/usage-config-page.png", + title: "配置用量查询", + desc: "NewAPI 中转站模板、超时与自动刷新、测试查询一屏搞定", + }, + { + src: "screenshots/preset-picker.png", + title: "预设供应商", + desc: "22 个预设开箱即用,一键添加常用厂商", + }, + { + src: "screenshots/kimi-oauth-dialog.png", + title: "Kimi 授权登录", + desc: "设备码授权等同 kimi login,过期自动续期", + }, + { + src: "screenshots/dashboard-daily-detail.png", + title: "用量明细", + desc: "按天查看 Token 与费用走势", + }, + { + src: "screenshots/sessions-light.png", + title: "会话管理", + desc: "跨供应商浏览与恢复历史会话", + }, + { + src: "screenshots/kimi-plan-quota-card.png", + title: "套餐余量卡", + desc: "5 小时 / 每周额度直读,余量一眼可见", + }, + ], + }, + performance: { + title: "轻量原生", + subtitle: "Tauri + Rust 内核,WebView2 前端,常驻托盘零负担。", + metrics: [ + { target: 93, suffix: " MB", label: "Working Set", desc: "程序空闲态工作集内存" }, + { target: 34, suffix: " MB", label: "Private WS", desc: "独占内存(WebView2 共享部分扣除)" }, + { target: 0.3, decimals: 1, suffix: "%", label: "CPU 空闲", desc: "无活跃任务时几乎零占用" }, + ], + lightCaption: "浅色主题", + darkCaption: "深色主题", + }, + changelog: { + title: "更新日志", + subtitle: "每个版本的重要变更记录。", + syncedNote: "数据已同步 GitHub Releases", + fallbackNote: "内置版本记录", + entries: [ + { + version: "v0.6.7", + date: "2026-08-01", + items: [ + "应用内置 Kimi 设备授权登录(等同 kimi login),浏览器授权即用,过期自动续期", + "外链打开统一走 Rust 命令,修复部分链接无法跳转", + ], + }, + { + version: "v0.6.6", + date: "2026-08-01", + items: [ + "模型价格对标 models.dev,覆盖 5910 个模型", + "新增基元律动供应商与推荐链接", + "设置页文案与参考来源说明优化", + ], + }, + { + version: "v0.6.5", + date: "2026-08-01", + items: [ + "更新检查优化:私有仓库优先,GitHub 回退,8 秒超时", + "修复按量余额显示", + ], + }, + { + version: "v0.6.4", + date: "2026-08-01", + items: [ + "新增套餐账单查询(5 小时 / 每周用量卡片直显)", + "OpenCode Zen 预设补充推荐链接", + ], + }, + { + version: "v0.6.3", + date: "2026-07-30", + items: [ + "添加默认供应商支持,新增 StepFun Plan 套餐预设", + "供应商编辑页新增 API Key 获取链接(支持推广链接)", + "修复链接无法打开浏览器的问题", + ], + }, + { + version: "v0.6.2", + date: "2026-07-30", + items: [ + "仪表盘布局重构:每日用量趋势折线图(Token / 缓存命中率 / 请求数)", + "热力图独立整行,格子放大", + "新增 OpenCode Go / Zen 预设", + ], + }, + { + version: "v0.6.0", + date: "2026-07-29", + items: [ + "预设供应商与供应商账单查询上线", + "多平台打包:macOS / Linux / Windows CI 同步发布", + ], + }, + { + version: "v0.5.2", + date: "2026-07-29", + items: ["用量趋势改为 tab 容器,新增供应商模型两级下钻"], + }, + { + version: "v0.5.1", + date: "2026-07-29", + items: ["窗口与托盘行为优化;模型表格与能力编辑 UI 打磨"], + }, + ], + }, + privacy: { + title: "你的数据,只在你的电脑上", + subtitle: "三句话讲清楚隐私与开源承诺。", + items: [ + { + id: "local", + title: "本地存储", + desc: "配置与用量仅存本机 ~/.kimi-switch 与 config.toml,绝不上传。", + }, + { + id: "direct", + title: "官方直连", + desc: "账单查询直连各厂商官方 API,无中间商、无统计埋点。", + }, + { + id: "open", + title: "开源可审计", + desc: "MIT 协议全量开源(GitHub),欢迎审阅与共建。", + }, + ], + }, + download: { + title: "下载 Kimi Switch", + subtitle: "当前版本 v0.6.7 · Windows 10 / 11 主推,macOS 与 Linux 路线图上。", + autoUpdate: "应用内置自动检测更新,新版本发布后在设置页一键升级。", + ready: "已发布", + wip: "开发中", + githubBtn: "GitHub 下载", + mirrorBtn: "镜像下载", + items: [ + { id: "windows", name: "Windows", ready: true, note: ".msi 与 .exe 安装包,系统托盘常驻" }, + { id: "macos", name: "macOS", ready: false, note: "GitHub Actions 已能构建 .dmg,待官方适配" }, + { id: "linux", name: "Linux", ready: false, note: ".AppImage / .deb / .rpm 构建中" }, + ], + }, + cta: { + title: "现在就把所有供应商,放进一个应用", + subtitle: "免费 · 开源 MIT · 一分钟完成安装", + download: "免费下载", + source: "GitHub 源码", + }, + footer: { + recommend: "推荐供应商", + mirror: "国内镜像", + creditBefore: "仪表盘与会话管理功能基于 ", + creditAfter: " (MIT, © JochenYang) 移植", + recommendText: { + Kimi: "完成 Kimi 注册,你我都能 100% 拿奖,最高可得 1 年会员等值权益", + "智谱 GLM": + "通过我的邀请链接注册 BigModel.cn,即可获得 2000 万 Tokens 大礼包,畅享新一代旗舰模型 GLM-5.2", + DeepSeek: "", + OpenCodeGo: "", + MiniMax: + "MiniMax Token Plan:订阅套餐解锁最新模型,好友订阅享 9 折 + Builder 权益,邀请人得 10% 返利", + 基元律动: "", + } as Record, + }, +}; + +export type Dict = typeof zh; + +const en: Dict = { + nav: { + home: "Home", + features: "Features", + showcase: "Demo", + performance: "Performance", + changelog: "Changelog", + download: "Download", + downloadBtn: "Download v0.6.7", + }, + hero: { + badge: "Open source MIT · Windows 10 / 11", + titleBefore: "One app for all your ", + titleAccent: "AI providers", + titleAfter: "", + subtitle: + "Switch between Kimi, Zhipu GLM, MiniMax, DeepSeek, OpenRouter and TokenRhythm in one click, with usage and billing at a glance.", + download: "Free Download", + source: "View Source", + stats: [ + { value: "22", label: "Provider presets" }, + { value: "5910", label: "Model price DB" }, + { value: "100%", label: "Open source" }, + ], + }, + features: { + title: "Core Features", + subtitle: "From multi-provider management to usage monitoring, all in one place.", + items: [ + { + id: "multi-provider", + title: "Multi-Provider Management", + desc: "22 presets including Kimi, Zhipu GLM, MiniMax, DeepSeek, OpenRouter and TokenRhythm. Add and switch in one click.", + img: "screenshots/preset-picker.png", + }, + { + id: "custom-provider", + title: "Custom Providers", + desc: "Custom Base URL, API Key and model mapping, with advanced JSON editing.", + img: "screenshots/edit-provider-basic-managed.png", + }, + { + id: "usage", + title: "Usage & Billing", + desc: "5-hour / weekly plan quotas plus pay-as-you-go balance, priced with real models.dev rates and shown on cards.", + img: "screenshots/dashboard-light.png", + }, + { + id: "sessions", + title: "Session Manager", + desc: "Browse, search and resume past sessions across providers.", + img: "screenshots/sessions-light.png", + }, + { + id: "kimi-auth", + title: "One-Click Kimi Login", + desc: "Built-in device-code authorization (same as kimi login). Authorize in the browser; 15-minute expiry auto-renews.", + img: "screenshots/kimi-oauth-dialog.png", + }, + { + id: "usage-config", + title: "Usage Query Setup", + desc: "Full-page config: NewAPI relay templates, timeout, auto-refresh interval, and a test query.", + img: "screenshots/usage-config-page.png", + }, + { + id: "model-discovery", + title: "Smart Model Discovery", + desc: "Model capabilities and context sizes sync from models.dev at build time, covering 5910 models.", + img: "screenshots/kimi-cli-select-model.png", + }, + { + id: "auto-update", + title: "Auto Updates", + desc: "Automatically detects new versions and installs them in one click.", + img: "screenshots/settings.png", + }, + ], + }, + showcase: { + title: "Screenshots", + subtitle: "Real screenshots from the app. What you see is what you get.", + items: [ + { + src: "screenshots/usage-config-page.png", + title: "Usage Query Setup", + desc: "NewAPI relay templates, timeout and auto-refresh, plus a test query, all on one page", + }, + { + src: "screenshots/preset-picker.png", + title: "Provider Presets", + desc: "22 presets ready out of the box, add popular vendors in one click", + }, + { + src: "screenshots/kimi-oauth-dialog.png", + title: "Kimi Authorization", + desc: "Device-code flow identical to kimi login, auto-renews on expiry", + }, + { + src: "screenshots/dashboard-daily-detail.png", + title: "Usage Details", + desc: "Daily token and cost trends", + }, + { + src: "screenshots/sessions-light.png", + title: "Session Manager", + desc: "Browse and resume past sessions across providers", + }, + { + src: "screenshots/kimi-plan-quota-card.png", + title: "Plan Quota Card", + desc: "5-hour / weekly quotas at a glance", + }, + ], + }, + performance: { + title: "Lightweight & Native", + subtitle: "Tauri + Rust core with a WebView2 frontend. Zero tray overhead.", + metrics: [ + { target: 93, suffix: " MB", label: "Working Set", desc: "Idle working-set memory" }, + { target: 34, suffix: " MB", label: "Private WS", desc: "Private memory (shared WebView2 excluded)" }, + { target: 0.3, decimals: 1, suffix: "%", label: "Idle CPU", desc: "Nearly zero when idle" }, + ], + lightCaption: "Light theme", + darkCaption: "Dark theme", + }, + changelog: { + title: "Changelog", + subtitle: "Notable changes in every release.", + syncedNote: "Synced from GitHub Releases", + fallbackNote: "Built-in release notes", + entries: [ + { + version: "v0.6.7", + date: "2026-08-01", + items: [ + "Built-in Kimi device-code login (same as kimi login): authorize in the browser, auto-renews on expiry", + "External links now open via a unified Rust command, fixing broken jumps", + ], + }, + { + version: "v0.6.6", + date: "2026-08-01", + items: [ + "Model pricing aligned with models.dev, covering 5910 models", + "New TokenRhythm provider with referral link", + "Settings copy and source attribution polish", + ], + }, + { + version: "v0.6.5", + date: "2026-08-01", + items: [ + "Update check rework: private mirror first, GitHub fallback, 8s timeout", + "Fix pay-as-you-go balance display", + ], + }, + { + version: "v0.6.4", + date: "2026-08-01", + items: [ + "Plan billing queries (5-hour / weekly usage shown on cards)", + "OpenCode Zen preset gains a referral link", + ], + }, + { + version: "v0.6.3", + date: "2026-07-30", + items: [ + "Default provider support and a new StepFun Plan preset", + "API Key helper links on the provider edit page (referral links supported)", + "Fix links failing to open the browser", + ], + }, + { + version: "v0.6.2", + date: "2026-07-30", + items: [ + "Dashboard layout rework: daily trend line chart (tokens / cache hit rate / requests)", + "Heatmap gets its own full-width row with larger cells", + "New OpenCode Go / Zen presets", + ], + }, + { + version: "v0.6.0", + date: "2026-07-29", + items: [ + "Provider presets and per-provider billing queries launch", + "Multi-platform packaging: macOS / Linux / Windows CI releases", + ], + }, + { + version: "v0.5.2", + date: "2026-07-29", + items: ["Usage trends moved into a tab container with provider-model two-level drill-down"], + }, + { + version: "v0.5.1", + date: "2026-07-29", + items: ["Window and tray behavior polish; model table and capability editor UI refinements"], + }, + ], + }, + privacy: { + title: "Your Data Stays on Your Machine", + subtitle: "Our privacy and open-source commitments in three sentences.", + items: [ + { + id: "local", + title: "Local Storage", + desc: "Configs and usage data live only in ~/.kimi-switch and config.toml. Nothing is uploaded.", + }, + { + id: "direct", + title: "Direct Connections", + desc: "Billing queries go straight to each vendor's official API. No middlemen, no tracking.", + }, + { + id: "open", + title: "Open & Auditable", + desc: "Fully open source under MIT on GitHub. Reviews and contributions welcome.", + }, + ], + }, + download: { + title: "Download Kimi Switch", + subtitle: "Current version v0.6.7 · Windows 10 / 11 first, macOS and Linux on the roadmap.", + autoUpdate: "Built-in update detection: upgrade in one click from Settings when a new version ships.", + ready: "Available", + wip: "In development", + githubBtn: "Download from GitHub", + mirrorBtn: "China mirror", + items: [ + { id: "windows", name: "Windows", ready: true, note: ".msi and .exe installers, lives in the system tray" }, + { id: "macos", name: "macOS", ready: false, note: "GitHub Actions already builds .dmg, official support pending" }, + { id: "linux", name: "Linux", ready: false, note: ".AppImage / .deb / .rpm builds in progress" }, + ], + }, + cta: { + title: "Bring every provider into one app", + subtitle: "Free · Open source MIT · One-minute install", + download: "Free Download", + source: "GitHub Source", + }, + footer: { + recommend: "Recommended Providers", + mirror: "China mirror", + creditBefore: "Dashboard & session management adapted from ", + creditAfter: " (MIT, © JochenYang)", + recommendText: { + Kimi: "Sign up with my invite link and we both win rewards, up to a 1-year membership equivalent", + "智谱 GLM": + "Register on BigModel.cn via my invite link and get a 20M token gift pack for the new GLM-5.2 flagship", + DeepSeek: "", + OpenCodeGo: "", + MiniMax: + "MiniMax Token Plan: subscribe to unlock the latest models. Friends get 10% off, inviters get 10% rebate", + 基元律动: "", + } as Record, + }, +}; + +const dicts: Record = { zh, en }; + +const STORAGE_KEY = "kimi-switch-site-lang"; + +function detect(): Lang { + if (typeof window === "undefined") return "zh"; + const saved = localStorage.getItem(STORAGE_KEY); + if (saved === "zh" || saved === "en") return saved; + return navigator.language.toLowerCase().startsWith("zh") ? "zh" : "en"; +} + +const LangContext = createContext<{ + lang: Lang; + setLang: (l: Lang) => void; + t: Dict; +}>({ lang: "zh", setLang: () => {}, t: zh }); + +export function LangProvider({ children }: { children: ReactNode }) { + const [lang, setLangState] = useState(detect); + + const setLang = (l: Lang) => { + setLangState(l); + localStorage.setItem(STORAGE_KEY, l); + }; + + useEffect(() => { + document.documentElement.lang = lang === "zh" ? "zh-CN" : "en"; + }, [lang]); + + return ( + + {children} + + ); +} + +export function useLang() { + return useContext(LangContext); +} diff --git a/website/src/index.css b/website/src/index.css new file mode 100644 index 0000000..df31cc6 --- /dev/null +++ b/website/src/index.css @@ -0,0 +1,101 @@ +@import "@fontsource/inter/400.css"; +@import "@fontsource/inter/500.css"; +@import "@fontsource/inter/600.css"; +@import "@fontsource/inter/700.css"; +@import "@fontsource/inter/800.css"; +@import "@fontsource/fira-code/400.css"; +@import "@fontsource/fira-code/500.css"; + +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* Design tokens — Kimi brand: neutral gray + blue accent (matches the app UI). + Light is the default; dark follows prefers-color-scheme. */ +@layer base { + :root { + --background: 240 11% 97%; + --foreground: 240 9% 11%; + --card: 0 0% 100%; + --card-foreground: 240 9% 11%; + --muted: 240 6% 94%; + --muted-foreground: 220 9% 46%; + --accent: 240 6% 94%; + --accent-foreground: 240 9% 11%; + --border: 240 6% 90%; + --primary: 221 83% 53%; + --primary-foreground: 0 0% 100%; + --ring: 221 83% 53%; + } + + @media (prefers-color-scheme: dark) { + :root { + --background: 222 47% 6%; + --foreground: 220 20% 92%; + --card: 222 32% 10%; + --card-foreground: 220 20% 92%; + --muted: 222 25% 14%; + --muted-foreground: 220 12% 62%; + --accent: 222 25% 14%; + --accent-foreground: 220 20% 92%; + --border: 222 22% 17%; + --primary: 217 91% 60%; + --primary-foreground: 0 0% 100%; + --ring: 217 91% 60%; + } + } + + html { + scroll-behavior: smooth; + } + body { + @apply bg-background text-foreground antialiased; + } + /* 科技风底纹:固定网格线,极低透明度,不干扰阅读 */ + body::before { + content: ""; + position: fixed; + inset: 0; + z-index: 0; + pointer-events: none; + background-image: + linear-gradient(to right, hsl(var(--primary) / 0.05) 1px, transparent 1px), + linear-gradient(to bottom, hsl(var(--primary) / 0.05) 1px, transparent 1px); + background-size: 44px 44px; + mask-image: radial-gradient(ellipse 80% 60% at 50% 0%, black 30%, transparent 75%); + } + #root { + position: relative; + z-index: 1; + } +} + +@layer components { + .container-page { + @apply mx-auto w-full max-w-6xl px-6; + } + .btn { + @apply inline-flex items-center justify-center gap-2 rounded-xl px-5 py-2.5 text-sm font-medium transition-colors; + } + .btn-primary { + @apply btn bg-primary text-primary-foreground hover:opacity-90; + box-shadow: 0 0 20px hsl(var(--primary) / 0.35); + } + .btn-ghost { + @apply btn border border-border text-foreground hover:bg-accent; + } + .card { + @apply rounded-xl border border-border bg-card p-6 transition-shadow; + } + .card:hover { + box-shadow: 0 0 28px hsl(var(--primary) / 0.12); + } + /* 截图容器:限定最大宽高,避免撑满页面 */ + .screenshot { + @apply overflow-hidden rounded-xl border border-border bg-muted; + box-shadow: 0 0 36px hsl(var(--primary) / 0.1); + } + .screenshot > img { + @apply block h-auto w-full; + } +} diff --git a/website/src/lib/asset.ts b/website/src/lib/asset.ts new file mode 100644 index 0000000..90b9746 --- /dev/null +++ b/website/src/lib/asset.ts @@ -0,0 +1,7 @@ +/** + * Resolve a public-asset path against Vite's base URL. + * All site assets live under `/KimiSwitch/` in dev and on GitHub Pages, + * so bare absolute paths like `/logos/x.svg` would 404 — always go through here. + */ +export const asset = (p: string) => + `${import.meta.env.BASE_URL}${p.replace(/^\/+/, "")}`; diff --git a/website/src/main.tsx b/website/src/main.tsx new file mode 100644 index 0000000..bae3d87 --- /dev/null +++ b/website/src/main.tsx @@ -0,0 +1,16 @@ +import { StrictMode } from "react"; +import { createRoot } from "react-dom/client"; +import { HashRouter } from "react-router-dom"; +import { LangProvider } from "./i18n"; +import App from "./App"; +import "./index.css"; + +createRoot(document.getElementById("root")!).render( + + + + + + + , +); diff --git a/website/src/sections/CTA.tsx b/website/src/sections/CTA.tsx new file mode 100644 index 0000000..babe393 --- /dev/null +++ b/website/src/sections/CTA.tsx @@ -0,0 +1,47 @@ +import { Link } from "react-router-dom"; +import { useLang } from "../i18n"; + +export default function CTA() { + const { t } = useLang(); + return ( +
+
+
+ {/* 科技风光晕 */} + +
+
+ ); +} diff --git a/website/src/sections/Changelog.tsx b/website/src/sections/Changelog.tsx new file mode 100644 index 0000000..e1960f6 --- /dev/null +++ b/website/src/sections/Changelog.tsx @@ -0,0 +1,144 @@ +import { useEffect, useState } from "react"; +import SectionShell from "../components/SectionShell"; +import { useLang } from "../i18n"; + +interface ChangelogEntry { + version: string; + date: string; + items: string[]; +} + +const API_URL = + "https://api.github.com/repos/billowliu2/KimiSwitch/releases?per_page=20"; +const CACHE_KEY = "kimi-switch-changelog"; +const CACHE_TTL = 60 * 60 * 1000; // 1 hour + +/** Parse a GitHub release body into bullet items. */ +function parseBody(body: string): string[] { + return body + .split("\n") + .map((l) => l.replace(/^\s*[-*]\s+/, "").trim()) + .filter((l) => l.length > 0 && l !== "---"); +} + +async function fetchReleases(): Promise { + const res = await fetch(API_URL); + if (!res.ok) throw new Error(`GitHub API ${res.status}`); + const list = (await res.json()) as Array<{ + tag_name: string; + published_at: string | null; + body: string | null; + }>; + return list.map((r) => ({ + version: r.tag_name, + date: (r.published_at ?? "").slice(0, 10), + items: parseBody(r.body ?? ""), + })); +} + +function readCache(): ChangelogEntry[] | null { + try { + const raw = localStorage.getItem(CACHE_KEY); + if (!raw) return null; + const { ts, data } = JSON.parse(raw) as { ts: number; data: ChangelogEntry[] }; + if (Date.now() - ts > CACHE_TTL) return null; + return data; + } catch { + return null; + } +} + +function writeCache(data: ChangelogEntry[]) { + try { + localStorage.setItem( + CACHE_KEY, + JSON.stringify({ ts: Date.now(), data }), + ); + } catch { + /* ignore quota/private-mode errors */ + } +} + +export default function Changelog() { + const { t } = useLang(); + const embedded = t.changelog.entries as ChangelogEntry[]; + const [remote, setRemote] = useState(null); + const [synced, setSynced] = useState(false); + + useEffect(() => { + let cancelled = false; + const cached = readCache(); + if (cached) { + setRemote(cached); + setSynced(true); + return; + } + fetchReleases() + .then((data) => { + if (cancelled) return; + setRemote(data); + setSynced(true); + writeCache(data); + }) + .catch(() => { + /* 网络不通时使用内置列表兜底 */ + }); + return () => { + cancelled = true; + }; + }, []); + + // 远端拉到的版本优先显示(含未翻译的新版本),内置列表补齐缺失版本。 + const entries: ChangelogEntry[] = [ + ...(remote ?? []).filter( + (r) => !embedded.some((e) => e.version === r.version), + ), + ...embedded, + ]; + + return ( + +
    + {entries.map((e) => ( +
  1. + +
    +

    {e.version}

    + +
    + {e.items.length > 0 && ( +
      + {e.items.map((item) => ( +
    • {item}
    • + ))} +
    + )} +
  2. + ))} +
+

+ + {synced ? t.changelog.syncedNote : t.changelog.fallbackNote} + + {" · "} + + {t.footer.mirror} + +

+
+ ); +} diff --git a/website/src/sections/Download.tsx b/website/src/sections/Download.tsx new file mode 100644 index 0000000..820faae --- /dev/null +++ b/website/src/sections/Download.tsx @@ -0,0 +1,74 @@ +import SectionShell from "../components/SectionShell"; +import { WindowsLogo, AppleLogo, LinuxLogo, DownloadSimple, type Icon } from "@phosphor-icons/react"; +import { useLang } from "../i18n"; + +const icons: Record = { + windows: WindowsLogo, + macos: AppleLogo, + linux: LinuxLogo, +}; + +const GITHUB_RELEASES = "https://github.com/billowliu2/KimiSwitch/releases"; +const MIRROR_RELEASES = "https://git.codingplan.site/admin/KimiCodeSwitch/releases"; + +export default function Download() { + const { t } = useLang(); + return ( + +
+ {t.download.items.map((p) => { + const Icon = icons[p.id] ?? WindowsLogo; + return ( +
+
+
+ +
+ + {p.ready ? t.download.ready : t.download.wip} + +
+

{p.name}

+

{p.note}

+ {p.ready && ( + + )} +
+ ); + })} +
+ +

+ + {t.download.autoUpdate} +

+
+ ); +} diff --git a/website/src/sections/Features.tsx b/website/src/sections/Features.tsx new file mode 100644 index 0000000..ddfaf95 --- /dev/null +++ b/website/src/sections/Features.tsx @@ -0,0 +1,76 @@ +import SectionShell from "../components/SectionShell"; +import { useInView } from "../hooks"; +import { useLang } from "../i18n"; +import { asset } from "../lib/asset"; +import { + Stack, + PlusCircle, + Gauge, + ChatsCircle, + Key, + SlidersHorizontal, + MagnifyingGlass, + DownloadSimple, + type Icon, +} from "@phosphor-icons/react"; + +const icons: Record = { + "multi-provider": Stack, + "custom-provider": PlusCircle, + usage: Gauge, + sessions: ChatsCircle, + "kimi-auth": Key, + "usage-config": SlidersHorizontal, + "model-discovery": MagnifyingGlass, + "auto-update": DownloadSimple, +}; + +export default function Features() { + const { t } = useLang(); + const [gridRef, gridInView] = useInView(); + return ( + +
+ {t.features.items.map((f, i) => { + const Icon = icons[f.id] ?? Stack; + return ( +
+
+ {`Kimi +
+
+
+ +
+

{f.title}

+

+ {f.desc} +

+
+
+ ); + })} +
+
+ ); +} diff --git a/website/src/sections/Hero.tsx b/website/src/sections/Hero.tsx new file mode 100644 index 0000000..59d6ce4 --- /dev/null +++ b/website/src/sections/Hero.tsx @@ -0,0 +1,98 @@ +import { useEffect, useState } from "react"; +import { Link } from "react-router-dom"; +import { useLang } from "../i18n"; +import { asset } from "../lib/asset"; + +export default function Hero() { + const { t } = useLang(); + const [mounted, setMounted] = useState(false); + useEffect(() => setMounted(true), []); + + const reveal = (delay: number, extra = "") => ({ + style: { transitionDelay: `${delay}ms` }, + className: `transition-all duration-700 ease-out ${ + mounted + ? "motion-safe:opacity-100 motion-safe:translate-y-0" + : "motion-safe:opacity-0 motion-safe:translate-y-4" + } ${extra}`, + }); + + return ( +
+ {/* 科技风光晕 */} +
+ ); +} diff --git a/website/src/sections/Performance.tsx b/website/src/sections/Performance.tsx new file mode 100644 index 0000000..d81596d --- /dev/null +++ b/website/src/sections/Performance.tsx @@ -0,0 +1,76 @@ +import SectionShell from "../components/SectionShell"; +import { useInView, useCountUp } from "../hooks"; +import { useLang } from "../i18n"; +import { asset } from "../lib/asset"; + +export default function Performance() { + const { t } = useLang(); + return ( + +
+ {t.performance.metrics.map((m) => ( + + ))} +
+ + {/* 仪表盘截图示例 */} +
+
+
+ Kimi Switch usage dashboard (light theme) +
+
+ {t.performance.lightCaption} +
+
+
+
+ Kimi Switch usage dashboard (dark theme) +
+
+ {t.performance.darkCaption} +
+
+
+
+ ); +} + +function Counter({ + target, + decimals = 0, + suffix, + label, + desc, +}: { + target: number; + decimals?: number; + suffix: string; + label: string; + desc: string; +}) { + const [ref, inView] = useInView(); + const v = useCountUp(target, inView); + return ( +
+
+ {v.toFixed(decimals)} + {suffix} +
+
{label}
+
{desc}
+
+ ); +} diff --git a/website/src/sections/Privacy.tsx b/website/src/sections/Privacy.tsx new file mode 100644 index 0000000..5fc5d79 --- /dev/null +++ b/website/src/sections/Privacy.tsx @@ -0,0 +1,37 @@ +import SectionShell from "../components/SectionShell"; +import { Database, LinkSimple, BookOpen, type Icon } from "@phosphor-icons/react"; +import { useLang } from "../i18n"; + +const icons: Record = { + local: Database, + direct: LinkSimple, + open: BookOpen, +}; + +export default function Privacy() { + const { t } = useLang(); + return ( + +
+ {t.privacy.items.map((it) => { + const Icon = icons[it.id] ?? Database; + return ( +
+
+ +
+

{it.title}

+

+ {it.desc} +

+
+ ); + })} +
+
+ ); +} diff --git a/website/src/sections/Showcase.tsx b/website/src/sections/Showcase.tsx new file mode 100644 index 0000000..28d3591 --- /dev/null +++ b/website/src/sections/Showcase.tsx @@ -0,0 +1,46 @@ +import SectionShell from "../components/SectionShell"; +import { useInView } from "../hooks"; +import { useLang } from "../i18n"; +import { asset } from "../lib/asset"; + +export default function Showcase() { + const { t } = useLang(); + const [gridRef, gridInView] = useInView(); + return ( + +
+ {t.showcase.items.map((s, i) => ( +
+
+ {`Kimi +
+
+
{s.title}
+

{s.desc}

+
+
+ ))} +
+
+ ); +} diff --git a/website/src/vite-env.d.ts b/website/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/website/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/website/tailwind.config.js b/website/tailwind.config.js new file mode 100644 index 0000000..a9dfb0f --- /dev/null +++ b/website/tailwind.config.js @@ -0,0 +1,50 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: ["./index.html", "./src/**/*.{ts,tsx}"], + theme: { + extend: { + colors: { + background: "hsl(var(--background) / )", + foreground: "hsl(var(--foreground) / )", + card: { + DEFAULT: "hsl(var(--card) / )", + foreground: "hsl(var(--card-foreground) / )", + }, + muted: { + DEFAULT: "hsl(var(--muted) / )", + foreground: "hsl(var(--muted-foreground) / )", + }, + accent: { + DEFAULT: "hsl(var(--accent) / )", + foreground: "hsl(var(--accent-foreground) / )", + }, + border: "hsl(var(--border) / )", + primary: { + DEFAULT: "hsl(var(--primary) / )", + foreground: "hsl(var(--primary-foreground) / )", + }, + ring: "hsl(var(--ring) / )", + }, + fontFamily: { + sans: [ + "Inter", + "-apple-system", + "BlinkMacSystemFont", + '"Segoe UI"', + '"PingFang SC"', + '"Hiragino Sans GB"', + '"Microsoft YaHei"', + "sans-serif", + ], + mono: [ + '"Fira Code"', + "ui-monospace", + "SFMono-Regular", + "Consolas", + "monospace", + ], + }, + }, + }, + plugins: [], +}; diff --git a/website/tsconfig.json b/website/tsconfig.json new file mode 100644 index 0000000..b33736b --- /dev/null +++ b/website/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "paths": { "@/*": ["./src/*"] } + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} \ No newline at end of file diff --git a/website/tsconfig.node.json b/website/tsconfig.node.json new file mode 100644 index 0000000..4eb43d0 --- /dev/null +++ b/website/tsconfig.node.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true, + "strict": true + }, + "include": ["vite.config.ts"] +} \ No newline at end of file diff --git a/website/vite.config.ts b/website/vite.config.ts new file mode 100644 index 0000000..97f2f63 --- /dev/null +++ b/website/vite.config.ts @@ -0,0 +1,11 @@ +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; + +// GitHub Pages subpath: billowliu2.github.io/KimiSwitch/ +export default defineConfig({ + base: "/KimiSwitch/", + plugins: [react()], + resolve: { + alias: { "@": "/src" }, + }, +}); \ No newline at end of file