commit b0fce840a3ba16a3ac5c2abaaab3a454d7e9ad99 Author: MingNian <1281442923@qq.com> Date: Tue Jul 28 10:24:47 2026 +0800 首次提交:脑晴测 H5 项目 包含前端源码、预构建产物(dist/)、零依赖 Node.js 服务器(server.mjs)、 Cloudflare Worker 版本(worker/)、部署文档(DEPLOY.md)和交接文档。 技术总监可直接 clone 后运行 node server.mjs 启动,无需安装 React 或 build。 DEEPSEEK_API_KEY 通过环境变量注入,未纳入仓库。 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..19db6d3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,35 @@ +# Claude Code 本地配置(可能含个人偏好) +.claude/settings.local.json + +# 之前打的交付 ZIP +brain-h5-deploy-*.zip + +# 日志和 PID +*.log +*.pid +*.out.log +*.err.log + +# 临时和审阅资料 +brain-h5/tmp/ +brain-h5/video-review/ +brain-h5/audit-*/ +brain-h5/qa-*.png + +# 损坏的依赖和锁文件 +brain-h5/node_modules.broken-*/ +brain-h5/package-lock.broken-*.json + +# Vite 服务器残留 +brain-h5/.vite-server.* +brain-h5/vite-combined.log +brain-h5/dev*.log* +brain-h5/dev-server.* + +# 操作系统 +.DS_Store +Thumbs.db + +# IDE +.vscode/ +.idea/ diff --git a/DEPLOY.md b/DEPLOY.md new file mode 100644 index 0000000..dc7fcf3 --- /dev/null +++ b/DEPLOY.md @@ -0,0 +1,133 @@ +# 脑晴测 H5 部署说明(自有服务器 + Node.js) + +更新时间:2026-07-28 + +## 一、项目简介 + +- 中文、免登录的认知能力测评 H5 +- 含四项游戏 + AI 生成报告(DeepSeek) +- 前端 React 19 + Vite,已构建为静态文件 +- 服务端是零依赖单文件 Node.js(`server.mjs`) + +## 二、仓库结构 + +``` +. +├── brain-h5/ +│ ├── dist/client/ # 预构建前端(已含,无需再 build) +│ ├── server.mjs # Node.js 服务器入口(零依赖) +│ ├── src/ # 前端源码(仅二次开发时需要) +│ ├── worker/index.js # Cloudflare Worker 版本(本方案不用) +│ └── ... +├── 交接文档.md +└── DEPLOY.md # 本文件 +``` + +## 三、部署步骤(自有服务器 + Node.js) + +### 1. 系统要求 + +- Node.js v18 或更高(推荐 v20+) +- 任何能跑 Node.js 的操作系统(Linux/Windows/macOS) + +不需要 npm install,不需要 pnpm,不需要 React 开发环境。 + +### 2. 克隆仓库 + +```bash +git clone <仓库地址> +cd Brain +``` + +### 3. 配置 API Key + +`DEEPSEEK_API_KEY` 通过环境变量传入,**不要写入任何文件**。 + +Linux/macOS: +```bash +export DEEPSEEK_API_KEY=sk-你的key +``` + +Windows PowerShell: +```powershell +$env:DEEPSEEK_API_KEY = "sk-你的key" +``` + +或者用 systemd / pm2 / docker 等进程管理工具注入环境变量。 + +### 4. 启动服务 + +```bash +cd brain-h5 +node server.mjs +``` + +默认监听 `0.0.0.0:4173`。可通过环境变量改: + +```bash +PORT=8080 HOST=127.0.0.1 node server.mjs +``` + +### 5. 反向代理(推荐) + +如果服务器有 Nginx,建议反代到 Node 服务: + +```nginx +server { + listen 80; + server_name your.domain.com; + + location / { + proxy_pass http://127.0.0.1:4173; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} +``` + +### 6. 进程守护(生产环境) + +推荐用 pm2: + +```bash +npm install -g pm2 +cd brain-h5 +DEEPSEEK_API_KEY=sk-你的key pm2 start server.mjs --name brain-h5 +pm2 save +pm2 startup +``` + +## 四、健康检查 + +部署完成后应能通过: + +| 检查项 | 期望结果 | +|---|---| +| `GET /` | 返回 HTML(200) | +| `GET /assets/index-*.js` | 返回 JS bundle(200) | +| `POST /api/analyze`(带 JSON body) | 返回 JSON 报告(200) | +| 未配置 Key 时 `POST /api/analyze` | 返回 503 `{"error":"AI service is not configured..."}` | + +## 五、关键安全约束 + +- `DEEPSEEK_API_KEY` **必须**通过环境变量传入,**不要**写入仓库、commit、或前端 bundle。 +- `.env` 文件已在 `.gitignore` 中排除,不会进入仓库。 +- Key 由项目负责人通过私密渠道单独发送。 + +## 六、本地开发(可选,技术总监无需操作) + +如需修改源码并重新构建: + +```bash +cd brain-h5 +pnpm install # 或 npm install +pnpm run dev # 本地开发服务器 +pnpm run build # 重新构建到 dist/client/ +``` + +## 七、联系人 + +- 项目负责人:MingNian +- 项目根目录:`D:\GMS project` diff --git a/brain-h5/.env.example b/brain-h5/.env.example new file mode 100644 index 0000000..73da214 --- /dev/null +++ b/brain-h5/.env.example @@ -0,0 +1,2 @@ +# Server-side only. Never rename this to VITE_DEEPSEEK_API_KEY. +DEEPSEEK_API_KEY=replace_with_your_rotated_key diff --git a/brain-h5/.gitignore b/brain-h5/.gitignore new file mode 100644 index 0000000..67e837d --- /dev/null +++ b/brain-h5/.gitignore @@ -0,0 +1,6 @@ +node_modules/ +dist/ +test-results/ +playwright-report/ +.env +.env.local diff --git a/brain-h5/.npmrc b/brain-h5/.npmrc new file mode 100644 index 0000000..1223b5c --- /dev/null +++ b/brain-h5/.npmrc @@ -0,0 +1,2 @@ +fund=false +audit=false diff --git a/brain-h5/.openai/hosting.json b/brain-h5/.openai/hosting.json new file mode 100644 index 0000000..47c28cb --- /dev/null +++ b/brain-h5/.openai/hosting.json @@ -0,0 +1,4 @@ +{ + "d1": null, + "r2": null +} diff --git a/brain-h5/AGENTS.md b/brain-h5/AGENTS.md new file mode 100644 index 0000000..cacdc74 --- /dev/null +++ b/brain-h5/AGENTS.md @@ -0,0 +1,91 @@ +# Mobile Prototype Agent Guide + +## Prototype Instructions + +### Durable product decisions + +- Each assessment owns a distinct visual theme: ivory/cobalt for symbol matching, mint for trail making, sky blue for attention, and peach/orange for shopping memory. Do not apply one global green theme to all games. +- On narrow screens, every active game must keep its primary prompt and controls inside one `100dvh` interaction surface without long page scrolling. +- Assessment screens use an unframed, low-nesting composition. Generated raster assets must be post-processed to real transparency before use. +- Every task starts with a hands-on practice interaction. Timed tasks stop at zero; completion-based tasks stop immediately when their required objective is reached. +- The home screen is a compact app entry, not a marketing landing page. It includes age, gender, and education selection directly and starts the first task without a separate profile screen. +- Do not use brain imagery in the brand or home experience. Use a calm abstract product mark. +- Active game headers contain only a back control and the timer. Do not show task numbers, percentages, or progress bars. +- Correct and incorrect feedback is icon-only: a green check or red cross. +- Tutorial overlays must point toward the interaction target and ask the user to perform the action, instead of only describing the rules. +- Exact-change practice teaches the controls with an easy example. Formal testing uses three progressively harder, separately timed rounds, does not reveal the target change amount, includes half-unit values, and allows at most two submissions per round. +- Product name is temporarily “脑晴测”. It is a free, no-login Chinese H5 cognitive check that must avoid diagnosis or disease claims. +- The default product is a responsive full-browser H5 page. Desktop must fill the browser viewport and must not show the black phone/device preview frame, status bar, camera cutout, or device picker. Narrow screens retain a portrait-friendly responsive layout without simulated device chrome. +- The selected visual direction combines tactile 2.5D objects resting on a pearl-white surface with spectral cyan/violet/coral gradient indicators. +- The core is four working assessments (symbol matching, alternating trail making, attention/direction, shopping working memory) followed by an AI-generated, tiered report. +- Reference recordings and screenshots define task logic only; all UI copy, assets, motion, composition, and visual identity must be original. +- DeepSeek credentials remain server-side only. Never expose the API key through a `VITE_` environment variable or client bundle. + +In ChatGPT Work Mode, run `sites-preview start "$PWD"`, open `http://terminal.local:4173/` in the cloud browser, and verify the rendered app and its primary interactions. Keep that preview open and tell the user to inspect it in the cloud browser; do not present the local URL as a user-facing chat link. In Codex Desktop, run the local server yourself, open the preview in the in-app browser, and provide the clickable local URL. Do not deploy to Sites unless the user explicitly asks to share, publish, or deploy. Do not give the user server-start instructions when you can run it. + +Before planning or implementing any mobile-app change, read this `AGENTS.md` in full. It is the source of truth for the template's runtime and component guidance. + +Before making substantial visual changes, use the Product Design plugin's `get-context` skill when the visual source is unclear or no longer matches the current goal. When the user gives durable prototype-specific design feedback, preferences, or decisions, record them in `AGENTS.md`. + +When implementing from a selected generated mock, treat that image as the source of truth for layout, component anatomy, density, spacing, color, typography, visible content, and hierarchy. + +## Editing Boundary + +- Build app-specific UI in `src/Prototype.tsx` and `src/prototype.css`. +- Treat `src/App.tsx`, `src/main.tsx`, `src/styles.css`, `src/mobile/`, `public/assets/iphone/`, `public/assets/android/`, `public/assets/status/`, `vite.config.ts`, `worker/index.js`, and `scripts/prepare-sites-build.mjs` as protected runtime files. Do not edit, replace, remove, or recreate them unless the user explicitly asks to change the mobile runtime itself. For an explicit runtime change, update the affected lock hashes only after verifying the new runtime behavior. +- Run `npm run check:runtime` before preview or handoff. If it fails, restore the protected runtime instead of weakening or bypassing the check. +- `npm run build` preserves the mobile runtime and prepares the static Cloudflare Worker output required by Sites. Before a Sites handoff, confirm `dist/client/index.html`, `dist/server/index.js`, `dist/.openai/hosting.json`, and source `.openai/hosting.json` exist, then run `npm run test:sites`. Do not replace this project with a Vinext starter. + +## Runtime Contract + +- Project-specific override (confirmed by the user on 2026-07-23): the production/default route must render the app directly as a full-browser responsive web experience. The older `PhoneFrame` preservation rules below describe the original development template only and do not apply to the default product route. A device preview may exist only as an explicitly separate development tool and must never wrap the user-facing H5. +- Preserve the mobile device runtime unless the user's task explicitly asks otherwise. Do not replace it with a standalone page. Visual fidelity applies to app-owned content inside the device screen, not to template-owned device chrome. +- Keep `App` composed around `PhoneFrame` -> `KeyboardProvider`, with `StatusBar`, app content, `HomeIndicator`, and `KeyboardDock` mounted inside the phone frame. `StatusBar` and the iOS home indicator are overlaid device chrome. When the Android keyboard is closed, the app viewport reserves the protected navigation-bar region instead of painting behind it. When the Android keyboard is open, preserve the current full-screen keyboard layout: its asset includes the IME navigation strip and the separate black navigation bar is hidden. iOS screens continue to paint behind the home-indicator area and own their safe-area content padding. +- Preserve the `iPhone` / `Pixel 10` device picker and both calibrated device presets. The Pixel screen is `427 x 952`; its `32 x 32` camera circle and `public/assets/android/navigation-bar.svg` bottom navigation bar are protected device chrome, not app content. +- Preserve the device picker's intentionally lightweight Codex styling in the top-right corner: its trigger wrapper is borderless and transparent, its trigger sizes to content, and its right-aligned menu uses the compact 3px inset plus the specified hairline and elevation shadow layers. Keep the prototype root and default app screen white. +- Preserve `StatusBar` as live device chrome, including its platform-specific typography, source status-icon assets, and spacing. Pixel 10 uses Roboto, Android indicators, and 32px top, left, and right padding. iPhone uses its iOS indicators, system typography, and calibrated spacing. Do not hardcode screenshot times like `9:41` into the status bar, replace its real-time clock, or move status bar content into app markup unless the user explicitly asks for a fixed/mock device time. +- `PhoneFrame` owns the calibrated device frame, screen portal, device picker, camera cutout, and custom cursor. Keep device assets in `public/assets/iphone/` and `public/assets/android/`; if an asset fails to load, repair the asset path or restore the asset instead of removing the frame, keyboard, or image render. +- Use `MobileScroll` directly for simple single-screen prototypes. Use `FlowStack` for conventional multi-screen flows whose routes can own their fixed header and footer; when using it, define each route as a `FlowScreen`: `{ id, header?, headerHeight?, footer?, footerHeight?, render }`, and use `flow.push(screen)`, `flow.pop()`, and `flow.replace(screen)` from `FlowStack` render callbacks or `useFlow()` instead of introducing another router. +- Use `Carousel` for a carousel, horizontal rail, swipeable cards, image or media strip, horizontally scrollable cards, chip rail, or other horizontal collection. +- For a layered app shell—such as a persistent composer, independently presented sheet, pushed/peek sidebar, or app-wide transition—compose directly in `Prototype.tsx` rather than forcing it through `FlowStack`. Keep app-owned fixed chrome as sibling layers outside `MobileScroll`. +- When using `FlowScreen`, put route-owned fixed headers or footers in `FlowScreen.header` or `FlowScreen.footer`. Set `headerHeight` to the visible app-toolbar height; `FlowStack` adds the device's top safe-area/status-bar inset automatically. Do not include `StatusBar` or its height in the header. Set `footerHeight` to the full app-footer height. `FlowScreen.footer` is an overlay, not reserved layout space; screens using it must add their own bottom content padding such as `padding-bottom: calc(var(--flow-footer-height) + var(--mobile-safe-area-height) + 24px)` so final content can scroll above the footer while still painting behind it. +- Render only scrollable content inside `MobileScroll`; it is for content that should move with scroll and rubber-band overscroll. Keep app-owned headers, nav bars, tabs, composers, and overlays outside it. This keeps scroll physics, safe areas, keyboard insets, scrollbars, and drag click suppression active without letting content paint under fixed chrome. +- Buttons, links, cards, and images inside `MobileScroll` should still allow drag scrolling when the pointer moves beyond tap slop. Use `data-scroll-drag="ignore"` only for rare controls that must own the drag gesture themselves. +- Do not add `var(--keyboard-height)` to ordinary screen/content padding inside `MobileScroll`; the scroll viewport already shrinks above the simulated keyboard. For custom fixed composers, search bars, or toast chrome, use `useKeyboardInsets().bottomInset`. It is relative to the app viewport: Android returns `0` while the closed-keyboard viewport already reserves navigation, then returns the keyboard height while open; iOS continues to clear the home indicator while closed and ride directly above the keyboard while open. Do not pin custom bottom chrome to `bottom: 0` or only `keyboardHeight`. +- Use `KeyboardInput`, `KeyboardTextarea`, or `MobileTextField` for every text-entry control. A raw `input` or `textarea` disconnects focus, keyboard animation, safe-area insets, and attached surfaces. +- Use `BottomSheet` for phone-scoped sheets. Its props are `open`, `onOpenChange`, `title`, optional `description`, optional `snap`, and `children`; it renders through the phone screen portal and dismisses the keyboard before opening. + +## Horizontal Carousels + +- Use `Carousel` for horizontally draggable cards, images, media, chips, or other horizontal collections. Do not recreate these with `overflow-x`, custom pointer handlers, or a generic div. +- `Carousel` can be nested directly inside `MobileScroll`. It owns horizontal gestures and automatically yields vertical gestures to the parent. +- Never put `data-scroll-drag="ignore"` on or around a `Carousel`; doing so prevents vertical parent scrolling when a gesture begins inside it. +- Do not add CSS scroll snapping to `Carousel`; its runtime owns momentum and release motion. +- Use `data-scroll-drag="ignore"` only when a control must prevent parent scrolling in every drag direction. + +See `src/mobile/COMPONENTS.md` for the full component and gesture contract. + +## Keyboard Rule + +The simulated keyboard is a separate top-layer component. Before presenting anything that behaves like iOS navigation or modal UI, dismiss it first. + +Call `keyboard.hide()` before: + +- pushing, popping, or replacing FlowStack routes +- opening bottom sheets, action sheets, dialogs, menus, or navigation sheets +- starting transitions where the destination should not inherit text-input focus + +`FlowStack` already hides the keyboard for `push`, `pop`, and `replace`. `BottomSheet` already hides it before opening. If you add new modal/sheet/navigation primitives, follow the same rule. + +When a composer, search surface, or other keyboard-attached component closes, call `keyboard.hide()` in the same event before changing that component's open state. Position attached surfaces from `useKeyboardInsets()` rather than a separate timer or visibility flag so both dismiss together. + +When any text-entry control loses focus, dismiss the simulated keyboard. If the control is custom or does not use the runtime's keyboard-aware fields, handle its blur event and call `keyboard.hide()` explicitly. Keep the keyboard open only when focus is moving directly to another text-entry control that should share the same keyboard session. + +## Interaction Rules + +- Do not trigger buttons or inputs after a pointer has become a drag. Preserve the drag suppression behavior in `MobileScroll`. +- Do not allow native browser image/file dragging inside the phone frame. Preserve the phone-level `dragstart` suppression and non-draggable image styles so scroll drags that begin on images still scroll the prototype. +- Use `KeyboardInput`, `KeyboardTextarea`, or `MobileTextField` for text entry so the simulated keyboard and safe-area insets stay connected. +- Fixed phone chrome should not animate with pushed screens. Screen content can animate; the status bar, camera cutout, and preview chrome should stay put. +- Keep the keyboard below the home indicator/safe area layer in z-index, and above ordinary app UI while visible. +- Keep the home indicator as the topmost safe-area layer in the z-index above everything else in the prototype. diff --git a/brain-h5/GAME-AUDIT.md b/brain-h5/GAME-AUDIT.md new file mode 100644 index 0000000..1fe180d --- /dev/null +++ b/brain-h5/GAME-AUDIT.md @@ -0,0 +1,42 @@ +# 脑晴测游戏完整性复审 + +复审日期:2026-07-23 +复审范围:无登录入口、资料页、四项任务、AI 报告、手机竖屏交互。 + +## 复审结论 + +初版已具备完整闭环,但存在“能玩、尚未完全产品化”的问题。本轮已完成关键补强,当前版本适合作为免费 H5 内测版;评分仍属于产品分档,不属于医学常模。 + +## 已发现并修复 + +1. 教学只有文字:四项任务现均包含必须完成的互动练习,错误时给出纠错提示,练习不计分。 +2. 连线任务辨识度不足:改为绿色扇区面积排序,目标位置每次随机且避免重叠,并绘制真实连接轨迹。 +3. 注意力场景存在位置规律:青色目标位置和所有干扰方向改为逐题随机。 +4. 任务未完成可能出现虚高分:评分加入任务完成度 20% 权重,报告展示完成比例。 +5. 购物记忆缺少辅助行为记录:每轮允许查看一次清单并记录辅助使用。 +6. 找零一次错误即结束:每轮增加一次纠错机会,第二次后才推进。 +7. 切到后台继续计时:改为自动暂停,返回后由用户主动恢复。 +8. 报告只能查看处理速度:四个认知维度均可点击展开解释、完成度和建议。 +9. 基础资料文案容易让人误认为已有常模:明确说明当前尚未建立医学常模。 +10. 可访问性不足:增加中文方向标签、计时器语义、键盘焦点样式和减少动画适配。 + +## 当前仍需后续数据工作的部分 + +- 分数阈值需要真实用户样本校准。 +- 年龄、教育程度和设备差异目前只用于 AI 解释,不用于医学常模换算。 +- 上线前应完成至少 30–50 名目标用户的可用性测试,再调整题量、限时和字体尺寸。 +- 若未来用于科研或医疗辅助,需要伦理、数据合规和专业量表效度验证。 + +## 审核证据 + +- `audit-2026-07-23/01-start.png` +- `audit-2026-07-23/04-symbol.png` +- `audit-2026-07-23/05-trail.png` +- `audit-2026-07-23/06-attention.png` +- `audit-2026-07-23/07-memory.png` +- `audit-2026-07-23/08-report.png` +- `audit-2026-07-23/09-practice.png` +- `audit-2026-07-23/10-trail-improved.png` +- `audit-2026-07-23/11-report-improved.png` + +final result: passed for H5 internal testing diff --git a/brain-h5/GAME-DESIGN.md b/brain-h5/GAME-DESIGN.md new file mode 100644 index 0000000..d509075 --- /dev/null +++ b/brain-h5/GAME-DESIGN.md @@ -0,0 +1,104 @@ +# 脑晴测 H5 游戏设计规范(增强版 v1.1) + +## 通用测试约束 + +- 竖屏触控优先;正式测试时不允许横屏布局改变刺激相对关系。 +- 每项任务必须先完成一道互动练习,教程和正式测试严格分离,练习行为不进入正式分数。 +- 每个有效操作记录:游戏、题号、期望答案、用户答案、正确性、反应时间和时间戳。 +- 切换后台时自动暂停计时并要求用户主动恢复;页面刷新、主动退出视为未完整完成。 +- 报告只解释本次任务表现,不输出疾病或诊断结论。 + +## 1. 符号速配(处理速度) + +### 规则 + +- 10 个视觉符号与数字 0–9 建立随机一一映射。 +- 同一次正式测试中映射固定,重新评估时重新随机。 +- 屏幕中央每题显示一个目标符号,用户点击其映射数字。 +- 连续目标不得与上一题相同。 +- 30 题或 60 秒先到即结束。 + +### 数据 + +- 正确数、错误数、正确率。 +- 每题反应时间、平均反应时间。 +- 连续错误、超时、完成题数。 + +### 评分重点 + +- 正确率 55%,速度 20%,任务完成度 20%,基础分 5%,错误额外扣分。 +- 未完成 30 题时按完成比例扣分,避免“只做少量题但正确率高”获得虚高结果。 + +## 2. 交替连线(执行功能) + +### 规则 + +- 画布中包含数字 1–10 和 10 个绿色面积依次增大的扇区圆。 +- 每次评估重新随机 20 个目标的位置,并使用预设安全点位避免重叠。 +- 正确顺序:1 → 最小绿色扇区 → 2 → 第二小绿色扇区,直到 10 → 最大绿色扇区。 +- 每次正确选择后绘制连接轨迹,帮助用户确认路径与当前进度。 +- 点错不推进当前步骤,并记录错误目标和错误类型。 +- 20 个目标或 180 秒先到即结束。 + +### 数据 + +- 已完成步骤、总用时、单步停顿时间。 +- 数字顺序错误、色块大小错误、规则切换错误。 +- 错误发生在任务前段还是后段。 + +## 3. 方向追踪(注意力) + +### 规则 + +- 每题展示 7 架飞机,只有 1 架保持青色,其余为高区分度干扰颜色。 +- 飞机使用唯一长机头、钝尾、后方短翼和尾翼,避免方向歧义。 +- 方向仅使用上、右、下、左四个标准 90° 旋转。 +- 用户找到青色目标后点击机头方向。 +- 每题重新随机青色目标位置和干扰飞机方向,避免用户通过固定位置规律作答。 +- 30 题或 60 秒先到即结束;3 次错误后提前结束。 + +### 数据 + +- 正确率、平均反应时间、剩余容错次数。 +- 上下混淆、左右混淆和连续失误。 +- 前后半程反应速度变化。 + +## 4. 购物记忆(工作记忆) + +### 第 1–4 轮:清单回忆 + +- 清单长度依次为 2、3、4、5 件。 +- 每轮从 8 件商品中随机抽取,用户确认记住后隐藏清单。 +- 用户从完整货架中多选刚才出现的商品。 +- 每轮允许查看一次原清单;查看行为会被记录为辅助使用并进入错误/辅助指标。 +- 记录命中、遗漏、误选、辅助查看和回忆时间。 + +### 独立任务:精确找零 + +- 正式测试不直接显示应找金额,用户需根据价格与付款金额自行计算。 +- 第 1 轮:价格 ¥13,付款 ¥20,目标找零 ¥7,限时 40 秒。 +- 第 2 轮:价格 ¥26.5,付款 ¥40,目标找零 ¥13.5,限时 45 秒。 +- 第 3 轮:价格 ¥41.5,付款 ¥60,目标找零 ¥18.5,限时 50 秒。 +- 可使用 ¥0.5、¥1、¥2、¥5、¥10、¥20 面额组合。 +- 每轮最多尝试 2 次;第一次错误后清空金额并提供一次重试机会。 +- 记录每次金额、金额误差、尝试次数和操作时间。 + +### 结束条件 + +- 购物记忆完成 3 轮后结束该任务;精确找零完成 3 轮后结束该任务。每轮以各自倒计时为准。 + +## 分数与报告 + +- 每个维度输出 20–98 分,避免原型阶段制造虚假的绝对满分精度。 +- 分数同时考虑正确率、反应速度、任务完成度和错误惩罚。 +- 80–98:状态不错;60–79:状态平稳;20–59:可以提升。 +- DeepSeek 根据结构化维度数据生成总结、优势、提升空间和三条建议。 +- DeepSeek 超时、配置缺失或返回格式错误时,自动使用本地规则报告。 +- 所有措辞限定为本次表现,不使用医疗诊断词汇。 +- 报告中的四个维度均可点击展开,并显示对应解释、完成度和建议。 + +## 后续校准 + +- 当前分值属于产品 MVP 分档,不是临床常模。 +- 后续应按年龄、教育程度、设备类型和真实样本分布建立常模。 +- 在常模完成前,报告必须保留“仅供自我了解与能力参考”的说明。 diff --git a/brain-h5/README.md b/brain-h5/README.md new file mode 100644 index 0000000..53bd0ca --- /dev/null +++ b/brain-h5/README.md @@ -0,0 +1,31 @@ +# 脑晴测 H5 + +一个无需登录的中文数字认知评估 H5,包含处理速度、执行功能、注意力和工作记忆四项任务,以及 DeepSeek 辅助生成的非医疗化表现报告。 + +## 技术栈 + +- React 19 + Vite +- TypeScript/JSX(业务代码不依赖复杂类型系统,后续可平移至 Taro React) +- Phosphor Icons +- Cloudflare Worker / Vite 本地中间件代理 DeepSeek + +## 本地运行 + +1. 复制 `.env.example` 为 `.env`。 +2. 在 `.env` 中设置服务端 `DEEPSEEK_API_KEY`,不要添加 `VITE_` 前缀。 +3. 安装依赖并运行 `pnpm dev`。 + +## 验证命令 + +- `pnpm run check:runtime` +- `pnpm run build` +- `pnpm run test:sites` + +## 隐私与安全 + +- API Key 不进入浏览器构建产物。 +- 测试结果默认仅保存在当前浏览器 `localStorage`,用于显示最近一次报告。 +- 调用 AI 时仅发送基础范围、四维指标和事件数量,不发送姓名、手机号等身份信息。 +- 上线部署时应将 `DEEPSEEK_API_KEY` 配置为服务端 Secret。 + +详细任务规则见 [GAME-DESIGN.md](./GAME-DESIGN.md)。 diff --git a/brain-h5/design-qa.md b/brain-h5/design-qa.md new file mode 100644 index 0000000..032f6be --- /dev/null +++ b/brain-h5/design-qa.md @@ -0,0 +1,58 @@ +**Design QA** + +- Source visual truth: + - `C:\Users\明年\AppData\Local\Temp\codex-clipboard-b2896c59-bbb1-4cbb-9a79-a7e0830e0d46.png` + - `C:\Users\明年\AppData\Local\Temp\codex-clipboard-84af1b55-83a2-49e7-b04f-1e84ea95049f.png` + - `C:\Users\明年\AppData\Local\Temp\codex-clipboard-b0b0bd77-9865-4dc2-a5a5-d72b44f3dfba.png` + - `C:\Users\明年\AppData\Local\Temp\codex-clipboard-14be5be9-42f8-4947-81e3-695cca505d36.png` + - `C:\Users\明年\AppData\Local\Temp\codex-clipboard-19cddb0d-1628-4d21-a97d-6695a376ac74.png` + - `C:\Users\明年\AppData\Local\Temp\codex-clipboard-0f791933-9ea7-4cb1-8fa1-b8b12745ee6f.png` + - `C:\Users\明年\AppData\Local\Temp\codex-clipboard-5b000418-c746-465d-9d1-1cd4cdafaa70.png` +- Implementation screenshot: `D:\GMS project\brain-h5\qa-home-mobile.png` +- Viewport: 393 x 852 CSS pixels, device scale factor 1. +- State: mobile home screen; assessment screens could not be captured. +- Source density: mixed supplied PNG dimensions. +- Implementation density: 393 x 852 pixels. + +**Comparison History** + +- Initial implementation used one green-led palette, vertically stacked desktop panels on mobile, opaque checkerboard assets, a 5-column number pad, linear direction controls, duplicate target-color planes, manual memory confirmation, and timers that did not stop the task. +- Fixes applied: + - Added distinct ivory/cobalt, mint, sky-blue, and peach/orange game themes. + - Constrained active mobile game surfaces to `100dvh`. + - Removed large nested game containers on the mobile breakpoint. + - Converted supplied images to real transparent PNG assets. + - Added 3 x 4 numeric keypad layout and floating target motion. + - Made attention target color unique and direction controls spatial. + - Made conveyor items move in one horizontal row and select immediately. + - Added image-based expandable shopping list. + - Replaced pre-game rule cards with in-context guided demos on the real game surfaces. + - Added four-piece click-blocking shade, a live target cutout, and Chinese coach bubbles. + - Required real clicks on the symbol keypad, trail nodes, direction key, shopping list, and conveyor item before formal timing starts. + - Added objective and timer completion states. + - Compacted mobile home, profile, and 2 x 2 overview screens. + - Restored plane entry from all four screen edges while preventing delayed planes from appearing in the middle. + - Added animated symbol relocation, 3.5-second conveyor spacing, larger shopping-list imagery, and ringed result icons. + +**Fidelity Surfaces** + +- Typography: Chinese copy and hierarchy compile correctly; game-screen visual comparison remains unavailable. +- Spacing and layout: code constrains active games to one mobile viewport; browser-rendered confirmation remains unavailable. +- Colors: four independent themes are implemented and no longer share one global green theme. +- Image quality: all 20 supplied assets now contain real alpha; checkerboard pixels are not rendered as content. +- Copy: Chinese in-context coaching, timeout messaging, and shopping-list labels are present. + +**Verification** + +- `npm run check:runtime`: passed. +- `npm run build`: passed. +- Local HTTP health: 200. +- Server binding: `0.0.0.0:4173`. +- Primary interactions tested in browser: home navigation only; the latest guided-demo states could not be captured. +- Browser console: no application error was observed before local-address interaction was blocked. + +**Blocker** + +- The in-app browser security policy stopped further interaction with the local address after the home screen. Therefore matching assessment-screen screenshots and full interaction testing could not be completed in this run. + +final result: blocked diff --git a/brain-h5/dist/.openai/hosting.json b/brain-h5/dist/.openai/hosting.json new file mode 100644 index 0000000..47c28cb --- /dev/null +++ b/brain-h5/dist/.openai/hosting.json @@ -0,0 +1,4 @@ +{ + "d1": null, + "r2": null +} diff --git a/brain-h5/dist/client/assets/android/Keyboard.png b/brain-h5/dist/client/assets/android/Keyboard.png new file mode 100644 index 0000000..bf959fa Binary files /dev/null and b/brain-h5/dist/client/assets/android/Keyboard.png differ diff --git a/brain-h5/dist/client/assets/android/Pixel10.png b/brain-h5/dist/client/assets/android/Pixel10.png new file mode 100644 index 0000000..2ba4a10 Binary files /dev/null and b/brain-h5/dist/client/assets/android/Pixel10.png differ diff --git a/brain-h5/dist/client/assets/android/navigation-bar.svg b/brain-h5/dist/client/assets/android/navigation-bar.svg new file mode 100644 index 0000000..9e79543 --- /dev/null +++ b/brain-h5/dist/client/assets/android/navigation-bar.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/brain-h5/dist/client/assets/brain/airplane-source.png b/brain-h5/dist/client/assets/brain/airplane-source.png new file mode 100644 index 0000000..35728f8 Binary files /dev/null and b/brain-h5/dist/client/assets/brain/airplane-source.png differ diff --git a/brain-h5/dist/client/assets/brain/airplane.png b/brain-h5/dist/client/assets/brain/airplane.png new file mode 100644 index 0000000..87f3d22 Binary files /dev/null and b/brain-h5/dist/client/assets/brain/airplane.png differ diff --git a/brain-h5/dist/client/assets/brain/design-reference.png b/brain-h5/dist/client/assets/brain/design-reference.png new file mode 100644 index 0000000..644ffc2 Binary files /dev/null and b/brain-h5/dist/client/assets/brain/design-reference.png differ diff --git a/brain-h5/dist/client/assets/brain/direction-object.png b/brain-h5/dist/client/assets/brain/direction-object.png new file mode 100644 index 0000000..c6d95a9 Binary files /dev/null and b/brain-h5/dist/client/assets/brain/direction-object.png differ diff --git a/brain-h5/dist/client/assets/brain/direction-source.png b/brain-h5/dist/client/assets/brain/direction-source.png new file mode 100644 index 0000000..a73fc16 Binary files /dev/null and b/brain-h5/dist/client/assets/brain/direction-source.png differ diff --git a/brain-h5/dist/client/assets/brain/memory/bread.png b/brain-h5/dist/client/assets/brain/memory/bread.png new file mode 100644 index 0000000..3c2469b Binary files /dev/null and b/brain-h5/dist/client/assets/brain/memory/bread.png differ diff --git a/brain-h5/dist/client/assets/brain/memory/carrot.png b/brain-h5/dist/client/assets/brain/memory/carrot.png new file mode 100644 index 0000000..71b4f8b Binary files /dev/null and b/brain-h5/dist/client/assets/brain/memory/carrot.png differ diff --git a/brain-h5/dist/client/assets/brain/memory/cheese.png b/brain-h5/dist/client/assets/brain/memory/cheese.png new file mode 100644 index 0000000..65ed926 Binary files /dev/null and b/brain-h5/dist/client/assets/brain/memory/cheese.png differ diff --git a/brain-h5/dist/client/assets/brain/memory/coffee.png b/brain-h5/dist/client/assets/brain/memory/coffee.png new file mode 100644 index 0000000..bbacaec Binary files /dev/null and b/brain-h5/dist/client/assets/brain/memory/coffee.png differ diff --git a/brain-h5/dist/client/assets/brain/memory/cookie.png b/brain-h5/dist/client/assets/brain/memory/cookie.png new file mode 100644 index 0000000..b3f8b4a Binary files /dev/null and b/brain-h5/dist/client/assets/brain/memory/cookie.png differ diff --git a/brain-h5/dist/client/assets/brain/memory/egg.png b/brain-h5/dist/client/assets/brain/memory/egg.png new file mode 100644 index 0000000..6068e68 Binary files /dev/null and b/brain-h5/dist/client/assets/brain/memory/egg.png differ diff --git a/brain-h5/dist/client/assets/brain/memory/fish.png b/brain-h5/dist/client/assets/brain/memory/fish.png new file mode 100644 index 0000000..3242c63 Binary files /dev/null and b/brain-h5/dist/client/assets/brain/memory/fish.png differ diff --git a/brain-h5/dist/client/assets/brain/memory/orange.png b/brain-h5/dist/client/assets/brain/memory/orange.png new file mode 100644 index 0000000..142c786 Binary files /dev/null and b/brain-h5/dist/client/assets/brain/memory/orange.png differ diff --git a/brain-h5/dist/client/assets/brain/planes/coral.png b/brain-h5/dist/client/assets/brain/planes/coral.png new file mode 100644 index 0000000..490f12e Binary files /dev/null and b/brain-h5/dist/client/assets/brain/planes/coral.png differ diff --git a/brain-h5/dist/client/assets/brain/planes/teal.png b/brain-h5/dist/client/assets/brain/planes/teal.png new file mode 100644 index 0000000..5f937d8 Binary files /dev/null and b/brain-h5/dist/client/assets/brain/planes/teal.png differ diff --git a/brain-h5/dist/client/assets/brain/symbols/camera.png b/brain-h5/dist/client/assets/brain/symbols/camera.png new file mode 100644 index 0000000..fade936 Binary files /dev/null and b/brain-h5/dist/client/assets/brain/symbols/camera.png differ diff --git a/brain-h5/dist/client/assets/brain/symbols/coffee.png b/brain-h5/dist/client/assets/brain/symbols/coffee.png new file mode 100644 index 0000000..1436ca0 Binary files /dev/null and b/brain-h5/dist/client/assets/brain/symbols/coffee.png differ diff --git a/brain-h5/dist/client/assets/brain/symbols/gear.png b/brain-h5/dist/client/assets/brain/symbols/gear.png new file mode 100644 index 0000000..8404654 Binary files /dev/null and b/brain-h5/dist/client/assets/brain/symbols/gear.png differ diff --git a/brain-h5/dist/client/assets/brain/symbols/lightning.png b/brain-h5/dist/client/assets/brain/symbols/lightning.png new file mode 100644 index 0000000..364e3ec Binary files /dev/null and b/brain-h5/dist/client/assets/brain/symbols/lightning.png differ diff --git a/brain-h5/dist/client/assets/brain/symbols/lock.png b/brain-h5/dist/client/assets/brain/symbols/lock.png new file mode 100644 index 0000000..e818a36 Binary files /dev/null and b/brain-h5/dist/client/assets/brain/symbols/lock.png differ diff --git a/brain-h5/dist/client/assets/brain/symbols/moon.png b/brain-h5/dist/client/assets/brain/symbols/moon.png new file mode 100644 index 0000000..7d5635e Binary files /dev/null and b/brain-h5/dist/client/assets/brain/symbols/moon.png differ diff --git a/brain-h5/dist/client/assets/brain/symbols/puzzle.png b/brain-h5/dist/client/assets/brain/symbols/puzzle.png new file mode 100644 index 0000000..55c3bf0 Binary files /dev/null and b/brain-h5/dist/client/assets/brain/symbols/puzzle.png differ diff --git a/brain-h5/dist/client/assets/brain/symbols/squares.png b/brain-h5/dist/client/assets/brain/symbols/squares.png new file mode 100644 index 0000000..3aeaebb Binary files /dev/null and b/brain-h5/dist/client/assets/brain/symbols/squares.png differ diff --git a/brain-h5/dist/client/assets/brain/symbols/star.png b/brain-h5/dist/client/assets/brain/symbols/star.png new file mode 100644 index 0000000..d406cb6 Binary files /dev/null and b/brain-h5/dist/client/assets/brain/symbols/star.png differ diff --git a/brain-h5/dist/client/assets/brain/symbols/sun.png b/brain-h5/dist/client/assets/brain/symbols/sun.png new file mode 100644 index 0000000..1b2bca0 Binary files /dev/null and b/brain-h5/dist/client/assets/brain/symbols/sun.png differ diff --git a/brain-h5/dist/client/assets/index-8xOYLbW9.js b/brain-h5/dist/client/assets/index-8xOYLbW9.js new file mode 100644 index 0000000..57f2380 --- /dev/null +++ b/brain-h5/dist/client/assets/index-8xOYLbW9.js @@ -0,0 +1,9 @@ +var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t,n)=>()=>{if(n)throw n[0];try{return e&&(t=e(e=0)),t}catch(e){throw n=[e],e}},s=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),c=(e,n)=>{let r={};for(var i in e)t(r,i,{get:e[i],enumerable:!0});return n||t(r,Symbol.toStringTag,{value:`Module`}),r},l=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;li[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},u=(n,r,a)=>(a=n==null?{}:e(i(n)),l(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n)),d=e=>a.call(e,`module.exports`)?e[`module.exports`]:l(t({},`__esModule`,{value:!0}),e);(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var f=s((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.portal`),r=Symbol.for(`react.fragment`),i=Symbol.for(`react.strict_mode`),a=Symbol.for(`react.profiler`),o=Symbol.for(`react.consumer`),s=Symbol.for(`react.context`),c=Symbol.for(`react.forward_ref`),l=Symbol.for(`react.suspense`),u=Symbol.for(`react.memo`),d=Symbol.for(`react.lazy`),f=Symbol.for(`react.activity`),p=Symbol.iterator;function m(e){return typeof e!=`object`||!e?null:(e=p&&e[p]||e[`@@iterator`],typeof e==`function`?e:null)}var h={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},g=Object.assign,_={};function v(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}v.prototype.isReactComponent={},v.prototype.setState=function(e,t){if(typeof e!=`object`&&typeof e!=`function`&&e!=null)throw Error(`takes an object of state variables to update or a function which returns an object of state variables.`);this.updater.enqueueSetState(this,e,t,`setState`)},v.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,`forceUpdate`)};function y(){}y.prototype=v.prototype;function b(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}var x=b.prototype=new y;x.constructor=b,g(x,v.prototype),x.isPureReactComponent=!0;var S=Array.isArray;function C(){}var w={H:null,A:null,T:null,S:null},ee=Object.prototype.hasOwnProperty;function te(e,n,r){var i=r.ref;return{$$typeof:t,type:e,key:n,ref:i===void 0?null:i,props:r}}function ne(e,t){return te(e.type,t,e.props)}function T(e){return typeof e==`object`&&!!e&&e.$$typeof===t}function re(e){var t={"=":`=0`,":":`=2`};return`$`+e.replace(/[=:]/g,function(e){return t[e]})}var ie=/\/+/g;function ae(e,t){return typeof e==`object`&&e&&e.key!=null?re(``+e.key):t.toString(36)}function oe(e){switch(e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason;default:switch(typeof e.status==`string`?e.then(C,C):(e.status=`pending`,e.then(function(t){e.status===`pending`&&(e.status=`fulfilled`,e.value=t)},function(t){e.status===`pending`&&(e.status=`rejected`,e.reason=t)})),e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason}}throw e}function se(e,r,i,a,o){var s=typeof e;(s===`undefined`||s===`boolean`)&&(e=null);var c=!1;if(e===null)c=!0;else switch(s){case`bigint`:case`string`:case`number`:c=!0;break;case`object`:switch(e.$$typeof){case t:case n:c=!0;break;case d:return c=e._init,se(c(e._payload),r,i,a,o)}}if(c)return o=o(e),c=a===``?`.`+ae(e,0):a,S(o)?(i=``,c!=null&&(i=c.replace(ie,`$&/`)+`/`),se(o,r,i,``,function(e){return e})):o!=null&&(T(o)&&(o=ne(o,i+(o.key==null||e&&e.key===o.key?``:(``+o.key).replace(ie,`$&/`)+`/`)+c)),r.push(o)),1;c=0;var l=a===``?`.`:a+`:`;if(S(e))for(var u=0;u{t.exports=f()})),m=s((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0>>1,a=e[r];if(0>>1;ri(c,n))li(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(li(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(e.unstable_now=void 0,typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=!1,_=typeof setTimeout==`function`?setTimeout:null,v=typeof clearTimeout==`function`?clearTimeout:null,y=typeof setImmediate<`u`?setImmediate:null;function b(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function x(e){if(h=!1,b(e),!m)if(n(c)!==null)m=!0,S||(S=!0,T());else{var t=n(l);t!==null&&ae(x,t.startTime-e)}}var S=!1,C=-1,w=5,ee=-1;function te(){return g?!0:!(e.unstable_now()-eet&&te());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=t);if(t=e.unstable_now(),typeof s==`function`){d.callback=s,b(t),i=!0;break b}d===n(c)&&r(c),b(t)}else r(c);d=n(c)}if(d!==null)i=!0;else{var u=n(l);u!==null&&ae(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}i=void 0}}finally{i?T():S=!1}}}var T;if(typeof y==`function`)T=function(){y(ne)};else if(typeof MessageChannel<`u`){var re=new MessageChannel,ie=re.port2;re.port1.onmessage=ne,T=function(){ie.postMessage(null)}}else T=function(){_(ne,0)};function ae(t,n){C=_(function(){t(e.unstable_now())},n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_forceFrameRate=function(e){0>e||125o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(C),C=-1):h=!0,ae(x,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,S||(S=!0,T()))),r},e.unstable_shouldYield=te,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),h=s(((e,t)=>{t.exports=m()})),g=s((e=>{var t=p();function n(e){var t=`https://react.dev/errors/`+e;if(1{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=g()})),v=s((e=>{var t=h(),n=p(),r=_();function i(e){var t=`https://react.dev/errors/`+e;if(1fe||(e.current=de[fe],de[fe]=null,fe--)}function k(e,t){fe++,de[fe]=e.current,e.current=t}var me=O(null),he=O(null),ge=O(null),_e=O(null);function ve(e,t){switch(k(ge,t),k(he,e),k(me,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?Vd(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=Vd(t),e=Hd(t,e);else switch(e){case`svg`:e=1;break;case`math`:e=2;break;default:e=0}}pe(me),k(me,e)}function ye(){pe(me),pe(he),pe(ge)}function be(e){e.memoizedState!==null&&k(_e,e);var t=me.current,n=Hd(t,e.type);t!==n&&(k(he,e),k(me,n))}function xe(e){he.current===e&&(pe(me),pe(he)),_e.current===e&&(pe(_e),Qf._currentValue=ue)}var Se,Ce;function we(e){if(Se===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);Se=t&&t[1]||``,Ce=-1)`:-1i||c[r]!==l[i]){var u=` +`+c[r].replace(` at new `,` at `);return e.displayName&&u.includes(``)&&(u=u.replace(``,e.displayName)),u}while(1<=r&&0<=i);break}}}finally{Te=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:``)?we(n):``}function De(e,t){switch(e.tag){case 26:case 27:case 5:return we(e.type);case 16:return we(`Lazy`);case 13:return e.child!==t&&t!==null?we(`Suspense Fallback`):we(`Suspense`);case 19:return we(`SuspenseList`);case 0:case 15:return Ee(e.type,!1);case 11:return Ee(e.type.render,!1);case 1:return Ee(e.type,!0);case 31:return we(`Activity`);default:return``}}function Oe(e){try{var t=``,n=null;do t+=De(e,n),n=e,e=e.return;while(e);return t}catch(e){return` +Error generating stack: `+e.message+` +`+e.stack}}var ke=Object.prototype.hasOwnProperty,Ae=t.unstable_scheduleCallback,je=t.unstable_cancelCallback,Me=t.unstable_shouldYield,Ne=t.unstable_requestPaint,Pe=t.unstable_now,Fe=t.unstable_getCurrentPriorityLevel,Ie=t.unstable_ImmediatePriority,Le=t.unstable_UserBlockingPriority,Re=t.unstable_NormalPriority,A=t.unstable_LowPriority,ze=t.unstable_IdlePriority,j=t.log,Be=t.unstable_setDisableYieldValue,Ve=null,He=null;function M(e){if(typeof j==`function`&&Be(e),He&&typeof He.setStrictMode==`function`)try{He.setStrictMode(Ve,e)}catch{}}var Ue=Math.clz32?Math.clz32:Ke,We=Math.log,Ge=Math.LN2;function Ke(e){return e>>>=0,e===0?32:31-(We(e)/Ge|0)|0}var qe=256,Je=262144,Ye=4194304;function Xe(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function Ze(e,t,n){var r=e.pendingLanes;if(r===0)return 0;var i=0,a=e.suspendedLanes,o=e.pingedLanes;e=e.warmLanes;var s=r&134217727;return s===0?(s=r&~a,s===0?o===0?n||(n=r&~e,n!==0&&(i=Xe(n))):i=Xe(o):i=Xe(s)):(r=s&~a,r===0?(o&=s,o===0?n||(n=s&~e,n!==0&&(i=Xe(n))):i=Xe(o)):i=Xe(r)),i===0?0:t!==0&&t!==i&&(t&a)===0&&(a=i&-i,n=t&-t,a>=n||a===32&&n&4194048)?t:i}function Qe(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function $e(e,t){switch(e){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function et(){var e=Ye;return Ye<<=1,!(Ye&62914560)&&(Ye=4194304),e}function tt(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function nt(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function rt(e,t,n,r,i,a){var o=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var s=e.entanglements,c=e.expirationTimes,l=e.hiddenUpdates;for(n=o&~n;0`u`||window.document===void 0||window.document.createElement===void 0),fn=!1;if(dn)try{var pn={};Object.defineProperty(pn,"passive",{get:function(){fn=!0}}),window.addEventListener(`test`,pn,pn),window.removeEventListener(`test`,pn,pn)}catch{fn=!1}var mn=null,hn=null,gn=null;function _n(){if(gn)return gn;var e,t=hn,n=t.length,r,i=`value`in mn?mn.value:mn.textContent,a=i.length;for(e=0;e=Yn),Qn=` `,$n=!1;function er(e,t){switch(e){case`keyup`:return qn.indexOf(t.keyCode)!==-1;case`keydown`:return t.keyCode!==229;case`keypress`:case`mousedown`:case`focusout`:return!0;default:return!1}}function tr(e){return e=e.detail,typeof e==`object`&&`data`in e?e.data:null}var nr=!1;function rr(e,t){switch(e){case`compositionend`:return tr(t);case`keypress`:return t.which===32?($n=!0,Qn):null;case`textInput`:return e=t.data,e===Qn&&$n?null:e;default:return null}}function ir(e,t){if(nr)return e===`compositionend`||!Jn&&er(e,t)?(e=_n(),gn=hn=mn=null,nr=!1,e):null;switch(e){case`paste`:return null;case`keypress`:if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=r}a:{for(;n;){if(n.nextSibling){n=n.nextSibling;break a}n=n.parentNode}n=void 0}n=Er(n)}}function Or(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Or(e,t.parentNode):`contains`in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function kr(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=zt(e.document);t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href==`string`}catch{n=!1}if(n)e=t.contentWindow;else break;t=zt(e.document)}return t}function Ar(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t===`input`&&(e.type===`text`||e.type===`search`||e.type===`tel`||e.type===`url`||e.type===`password`)||t===`textarea`||e.contentEditable===`true`)}var jr=dn&&`documentMode`in document&&11>=document.documentMode,Mr=null,Nr=null,Pr=null,Fr=!1;function Ir(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;Fr||Mr==null||Mr!==zt(r)||(r=Mr,`selectionStart`in r&&Ar(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Pr&&Tr(Pr,r)||(Pr=r,r=Dd(Nr,`onSelect`),0>=o,i-=o,Di=1<<32-Ue(t)+i|n<h?(g=d,d=null):g=d.sibling;var _=p(i,d,s[h],c);if(_===null){d===null&&(d=g);break}e&&d&&_.alternate===null&&t(i,d),a=o(_,a,h),u===null?l=_:u.sibling=_,u=_,d=g}if(h===s.length)return n(i,d),z&&ki(i,h),l;if(d===null){for(;hg?(_=h,h=null):_=h.sibling;var y=p(a,h,v.value,l);if(y===null){h===null&&(h=_);break}e&&h&&y.alternate===null&&t(a,h),s=o(y,s,g),d===null?u=y:d.sibling=y,d=y,h=_}if(v.done)return n(a,h),z&&ki(a,g),u;if(h===null){for(;!v.done;g++,v=c.next())v=f(a,v.value,l),v!==null&&(s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return z&&ki(a,g),u}for(h=r(h);!v.done;g++,v=c.next())v=m(h,a,g,v.value,l),v!==null&&(e&&v.alternate!==null&&h.delete(v.key===null?g:v.key),s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return e&&h.forEach(function(e){return t(a,e)}),z&&ki(a,g),u}function b(e,r,o,c){if(typeof o==`object`&&o&&o.type===y&&o.key===null&&(o=o.props.children),typeof o==`object`&&o){switch(o.$$typeof){case g:a:{for(var l=o.key;r!==null;){if(r.key===l){if(l=o.type,l===y){if(r.tag===7){n(e,r.sibling),c=a(r,o.props.children),c.return=e,e=c;break a}}else if(r.elementType===l||typeof l==`object`&&l&&l.$$typeof===T&&Oa(l)===r.type){n(e,r.sibling),c=a(r,o.props),Fa(c,o),c.return=e,e=c;break a}n(e,r);break}else t(e,r);r=r.sibling}o.type===y?(c=mi(o.props.children,e.mode,c,o.key),c.return=e,e=c):(c=pi(o.type,o.key,o.props,null,e.mode,c),Fa(c,o),c.return=e,e=c)}return s(e);case v:a:{for(l=o.key;r!==null;){if(r.key===l)if(r.tag===4&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),c=a(r,o.children||[]),c.return=e,e=c;break a}else{n(e,r);break}else t(e,r);r=r.sibling}c=_i(o,e.mode,c),c.return=e,e=c}return s(e);case T:return o=Oa(o),b(e,r,o,c)}if(le(o))return h(e,r,o,c);if(oe(o)){if(l=oe(o),typeof l!=`function`)throw Error(i(150));return o=l.call(o),_(e,r,o,c)}if(typeof o.then==`function`)return b(e,r,Pa(o),c);if(o.$$typeof===C)return b(e,r,na(e,o),c);Ia(e,o)}return typeof o==`string`&&o!==``||typeof o==`number`||typeof o==`bigint`?(o=``+o,r!==null&&r.tag===6?(n(e,r.sibling),c=a(r,o),c.return=e,e=c):(n(e,r),c=hi(o,e.mode,c),c.return=e,e=c),s(e)):n(e,r)}return function(e,t,n,r){try{Na=0;var i=b(e,t,n,r);return Ma=null,i}catch(t){if(t===Sa||t===wa)throw t;var a=li(29,t,null,e.mode);return a.lanes=r,a.return=e,a}}}var Ra=La(!0),za=La(!1),Ba=!1;function Va(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Ha(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function Ua(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function Wa(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,G&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,t=oi(e),ai(e,null,n),t}return ri(e,r,t,n),oi(e)}function Ga(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,n&4194048)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,at(e,n)}}function Ka(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var i=null,a=null;if(n=n.firstBaseUpdate,n!==null){do{var o={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};a===null?i=a=o:a=a.next=o,n=n.next}while(n!==null);a===null?i=a=t:a=a.next=t}else i=a=t;n={baseState:r.baseState,firstBaseUpdate:i,lastBaseUpdate:a,shared:r.shared,callbacks:r.callbacks},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var qa=!1;function Ja(){if(qa){var e=pa;if(e!==null)throw e}}function Ya(e,t,n,r){qa=!1;var i=e.updateQueue;Ba=!1;var a=i.firstBaseUpdate,o=i.lastBaseUpdate,s=i.shared.pending;if(s!==null){i.shared.pending=null;var c=s,l=c.next;c.next=null,o===null?a=l:o.next=l,o=c;var u=e.alternate;u!==null&&(u=u.updateQueue,s=u.lastBaseUpdate,s!==o&&(s===null?u.firstBaseUpdate=l:s.next=l,u.lastBaseUpdate=c))}if(a!==null){var d=i.baseState;o=0,u=l=c=null,s=a;do{var p=s.lane&-536870913,m=p!==s.lane;if(m?(J&p)===p:(r&p)===p){p!==0&&p===fa&&(qa=!0),u!==null&&(u=u.next={lane:0,tag:s.tag,payload:s.payload,callback:null,next:null});a:{var h=e,g=s;p=t;var _=n;switch(g.tag){case 1:if(h=g.payload,typeof h==`function`){d=h.call(_,d,p);break a}d=h;break a;case 3:h.flags=h.flags&-65537|128;case 0:if(h=g.payload,p=typeof h==`function`?h.call(_,d,p):h,p==null)break a;d=f({},d,p);break a;case 2:Ba=!0}}p=s.callback,p!==null&&(e.flags|=64,m&&(e.flags|=8192),m=i.callbacks,m===null?i.callbacks=[p]:m.push(p))}else m={lane:p,tag:s.tag,payload:s.payload,callback:s.callback,next:null},u===null?(l=u=m,c=d):u=u.next=m,o|=p;if(s=s.next,s===null){if(s=i.shared.pending,s===null)break;m=s,s=m.next,m.next=null,i.lastBaseUpdate=m,i.shared.pending=null}}while(1);u===null&&(c=d),i.baseState=c,i.firstBaseUpdate=l,i.lastBaseUpdate=u,a===null&&(i.shared.lanes=0),Kl|=o,e.lanes=o,e.memoizedState=d}}function Xa(e,t){if(typeof e!=`function`)throw Error(i(191,e));e.call(t)}function Za(e,t){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;ea?a:8;var o=E.T,s={};E.T=s,Is(e,!1,t,n);try{var c=i(),l=E.S;l!==null&&l(s,c),typeof c==`object`&&c&&typeof c.then==`function`?Fs(e,t,ga(c,r),mu(e)):Fs(e,t,r,mu(e))}catch(n){Fs(e,t,{then:function(){},status:`rejected`,reason:n},mu())}finally{D.p=a,o!==null&&s.types!==null&&(o.types=s.types),E.T=o}}function Ts(){}function Es(e,t,n,r){if(e.tag!==5)throw Error(i(476));var a=Ds(e).queue;ws(e,a,t,ue,n===null?Ts:function(){return Os(e),n(r)})}function Ds(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:ue,baseState:ue,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Lo,lastRenderedState:ue},next:null};var n={};return t.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Lo,lastRenderedState:n},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function Os(e){var t=Ds(e);t.next===null&&(t=e.alternate.memoizedState),Fs(e,t.next.queue,{},mu())}function ks(){return ta(Qf)}function As(){return Mo().memoizedState}function js(){return Mo().memoizedState}function Ms(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var n=mu();e=Ua(n);var r=Wa(t,e,n);r!==null&&(gu(r,t,n),Ga(r,t,n)),t={cache:ca()},e.payload=t;return}t=t.return}}function Ns(e,t,n){var r=mu();n={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},Ls(e)?Rs(t,n):(n=ii(e,t,n,r),n!==null&&(gu(n,e,r),zs(n,t,r)))}function Ps(e,t,n){Fs(e,t,n,mu())}function Fs(e,t,n,r){var i={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null};if(Ls(e))Rs(t,i);else{var a=e.alternate;if(e.lanes===0&&(a===null||a.lanes===0)&&(a=t.lastRenderedReducer,a!==null))try{var o=t.lastRenderedState,s=a(o,n);if(i.hasEagerState=!0,i.eagerState=s,wr(s,o))return ri(e,t,i,0),K===null&&ni(),!1}catch{}if(n=ii(e,t,i,r),n!==null)return gu(n,e,r),zs(n,t,r),!0}return!1}function Is(e,t,n,r){if(r={lane:2,revertLane:fd(),gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},Ls(e)){if(t)throw Error(i(479))}else t=ii(e,n,r,2),t!==null&&gu(t,e,2)}function Ls(e){var t=e.alternate;return e===B||t!==null&&t===B}function Rs(e,t){go=ho=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function zs(e,t,n){if(n&4194048){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,at(e,n)}}var Bs={readContext:ta,use:Fo,useCallback:So,useContext:So,useEffect:So,useImperativeHandle:So,useLayoutEffect:So,useInsertionEffect:So,useMemo:So,useReducer:So,useRef:So,useState:So,useDebugValue:So,useDeferredValue:So,useTransition:So,useSyncExternalStore:So,useId:So,useHostTransitionStatus:So,useFormState:So,useActionState:So,useOptimistic:So,useMemoCache:So,useCacheRefresh:So};Bs.useEffectEvent=So;var Vs={readContext:ta,use:Fo,useCallback:function(e,t){return jo().memoizedState=[e,t===void 0?null:t],e},useContext:ta,useEffect:ds,useImperativeHandle:function(e,t,n){n=n==null?null:n.concat([e]),ls(4194308,4,_s.bind(null,t,e),n)},useLayoutEffect:function(e,t){return ls(4194308,4,e,t)},useInsertionEffect:function(e,t){ls(4,2,e,t)},useMemo:function(e,t){var n=jo();t=t===void 0?null:t;var r=e();if(_o){M(!0);try{e()}finally{M(!1)}}return n.memoizedState=[r,t],r},useReducer:function(e,t,n){var r=jo();if(n!==void 0){var i=n(t);if(_o){M(!0);try{n(t)}finally{M(!1)}}}else i=t;return r.memoizedState=r.baseState=i,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:i},r.queue=e,e=e.dispatch=Ns.bind(null,B,e),[r.memoizedState,e]},useRef:function(e){var t=jo();return e={current:e},t.memoizedState=e},useState:function(e){e=qo(e);var t=e.queue,n=Ps.bind(null,B,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:ys,useDeferredValue:function(e,t){return Ss(jo(),e,t)},useTransition:function(){var e=qo(!1);return e=ws.bind(null,B,e.queue,!0,!1),jo().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=B,a=jo();if(z){if(n===void 0)throw Error(i(407));n=n()}else{if(n=t(),K===null)throw Error(i(349));J&127||Ho(r,t,n)}a.memoizedState=n;var o={value:n,getSnapshot:t};return a.queue=o,ds(Wo.bind(null,r,o,e),[e]),r.flags|=2048,ss(9,{destroy:void 0},Uo.bind(null,r,o,n,t),null),n},useId:function(){var e=jo(),t=K.identifierPrefix;if(z){var n=Oi,r=Di;n=(r&~(1<<32-Ue(r)-1)).toString(32)+n,t=`_`+t+`R_`+n,n=vo++,0<\/script>`,o=o.removeChild(o.firstChild);break;case`select`:o=typeof r.is==`string`?s.createElement(`select`,{is:r.is}):s.createElement(`select`),r.multiple?o.multiple=!0:r.size&&(o.size=r.size);break;default:o=typeof r.is==`string`?s.createElement(a,{is:r.is}):s.createElement(a)}}o[N]=t,o[ft]=r;a:for(s=t.child;s!==null;){if(s.tag===5||s.tag===6)o.appendChild(s.stateNode);else if(s.tag!==4&&s.tag!==27&&s.child!==null){s.child.return=s,s=s.child;continue}if(s===t)break a;for(;s.sibling===null;){if(s.return===null||s.return===t)break a;s=s.return}s.sibling.return=s.return,s=s.sibling}t.stateNode=o;a:switch($(o,a,r),a){case`button`:case`input`:case`select`:case`textarea`:r=!!r.autoFocus;break a;case`img`:r=!0;break a;default:r=!1}r&&Pc(t)}}return U(t),Fc(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,n),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==r&&Pc(t);else{if(typeof r!=`string`&&t.stateNode===null)throw Error(i(166));if(e=ge.current,Vi(t)){if(e=t.stateNode,n=t.memoizedProps,r=null,a=Pi,a!==null)switch(a.tag){case 27:case 5:r=a.memoizedProps}e[N]=t,e=!!(e.nodeValue===n||r!==null&&!0===r.suppressHydrationWarning||Nd(e.nodeValue,n)),e||Ri(t,!0)}else e=Bd(e).createTextNode(r),e[N]=t,t.stateNode=e}return U(t),null;case 31:if(n=t.memoizedState,e===null||e.memoizedState!==null){if(r=Vi(t),n!==null){if(e===null){if(!r)throw Error(i(318));if(e=t.memoizedState,e=e===null?null:e.dehydrated,!e)throw Error(i(557));e[N]=t}else Hi(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;U(t),e=!1}else n=Ui(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?(lo(t),t):(lo(t),null);if(t.flags&128)throw Error(i(558))}return U(t),null;case 13:if(r=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(a=Vi(t),r!==null&&r.dehydrated!==null){if(e===null){if(!a)throw Error(i(318));if(a=t.memoizedState,a=a===null?null:a.dehydrated,!a)throw Error(i(317));a[N]=t}else Hi(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;U(t),a=!1}else a=Ui(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=a),a=!0;if(!a)return t.flags&256?(lo(t),t):(lo(t),null)}return lo(t),t.flags&128?(t.lanes=n,t):(n=r!==null,e=e!==null&&e.memoizedState!==null,n&&(r=t.child,a=null,r.alternate!==null&&r.alternate.memoizedState!==null&&r.alternate.memoizedState.cachePool!==null&&(a=r.alternate.memoizedState.cachePool.pool),o=null,r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(o=r.memoizedState.cachePool.pool),o!==a&&(r.flags|=2048)),n!==e&&n&&(t.child.flags|=8192),Lc(t,t.updateQueue),U(t),null);case 4:return ye(),e===null&&Cd(t.stateNode.containerInfo),U(t),null;case 10:return Yi(t.type),U(t),null;case 19:if(pe(uo),r=t.memoizedState,r===null)return U(t),null;if(a=(t.flags&128)!=0,o=r.rendering,o===null)if(a)Rc(r,!1);else{if(Gl!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(o=fo(e),o!==null){for(t.flags|=128,Rc(r,!1),e=o.updateQueue,t.updateQueue=e,Lc(t,e),t.subtreeFlags=0,e=n,n=t.child;n!==null;)fi(n,e),n=n.sibling;return k(uo,uo.current&1|2),z&&ki(t,r.treeForkCount),t.child}e=e.sibling}r.tail!==null&&Pe()>nu&&(t.flags|=128,a=!0,Rc(r,!1),t.lanes=4194304)}else{if(!a)if(e=fo(o),e!==null){if(t.flags|=128,a=!0,e=e.updateQueue,t.updateQueue=e,Lc(t,e),Rc(r,!0),r.tail===null&&r.tailMode===`hidden`&&!o.alternate&&!z)return U(t),null}else 2*Pe()-r.renderingStartTime>nu&&n!==536870912&&(t.flags|=128,a=!0,Rc(r,!1),t.lanes=4194304);r.isBackwards?(o.sibling=t.child,t.child=o):(e=r.last,e===null?t.child=o:e.sibling=o,r.last=o)}return r.tail===null?(U(t),null):(e=r.tail,r.rendering=e,r.tail=e.sibling,r.renderingStartTime=Pe(),e.sibling=null,n=uo.current,k(uo,a?n&1|2:n&1),z&&ki(t,r.treeForkCount),e);case 22:case 23:return lo(t),no(),r=t.memoizedState!==null,e===null?r&&(t.flags|=8192):e.memoizedState!==null!==r&&(t.flags|=8192),r?n&536870912&&!(t.flags&128)&&(U(t),t.subtreeFlags&6&&(t.flags|=8192)):U(t),n=t.updateQueue,n!==null&&Lc(t,n.retryQueue),n=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),r=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(r=t.memoizedState.cachePool.pool),r!==n&&(t.flags|=2048),e!==null&&pe(va),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),Yi(sa),U(t),null;case 25:return null;case 30:return null}throw Error(i(156,t.tag))}function Bc(e,t){switch(Mi(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Yi(sa),ye(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return xe(t),null;case 31:if(t.memoizedState!==null){if(lo(t),t.alternate===null)throw Error(i(340));Hi()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(lo(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(i(340));Hi()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return pe(uo),null;case 4:return ye(),null;case 10:return Yi(t.type),null;case 22:case 23:return lo(t),no(),e!==null&&pe(va),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return Yi(sa),null;case 25:return null;default:return null}}function Vc(e,t){switch(Mi(t),t.tag){case 3:Yi(sa),ye();break;case 26:case 27:case 5:xe(t);break;case 4:ye();break;case 31:t.memoizedState!==null&&lo(t);break;case 13:lo(t);break;case 19:pe(uo);break;case 10:Yi(t.type);break;case 22:case 23:lo(t),no(),e!==null&&pe(va);break;case 24:Yi(sa)}}function Hc(e,t){try{var n=t.updateQueue,r=n===null?null:n.lastEffect;if(r!==null){var i=r.next;n=i;do{if((n.tag&e)===e){r=void 0;var a=n.create,o=n.inst;r=a(),o.destroy=r}n=n.next}while(n!==i)}}catch(e){X(t,t.return,e)}}function Uc(e,t,n){try{var r=t.updateQueue,i=r===null?null:r.lastEffect;if(i!==null){var a=i.next;r=a;do{if((r.tag&e)===e){var o=r.inst,s=o.destroy;if(s!==void 0){o.destroy=void 0,i=t;var c=n,l=s;try{l()}catch(e){X(i,c,e)}}}r=r.next}while(r!==a)}}catch(e){X(t,t.return,e)}}function Wc(e){var t=e.updateQueue;if(t!==null){var n=e.stateNode;try{Za(t,n)}catch(t){X(e,e.return,t)}}}function Gc(e,t,n){n.props=Js(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(n){X(e,t,n)}}function Kc(e,t){try{var n=e.ref;if(n!==null){switch(e.tag){case 26:case 27:case 5:var r=e.stateNode;break;case 30:r=e.stateNode;break;default:r=e.stateNode}typeof n==`function`?e.refCleanup=n(r):n.current=r}}catch(n){X(e,t,n)}}function qc(e,t){var n=e.ref,r=e.refCleanup;if(n!==null)if(typeof r==`function`)try{r()}catch(n){X(e,t,n)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof n==`function`)try{n(null)}catch(n){X(e,t,n)}else n.current=null}function Jc(e){var t=e.type,n=e.memoizedProps,r=e.stateNode;try{a:switch(t){case`button`:case`input`:case`select`:case`textarea`:n.autoFocus&&r.focus();break a;case`img`:n.src?r.src=n.src:n.srcSet&&(r.srcset=n.srcSet)}}catch(t){X(e,e.return,t)}}function Yc(e,t,n){try{var r=e.stateNode;Fd(r,e.type,n,t),r[ft]=t}catch(t){X(e,e.return,t)}}function Xc(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&Zd(e.type)||e.tag===4}function Zc(e){a:for(;;){for(;e.sibling===null;){if(e.return===null||Xc(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.tag===27&&Zd(e.type)||e.flags&2||e.child===null||e.tag===4)continue a;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Qc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?(n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n).insertBefore(e,t):(t=n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n,t.appendChild(e),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=tn));else if(r!==4&&(r===27&&Zd(e.type)&&(n=e.stateNode,t=null),e=e.child,e!==null))for(Qc(e,t,n),e=e.sibling;e!==null;)Qc(e,t,n),e=e.sibling}function $c(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(r===27&&Zd(e.type)&&(n=e.stateNode),e=e.child,e!==null))for($c(e,t,n),e=e.sibling;e!==null;)$c(e,t,n),e=e.sibling}function el(e){var t=e.stateNode,n=e.memoizedProps;try{for(var r=e.type,i=t.attributes;i.length;)t.removeAttributeNode(i[0]);$(t,r,n),t[N]=e,t[ft]=n}catch(t){X(e,e.return,t)}}var tl=!1,nl=!1,rl=!1,il=typeof WeakSet==`function`?WeakSet:Set,al=null;function ol(e,t){if(e=e.containerInfo,Rd=sp,e=kr(e),Ar(e)){if(`selectionStart`in e)var n={start:e.selectionStart,end:e.selectionEnd};else a:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var a=r.anchorOffset,o=r.focusNode;r=r.focusOffset;try{n.nodeType,o.nodeType}catch{n=null;break a}var s=0,c=-1,l=-1,u=0,d=0,f=e,p=null;b:for(;;){for(var m;f!==n||a!==0&&f.nodeType!==3||(c=s+a),f!==o||r!==0&&f.nodeType!==3||(l=s+r),f.nodeType===3&&(s+=f.nodeValue.length),(m=f.firstChild)!==null;)p=f,f=m;for(;;){if(f===e)break b;if(p===n&&++u===a&&(c=s),p===o&&++d===r&&(l=s),(m=f.nextSibling)!==null)break;f=p,p=f.parentNode}f=m}n=c===-1||l===-1?null:{start:c,end:l}}else n=null}n||={start:0,end:0}}else n=null;for(zd={focusedElem:e,selectionRange:n},sp=!1,al=t;al!==null;)if(t=al,e=t.child,t.subtreeFlags&1028&&e!==null)e.return=t,al=e;else for(;al!==null;){switch(t=al,o=t.alternate,e=t.flags,t.tag){case 0:if(e&4&&(e=t.updateQueue,e=e===null?null:e.events,e!==null))for(n=0;n title`))),$(o,r,n),o[N]=e,Ct(o),r=o;break a;case`link`:var s=Vf(`link`,`href`,a).get(r+(n.href||``));if(s){for(var c=0;cg&&(o=g,g=h,h=o);var _=Dr(s,h),v=Dr(s,g);if(_&&v&&(p.rangeCount!==1||p.anchorNode!==_.node||p.anchorOffset!==_.offset||p.focusNode!==v.node||p.focusOffset!==v.offset)){var y=d.createRange();y.setStart(_.node,_.offset),p.removeAllRanges(),h>g?(p.addRange(y),p.extend(v.node,v.offset)):(y.setEnd(v.node,v.offset),p.addRange(y))}}}}for(d=[],p=s;p=p.parentNode;)p.nodeType===1&&d.push({element:p,left:p.scrollLeft,top:p.scrollTop});for(typeof s.focus==`function`&&s.focus(),s=0;sn?32:n,E.T=null,n=uu,uu=null;var o=ou,s=cu;if(au=0,su=ou=null,cu=0,G&6)throw Error(i(331));var c=G;if(G|=4,Fl(o.current),Dl(o,o.current,s,n),G=c,ad(0,!1),He&&typeof He.onPostCommitFiberRoot==`function`)try{He.onPostCommitFiberRoot(Ve,o)}catch{}return!0}finally{D.p=a,E.T=r,Hu(e,t)}}function Gu(e,t,n){t=yi(n,t),t=ec(e.stateNode,t,2),e=Wa(e,t,2),e!==null&&(nt(e,2),id(e))}function X(e,t,n){if(e.tag===3)Gu(e,e,n);else for(;t!==null;){if(t.tag===3){Gu(t,e,n);break}else if(t.tag===1){var r=t.stateNode;if(typeof t.type.getDerivedStateFromError==`function`||typeof r.componentDidCatch==`function`&&(iu===null||!iu.has(r))){e=yi(n,e),n=tc(2),r=Wa(t,n,2),r!==null&&(nc(n,r,t,e),nt(r,2),id(r));break}}t=t.return}}function Ku(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new zl;var i=new Set;r.set(t,i)}else i=r.get(t),i===void 0&&(i=new Set,r.set(t,i));i.has(n)||(Ul=!0,i.add(n),e=qu.bind(null,e,t,n),t.then(e,e))}function qu(e,t,n){var r=e.pingCache;r!==null&&r.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,K===e&&(J&n)===n&&(Gl===4||Gl===3&&(J&62914560)===J&&300>Pe()-eu?!(G&2)&&Cu(e,0):Jl|=n,Xl===J&&(Xl=0)),id(e)}function Ju(e,t){t===0&&(t=et()),e=L(e,t),e!==null&&(nt(e,t),id(e))}function Yu(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),Ju(e,n)}function Xu(e,t){var n=0;switch(e.tag){case 31:case 13:var r=e.stateNode,a=e.memoizedState;a!==null&&(n=a.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(i(314))}r!==null&&r.delete(t),Ju(e,n)}function Zu(e,t){return Ae(e,t)}var Qu=null,$u=null,ed=!1,td=!1,nd=!1,rd=0;function id(e){e!==$u&&e.next===null&&($u===null?Qu=$u=e:$u=$u.next=e),td=!0,ed||(ed=!0,dd())}function ad(e,t){if(!nd&&td){nd=!0;do for(var n=!1,r=Qu;r!==null;){if(!t)if(e!==0){var i=r.pendingLanes;if(i===0)var a=0;else{var o=r.suspendedLanes,s=r.pingedLanes;a=(1<<31-Ue(42|e)+1)-1,a&=i&~(o&~s),a=a&201326741?a&201326741|1:a?a|2:0}a!==0&&(n=!0,ud(r,a))}else a=J,a=Ze(r,r===K?a:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),!(a&3)||Qe(r,a)||(n=!0,ud(r,a));r=r.next}while(n);nd=!1}}function od(){sd()}function sd(){td=ed=!1;var e=0;rd!==0&&Gd()&&(e=rd);for(var t=Pe(),n=null,r=Qu;r!==null;){var i=r.next,a=cd(r,t);a===0?(r.next=null,n===null?Qu=i:n.next=i,i===null&&($u=n)):(n=r,(e!==0||a&3)&&(td=!0)),r=i}au!==0&&au!==5||ad(e,!1),rd!==0&&(rd=0)}function cd(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,i=e.expirationTimes,a=e.pendingLanes&-62914561;0s)break;var u=c.transferSize,d=c.initiatorType;u&&Id(d)&&(c=c.responseEnd,o+=u*(c`u`?null:document;function xf(e,t,n){var r=bf;if(r&&typeof t==`string`&&t){var i=Vt(t);i=`link[rel="`+e+`"][href="`+i+`"]`,typeof n==`string`&&(i+=`[crossorigin="`+n+`"]`),hf.has(i)||(hf.add(i),e={rel:e,crossOrigin:n,href:t},r.querySelector(i)===null&&(t=r.createElement(`link`),$(t,`link`,e),Ct(t),r.head.appendChild(t)))}}function Sf(e){_f.D(e),xf(`dns-prefetch`,e,null)}function Cf(e,t){_f.C(e,t),xf(`preconnect`,e,t)}function wf(e,t,n){_f.L(e,t,n);var r=bf;if(r&&e&&t){var i=`link[rel="preload"][as="`+Vt(t)+`"]`;t===`image`&&n&&n.imageSrcSet?(i+=`[imagesrcset="`+Vt(n.imageSrcSet)+`"]`,typeof n.imageSizes==`string`&&(i+=`[imagesizes="`+Vt(n.imageSizes)+`"]`)):i+=`[href="`+Vt(e)+`"]`;var a=i;switch(t){case`style`:a=Af(e);break;case`script`:a=Pf(e)}mf.has(a)||(e=f({rel:`preload`,href:t===`image`&&n&&n.imageSrcSet?void 0:e,as:t},n),mf.set(a,e),r.querySelector(i)!==null||t===`style`&&r.querySelector(jf(a))||t===`script`&&r.querySelector(Ff(a))||(t=r.createElement(`link`),$(t,`link`,e),Ct(t),r.head.appendChild(t)))}}function Tf(e,t){_f.m(e,t);var n=bf;if(n&&e){var r=t&&typeof t.as==`string`?t.as:`script`,i=`link[rel="modulepreload"][as="`+Vt(r)+`"][href="`+Vt(e)+`"]`,a=i;switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:a=Pf(e)}if(!mf.has(a)&&(e=f({rel:`modulepreload`,href:e},t),mf.set(a,e),n.querySelector(i)===null)){switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:if(n.querySelector(Ff(a)))return}r=n.createElement(`link`),$(r,`link`,e),Ct(r),n.head.appendChild(r)}}}function Ef(e,t,n){_f.S(e,t,n);var r=bf;if(r&&e){var i=St(r).hoistableStyles,a=Af(e);t||=`default`;var o=i.get(a);if(!o){var s={loading:0,preload:null};if(o=r.querySelector(jf(a)))s.loading=5;else{e=f({rel:`stylesheet`,href:e,"data-precedence":t},n),(n=mf.get(a))&&Rf(e,n);var c=o=r.createElement(`link`);Ct(c),$(c,`link`,e),c._p=new Promise(function(e,t){c.onload=e,c.onerror=t}),c.addEventListener(`load`,function(){s.loading|=1}),c.addEventListener(`error`,function(){s.loading|=2}),s.loading|=4,Lf(o,t,r)}o={type:`stylesheet`,instance:o,count:1,state:s},i.set(a,o)}}}function Df(e,t){_f.X(e,t);var n=bf;if(n&&e){var r=St(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=f({src:e,async:!0},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),Ct(a),$(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Of(e,t){_f.M(e,t);var n=bf;if(n&&e){var r=St(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=f({src:e,async:!0,type:`module`},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),Ct(a),$(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function kf(e,t,n,r){var a=(a=ge.current)?gf(a):null;if(!a)throw Error(i(446));switch(e){case`meta`:case`title`:return null;case`style`:return typeof n.precedence==`string`&&typeof n.href==`string`?(t=Af(n.href),n=St(a).hoistableStyles,r=n.get(t),r||(r={type:`style`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};case`link`:if(n.rel===`stylesheet`&&typeof n.href==`string`&&typeof n.precedence==`string`){e=Af(n.href);var o=St(a).hoistableStyles,s=o.get(e);if(s||(a=a.ownerDocument||a,s={type:`stylesheet`,instance:null,count:0,state:{loading:0,preload:null}},o.set(e,s),(o=a.querySelector(jf(e)))&&!o._p&&(s.instance=o,s.state.loading=5),mf.has(e)||(n={rel:`preload`,as:`style`,href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},mf.set(e,n),o||Nf(a,e,n,s.state))),t&&r===null)throw Error(i(528,``));return s}if(t&&r!==null)throw Error(i(529,``));return null;case`script`:return t=n.async,n=n.src,typeof n==`string`&&t&&typeof t!=`function`&&typeof t!=`symbol`?(t=Pf(n),n=St(a).hoistableScripts,r=n.get(t),r||(r={type:`script`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};default:throw Error(i(444,e))}}function Af(e){return`href="`+Vt(e)+`"`}function jf(e){return`link[rel="stylesheet"][`+e+`]`}function Mf(e){return f({},e,{"data-precedence":e.precedence,precedence:null})}function Nf(e,t,n,r){e.querySelector(`link[rel="preload"][as="style"][`+t+`]`)?r.loading=1:(t=e.createElement(`link`),r.preload=t,t.addEventListener(`load`,function(){return r.loading|=1}),t.addEventListener(`error`,function(){return r.loading|=2}),$(t,`link`,n),Ct(t),e.head.appendChild(t))}function Pf(e){return`[src="`+Vt(e)+`"]`}function Ff(e){return`script[async]`+e}function If(e,t,n){if(t.count++,t.instance===null)switch(t.type){case`style`:var r=e.querySelector(`style[data-href~="`+Vt(n.href)+`"]`);if(r)return t.instance=r,Ct(r),r;var a=f({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement(`style`),Ct(r),$(r,`style`,a),Lf(r,n.precedence,e),t.instance=r;case`stylesheet`:a=Af(n.href);var o=e.querySelector(jf(a));if(o)return t.state.loading|=4,t.instance=o,Ct(o),o;r=Mf(n),(a=mf.get(a))&&Rf(r,a),o=(e.ownerDocument||e).createElement(`link`),Ct(o);var s=o;return s._p=new Promise(function(e,t){s.onload=e,s.onerror=t}),$(o,`link`,r),t.state.loading|=4,Lf(o,n.precedence,e),t.instance=o;case`script`:return o=Pf(n.src),(a=e.querySelector(Ff(o)))?(t.instance=a,Ct(a),a):(r=n,(a=mf.get(o))&&(r=f({},n),zf(r,a)),e=e.ownerDocument||e,a=e.createElement(`script`),Ct(a),$(a,`link`,r),e.head.appendChild(a),t.instance=a);case`void`:return null;default:throw Error(i(443,t.type))}else t.type===`stylesheet`&&!(t.state.loading&4)&&(r=t.instance,t.state.loading|=4,Lf(r,n.precedence,e));return t.instance}function Lf(e,t,n){for(var r=n.querySelectorAll(`link[rel="stylesheet"][data-precedence],style[data-precedence]`),i=r.length?r[r.length-1]:null,a=i,o=0;o title`):null)}function Uf(e,t,n){if(n===1||t.itemProp!=null)return!1;switch(e){case`meta`:case`title`:return!0;case`style`:if(typeof t.precedence!=`string`||typeof t.href!=`string`||t.href===``)break;return!0;case`link`:if(typeof t.rel!=`string`||typeof t.href!=`string`||t.href===``||t.onLoad||t.onError)break;switch(t.rel){case`stylesheet`:return e=t.disabled,typeof t.precedence==`string`&&e==null;default:return!0}case`script`:if(t.async&&typeof t.async!=`function`&&typeof t.async!=`symbol`&&!t.onLoad&&!t.onError&&t.src&&typeof t.src==`string`)return!0}return!1}function Wf(e){return!(e.type===`stylesheet`&&!(e.state.loading&3))}function Gf(e,t,n,r){if(n.type===`stylesheet`&&(typeof r.media!=`string`||!1!==matchMedia(r.media).matches)&&!(n.state.loading&4)){if(n.instance===null){var i=Af(r.href),a=t.querySelector(jf(i));if(a){t=a._p,typeof t==`object`&&t&&typeof t.then==`function`&&(e.count++,e=Jf.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=a,Ct(a);return}a=t.ownerDocument||t,r=Mf(r),(i=mf.get(i))&&Rf(r,i),a=a.createElement(`link`),Ct(a);var o=a;o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),$(a,`link`,r),n.instance=a}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&!(n.state.loading&3)&&(e.count++,n=Jf.bind(e),t.addEventListener(`load`,n),t.addEventListener(`error`,n))}}var Kf=0;function qf(e,t){return e.stylesheets&&e.count===0&&Xf(e,e.stylesheets),0Kf?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(i)}}:null}function Jf(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Xf(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var Yf=null;function Xf(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,Yf=new Map,t.forEach(Zf,e),Yf=null,Jf.call(e))}function Zf(e,t){if(!(t.state.loading&4)){var n=Yf.get(e);if(n)var r=n.get(null);else{n=new Map,Yf.set(e,n);for(var i=e.querySelectorAll(`link[data-precedence],style[data-precedence]`),a=0;a{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=v()})),b=u(p(),1),x=u(y(),1),S=s((e=>{var t=Symbol.for(`react.transitional.element`);function n(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.jsx=n,e.jsxs=n})),C=s(((e,t)=>{t.exports=S()})),w=(0,b.createContext)({});function ee(e){let t=(0,b.useRef)(null);return t.current===null&&(t.current=e()),t.current}var te=typeof window<`u`?b.useLayoutEffect:b.useEffect,ne=(0,b.createContext)(null);function T(e,t){e.indexOf(t)===-1&&e.push(t)}function re(e,t){let n=e.indexOf(t);n>-1&&e.splice(n,1)}var ie=(e,t,n)=>n>t?t:n/^-?(?:\d+(?:\.\d+)?|\.\d+)$/u.test(e),se=e=>typeof e==`object`&&!!e,ce=e=>/^0[^.\s]+$/u.test(e);function le(e){let t;return()=>(t===void 0&&(t=e()),t)}var E=e=>e,D=(...e)=>e.reduce((e,t)=>n=>t(e(n))),ue=(e,t,n)=>{let r=t-e;return r?(n-e)/r:1},de=class{constructor(){this.subscriptions=[]}add(e){return T(this.subscriptions,e),()=>re(this.subscriptions,e)}notify(e,t,n){let r=this.subscriptions.length;if(r)if(r===1)this.subscriptions[0](e,t,n);else for(let i=0;ie*1e3,O=e=>e/1e3,pe=(e,t)=>t?1e3/t*e:0,k=(e,t,n)=>(((1-3*n+3*t)*e+(3*n-6*t))*e+3*t)*e,me=1e-7,he=12;function ge(e,t,n,r,i){let a,o,s=0;do o=t+(n-t)/2,a=k(o,r,i)-e,a>0?n=o:t=o;while(Math.abs(a)>me&&++sge(t,0,1,e,n);return e=>e===0||e===1?e:k(i(e),t,r)}var ve=e=>t=>t<=.5?e(2*t)/2:(2-e(2*(1-t)))/2,ye=e=>t=>1-e(1-t),be=_e(.33,1.53,.69,.99),xe=ye(be),Se=ve(xe),Ce=e=>e>=1?1:(e*=2)<1?.5*xe(e):.5*(2-2**(-10*(e-1))),we=e=>1-Math.sin(Math.acos(e)),Te=ye(we),Ee=ve(we),De=_e(.42,0,1,1),Oe=_e(0,0,.58,1),ke=_e(.42,0,.58,1),Ae=e=>Array.isArray(e)&&typeof e[0]!=`number`,je=e=>Array.isArray(e)&&typeof e[0]==`number`,Me={linear:E,easeIn:De,easeInOut:ke,easeOut:Oe,circIn:we,circInOut:Ee,circOut:Te,backIn:xe,backInOut:Se,backOut:be,anticipate:Ce},Ne=e=>typeof e==`string`,Pe=e=>{if(je(e)){e.length;let[t,n,r,i]=e;return _e(t,n,r,i)}else if(Ne(e))return Me[e],`${e}`,Me[e];return e},Fe=[`setup`,`read`,`resolveKeyframes`,`preUpdate`,`update`,`preRender`,`render`,`postRender`];function Ie(e){let t=new Set,n=new Set,r=!1,i=!1,a=new WeakSet,o={delta:0,timestamp:0,isProcessing:!1};function s(t){a.has(t)&&(c.schedule(t),e()),t(o)}let c={schedule:(e,i=!1,o=!1)=>{let s=o&&r?t:n;return i&&a.add(e),s.add(e),e},cancel:e=>{n.delete(e),a.delete(e)},process:e=>{if(o=e,r){i=!0;return}r=!0;let a=t;t=n,n=a,t.forEach(s),t.clear(),r=!1,i&&(i=!1,c.process(e))}};return c}var Le=40;function Re(e,t){let n=!1,r=!0,i={delta:0,timestamp:0,isProcessing:!1},a=()=>n=!0,o=Fe.reduce((e,t)=>(e[t]=Ie(a),e),{}),{setup:s,read:c,resolveKeyframes:l,preUpdate:u,update:d,preRender:f,render:p,postRender:m}=o,h=()=>{let a=ae.useManualTiming,o=a?i.timestamp:performance.now();n=!1,a||(i.delta=r?1e3/60:Math.max(Math.min(o-i.timestamp,Le),1)),i.timestamp=o,i.isProcessing=!0,s.process(i),c.process(i),l.process(i),u.process(i),d.process(i),f.process(i),p.process(i),m.process(i),i.isProcessing=!1,n&&t&&(r=!1,e(h))},g=()=>{n=!0,r=!0,i.isProcessing||e(h)};return{schedule:Fe.reduce((e,t)=>{let r=o[t];return e[t]=(e,t=!1,i=!1)=>(n||g(),r.schedule(e,t,i)),e},{}),cancel:e=>{for(let t=0;t(Ve===void 0&&M.set(j.isProcessing||ae.useManualTiming?j.timestamp:performance.now()),Ve),set:e=>{Ve=e,queueMicrotask(He)}},Ue=e=>t=>typeof t==`string`&&t.startsWith(e),We=Ue(`--`),Ge=Ue(`var(--`),Ke=e=>Ge(e)?qe.test(e.split(`/*`)[0].trim()):!1,qe=/var\(--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)$/iu;function Je(e){return typeof e==`string`&&e.split(`/*`)[0].includes(`var(--`)}var Ye={test:e=>typeof e==`number`,parse:parseFloat,transform:e=>e},Xe={...Ye,transform:e=>ie(0,1,e)},Ze={...Ye,default:1},Qe=e=>Math.round(e*1e5)/1e5,$e=/-?(?:\d+(?:\.\d+)?|\.\d+)/gu;function et(e){return e==null}var tt=/^(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))$/iu,nt=(e,t)=>n=>!!(typeof n==`string`&&tt.test(n)&&n.startsWith(e)||t&&!et(n)&&Object.prototype.hasOwnProperty.call(n,t)),rt=(e,t,n)=>r=>{if(typeof r!=`string`)return r;let[i,a,o,s]=r.match($e);return{[e]:parseFloat(i),[t]:parseFloat(a),[n]:parseFloat(o),alpha:s===void 0?1:parseFloat(s)}},it=e=>ie(0,255,e),at={...Ye,transform:e=>Math.round(it(e))},ot={test:nt(`rgb`,`red`),parse:rt(`red`,`green`,`blue`),transform:({red:e,green:t,blue:n,alpha:r=1})=>`rgba(`+at.transform(e)+`, `+at.transform(t)+`, `+at.transform(n)+`, `+Qe(Xe.transform(r))+`)`};function st(e){let t=``,n=``,r=``,i=``;return e.length>5?(t=e.substring(1,3),n=e.substring(3,5),r=e.substring(5,7),i=e.substring(7,9)):(t=e.substring(1,2),n=e.substring(2,3),r=e.substring(3,4),i=e.substring(4,5),t+=t,n+=n,r+=r,i+=i),{red:parseInt(t,16),green:parseInt(n,16),blue:parseInt(r,16),alpha:i?parseInt(i,16)/255:1}}var ct={test:nt(`#`),parse:st,transform:ot.transform},lt=e=>({test:t=>typeof t==`string`&&t.endsWith(e)&&t.split(` `).length===1,parse:parseFloat,transform:t=>`${t}${e}`}),ut=lt(`deg`),dt=lt(`%`),N=lt(`px`),ft=lt(`vh`),pt=lt(`vw`),mt={...dt,parse:e=>dt.parse(e)/100,transform:e=>dt.transform(e*100)},ht={test:nt(`hsl`,`hue`),parse:rt(`hue`,`saturation`,`lightness`),transform:({hue:e,saturation:t,lightness:n,alpha:r=1})=>`hsla(`+Math.round(e)+`, `+dt.transform(Qe(t))+`, `+dt.transform(Qe(n))+`, `+Qe(Xe.transform(r))+`)`},P={test:e=>ot.test(e)||ct.test(e)||ht.test(e),parse:e=>ot.test(e)?ot.parse(e):ht.test(e)?ht.parse(e):ct.parse(e),transform:e=>typeof e==`string`?e:e.hasOwnProperty(`red`)?ot.transform(e):ht.transform(e),getAnimatableNone:e=>{let t=P.parse(e);return t.alpha=0,P.transform(t)}},gt=/(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))/giu;function _t(e){return isNaN(e)&&typeof e==`string`&&(e.match($e)?.length||0)+(e.match(gt)?.length||0)>0}var vt=`number`,yt=`color`,bt=`var`,xt=`var(`,St="${}",Ct=/var\s*\(\s*--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)|#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\)|-?(?:\d+(?:\.\d+)?|\.\d+)/giu;function wt(e){let t=e.toString(),n=[],r={color:[],number:[],var:[]},i=[],a=0;return{values:n,split:t.replace(Ct,e=>(P.test(e)?(r.color.push(a),i.push(yt),n.push(P.parse(e))):e.startsWith(xt)?(r.var.push(a),i.push(bt),n.push(e)):(r.number.push(a),i.push(vt),n.push(parseFloat(e))),++a,St)).split(St),indexes:r,types:i}}function Tt(e){return wt(e).values}function Et({split:e,types:t}){let n=e.length;return r=>{let i=``;for(let a=0;atypeof e==`number`?0:P.test(e)?P.getAnimatableNone(e):e,kt=(e,t)=>typeof e==`number`?t?.trim().endsWith(`/`)?e:0:Ot(e);function At(e){let t=wt(e);return Et(t)(t.values.map((e,n)=>kt(e,t.split[n])))}var jt={test:_t,parse:Tt,createTransformer:Dt,getAnimatableNone:At};function Mt(e,t,n){return n<0&&(n+=1),n>1&&--n,n<1/6?e+(t-e)*6*n:n<1/2?t:n<2/3?e+(t-e)*(2/3-n)*6:e}function Nt({hue:e,saturation:t,lightness:n,alpha:r}){e/=360,t/=100,n/=100;let i=0,a=0,o=0;if(!t)i=a=o=n;else{let r=n<.5?n*(1+t):n+t-n*t,s=2*n-r;i=Mt(s,r,e+1/3),a=Mt(s,r,e),o=Mt(s,r,e-1/3)}return{red:Math.round(i*255),green:Math.round(a*255),blue:Math.round(o*255),alpha:r}}function Pt(e,t){return n=>n>0?t:e}var F=(e,t,n)=>e+(t-e)*n,Ft=(e,t,n)=>{let r=e*e,i=n*(t*t-r)+r;return i<0?0:Math.sqrt(i)},It=[ct,ot,ht],Lt=e=>It.find(t=>t.test(e));function Rt(e){let t=Lt(e);if(`${e}`,!t)return!1;let n=t.parse(e);return t===ht&&(n=Nt(n)),n}var zt=(e,t)=>{let n=Rt(e),r=Rt(t);if(!n||!r)return Pt(e,t);let i={...n};return e=>(i.red=Ft(n.red,r.red,e),i.green=Ft(n.green,r.green,e),i.blue=Ft(n.blue,r.blue,e),i.alpha=F(n.alpha,r.alpha,e),ot.transform(i))},Bt=new Set([`none`,`hidden`]);function Vt(e,t){return Bt.has(e)?n=>n<=0?e:t:n=>n>=1?t:e}function Ht(e,t){return n=>F(e,t,n)}function Ut(e){return typeof e==`number`?Ht:typeof e==`string`?Ke(e)?Pt:P.test(e)?zt:qt:Array.isArray(e)?Wt:typeof e==`object`?P.test(e)?zt:Gt:Pt}function Wt(e,t){let n=[...e],r=n.length,i=e.map((e,n)=>Ut(e)(e,t[n]));return e=>{for(let t=0;t{for(let t in r)n[t]=r[t](e);return n}}function Kt(e,t){let n=[],r={color:0,var:0,number:0};for(let i=0;i{let n=jt.createTransformer(t),r=wt(e),i=wt(t);return r.indexes.var.length===i.indexes.var.length&&r.indexes.color.length===i.indexes.color.length&&r.indexes.number.length>=i.indexes.number.length?Bt.has(e)&&!i.values.length||Bt.has(t)&&!r.values.length?Vt(e,t):D(Wt(Kt(r,i),i.values),n):(`${e}${t}`,Pt(e,t))};function Jt(e,t,n){return typeof e==`number`&&typeof t==`number`&&typeof n==`number`?F(e,t,n):Ut(e)(e,t)}var Yt=e=>{let t=({timestamp:t})=>e(t);return{start:(e=!0)=>A.update(t,e),stop:()=>ze(t),now:()=>j.isProcessing?j.timestamp:M.now()}},Xt=(e,t,n=10)=>{let r=``,i=Math.max(Math.round(t/n),2);for(let t=0;t=2e4?1/0:t}function $t(e,t=100,n){let r=n({...e,keyframes:[0,t]}),i=Math.min(Qt(r),Zt);return{type:`keyframes`,ease:e=>r.next(i*e).value/t,duration:O(i)}}var I={stiffness:100,damping:10,mass:1,velocity:0,duration:800,bounce:.3,visualDuration:.3,restSpeed:{granular:.01,default:2},restDelta:{granular:.005,default:.5},minDuration:.01,maxDuration:10,minDamping:.05,maxDamping:1};function en(e,t){return e*Math.sqrt(1-t*t)}var tn=12;function nn(e,t,n){let r=n;for(let n=1;n{let r=t*o,i=r*e,a=r-n,s=en(t,o),c=Math.exp(-i);return rn-a/s*c},a=t=>{let r=t*o*e,a=r*n+n,s=o**2*t**2*e,c=Math.exp(-r),l=en(t**2,o);return(-i(t)+rn>0?-1:1)*((a-s)*c)/l}):(i=t=>-.001+Math.exp(-t*e)*((t-n)*e+1),a=t=>Math.exp(-t*e)*((n-t)*(e*e)));let s=5/e,c=nn(i,a,s);if(e=fe(e),isNaN(c))return{stiffness:I.stiffness,damping:I.damping,duration:e};{let t=c**2*r;return{stiffness:t,damping:o*2*Math.sqrt(r*t),duration:e}}}var on=[`duration`,`bounce`],sn=[`stiffness`,`damping`,`mass`];function cn(e,t){return t.some(t=>e[t]!==void 0)}function ln(e){let t={velocity:I.velocity,stiffness:I.stiffness,damping:I.damping,mass:I.mass,isResolvedFromDuration:!1,...e};if(!cn(e,sn)&&cn(e,on))if(t.velocity=0,e.visualDuration){let n=e.visualDuration,r=2*Math.PI/(n*1.2),i=r*r,a=2*ie(.05,1,1-(e.bounce||0))*Math.sqrt(i);t={...t,mass:I.mass,stiffness:i,damping:a}}else{let n=an({...e,velocity:0});t={...t,...n,mass:I.mass},t.isResolvedFromDuration=!0}return t}function un(e=I.visualDuration,t=I.bounce){let n=typeof e==`object`?e:{visualDuration:e,keyframes:[0,1],bounce:t},{restSpeed:r,restDelta:i}=n,a=n.keyframes[0],o=n.keyframes[n.keyframes.length-1],s={done:!1,value:a},{stiffness:c,damping:l,mass:u,duration:d,velocity:f,isResolvedFromDuration:p}=ln({...n,velocity:-O(n.velocity||0)}),m=f||0,h=l/(2*Math.sqrt(c*u)),g=o-a,_=O(Math.sqrt(c/u)),v=Math.abs(g)<5;r||=v?I.restSpeed.granular:I.restSpeed.default,i||=v?I.restDelta.granular:I.restDelta.default;let y,b,x,S,C,w;if(h<1)x=en(_,h),S=(m+h*_*g)/x,y=e=>{let t=Math.exp(-h*_*e);return o-t*(S*Math.sin(x*e)+g*Math.cos(x*e))},C=h*_*S+g*x,w=h*_*g-S*x,b=e=>Math.exp(-h*_*e)*(C*Math.sin(x*e)+w*Math.cos(x*e));else if(h===1){y=e=>o-Math.exp(-_*e)*(g+(m+_*g)*e);let e=m+_*g;b=t=>Math.exp(-_*t)*(_*e*t-m)}else{let e=_*Math.sqrt(h*h-1);y=t=>{let n=Math.exp(-h*_*t),r=Math.min(e*t,300);return o-n*((m+h*_*g)*Math.sinh(r)+e*g*Math.cosh(r))/e};let t=(m+h*_*g)/e,n=h*_*t-g*e,r=h*_*g-t*e;b=t=>{let i=Math.exp(-h*_*t),a=Math.min(e*t,300);return i*(n*Math.sinh(a)+r*Math.cosh(a))}}let ee={calculatedDuration:p&&d||null,velocity:e=>fe(b(e)),next:e=>{if(!p&&h<1){let t=Math.exp(-h*_*e),n=Math.sin(x*e),a=Math.cos(x*e),c=o-t*(S*n+g*a),l=fe(t*(C*n+w*a));return s.done=Math.abs(l)<=r&&Math.abs(o-c)<=i,s.value=s.done?o:c,s}let t=y(e);if(p)s.done=e>=d;else{let n=fe(b(e));s.done=Math.abs(n)<=r&&Math.abs(o-t)<=i}return s.value=s.done?o:t,s},toString:()=>{let e=Math.min(Qt(ee),Zt),t=Xt(t=>ee.next(e*t).value,e,30);return e+`ms `+t},toTransition:()=>{}};return ee}un.applyToOptions=e=>{let t=$t(e,100,un);return e.ease=t.ease,e.duration=fe(t.duration),e.type=`keyframes`,e};var dn=5;function fn(e,t,n){let r=Math.max(t-dn,0);return pe(n-e(r),t-r)}function pn({keyframes:e,velocity:t=0,power:n=.8,timeConstant:r=325,bounceDamping:i=10,bounceStiffness:a=500,modifyTarget:o,min:s,max:c,restDelta:l=.5,restSpeed:u}){let d=e[0],f={done:!1,value:d},p=e=>s!==void 0&&ec,m=e=>s===void 0?c:c===void 0||Math.abs(s-e)-h*Math.exp(-e/r),y=e=>_+v(e),b=e=>{let t=v(e),n=y(e);f.done=Math.abs(t)<=l,f.value=f.done?_:n},x,S,C=e=>{p(f.value)&&(x=e,S=un({keyframes:[f.value,m(f.value)],velocity:fn(y,e,f.value),damping:i,stiffness:a,restDelta:l,restSpeed:u}))};return C(0),{calculatedDuration:null,next:e=>{let t=!1;return!S&&x===void 0&&(t=!0,b(e),C(e)),x!==void 0&&e>=x?S.next(e-x):(!t&&b(e),f)}}}function mn(e,t,n){let r=[],i=n||ae.mix||Jt,a=e.length-1;for(let n=0;nt[0];if(a===2&&t[0]===t[1])return()=>t[1];let o=e[0]===e[1];e[0]>e[a-1]&&(e=[...e].reverse(),t=[...t].reverse());let s=mn(t,r,i),c=s.length,l=n=>{if(o&&n1)for(;rl(ie(e[0],e[a-1],t)):l}function gn(e,t){let n=e[e.length-1];for(let r=1;r<=t;r++){let i=ue(0,t,r);e.push(F(n,1,i))}}function _n(e){let t=[0];return gn(t,e.length-1),t}function vn(e,t){return e.map(e=>e*t)}function yn(e,t){return e.map(()=>t||ke).splice(0,e.length-1)}function bn({duration:e=300,keyframes:t,times:n,ease:r=`easeInOut`}){let i=Ae(r)?r.map(Pe):Pe(r),a={done:!1,value:t[0]},o=hn(vn(n&&n.length===t.length?n:_n(t),e),t,{ease:Array.isArray(i)?i:yn(t,i)});return{calculatedDuration:e,next:t=>(a.value=o(t),a.done=t>=e,a)}}var xn=e=>e!==null;function Sn(e,{repeat:t,repeatType:n=`loop`},r,i=1){let a=e.filter(xn),o=i<0||t&&n!==`loop`&&t%2==1?0:a.length-1;return!o||r===void 0?a[o]:r}var Cn={decay:pn,inertia:pn,tween:bn,keyframes:bn,spring:un};function wn(e){typeof e.type==`string`&&(e.type=Cn[e.type])}var Tn=class{constructor(){this.updateFinished()}get finished(){return this._finished}updateFinished(){this._finished=new Promise(e=>{this.resolve=e})}notifyFinished(){this.resolve()}then(e,t){return this.finished.then(e,t)}},En=e=>e/100,Dn=class extends Tn{constructor(e){super(),this.state=`idle`,this.startTime=null,this.isStopped=!1,this.currentTime=0,this.holdTime=null,this.playbackSpeed=1,this.delayState={done:!1,value:void 0},this.stop=()=>{let{motionValue:e}=this.options;e&&e.updatedAt!==M.now()&&this.tick(M.now()),this.isStopped=!0,this.state!==`idle`&&(this.teardown(),this.options.onStop?.())},this.options=e,this.initAnimation(),this.play(),e.autoplay===!1&&this.pause()}initAnimation(){let{options:e}=this;wn(e);let{type:t=bn,repeat:n=0,repeatDelay:r=0,repeatType:i,velocity:a=0}=e,{keyframes:o}=e,s=t||bn;s!==bn&&typeof o[0]!=`number`&&(this.mixKeyframes=D(En,Jt(o[0],o[1])),o=[0,100]);let c=s({...e,keyframes:o});i===`mirror`&&(this.mirroredGenerator=s({...e,keyframes:[...o].reverse(),velocity:-a})),c.calculatedDuration===null&&(c.calculatedDuration=Qt(c));let{calculatedDuration:l}=c;this.calculatedDuration=l,this.resolvedDuration=l+r,this.totalDuration=this.resolvedDuration*(n+1)-r,this.generator=c}updateTime(e){let t=Math.round(e-this.startTime)*this.playbackSpeed;this.holdTime===null?this.currentTime=t:this.currentTime=this.holdTime}tick(e,t=!1){let{generator:n,totalDuration:r,mixKeyframes:i,mirroredGenerator:a,resolvedDuration:o,calculatedDuration:s}=this;if(this.startTime===null)return n.next(0);let{delay:c=0,keyframes:l,repeat:u,repeatType:d,repeatDelay:f,type:p,onUpdate:m,finalKeyframe:h}=this.options;this.speed>0?this.startTime=Math.min(this.startTime,e):this.speed<0&&(this.startTime=Math.min(e-r/this.speed,this.startTime)),t?this.currentTime=e:this.updateTime(e);let g=this.currentTime-c*(this.playbackSpeed>=0?1:-1),_=this.playbackSpeed>=0?g<0:g>r;this.currentTime=Math.max(g,0),this.state===`finished`&&this.holdTime===null&&(this.currentTime=r);let v=this.currentTime,y=n;if(u){let e=Math.min(this.currentTime,r)/o,t=Math.floor(e),n=e%1;!n&&e>=1&&(n=1),n===1&&t--,t=Math.min(t,u+1),t%2&&(d===`reverse`?(n=1-n,f&&(n-=f/o)):d===`mirror`&&(y=a)),v=ie(0,1,n)*o}let b;_?(this.delayState.value=l[0],b=this.delayState):b=y.next(v),i&&!_&&(b.value=i(b.value));let{done:x}=b;!_&&s!==null&&(x=this.playbackSpeed>=0?this.currentTime>=r:this.currentTime<=0);let S=this.holdTime===null&&(this.state===`finished`||this.state===`running`&&x);return S&&p!==pn&&(b.value=Sn(l,this.options,h,this.speed)),m&&m(b.value),S&&this.finish(),b}then(e,t){return this.finished.then(e,t)}get duration(){return O(this.calculatedDuration)}get iterationDuration(){let{delay:e=0}=this.options||{};return this.duration+O(e)}get time(){return O(this.currentTime)}set time(e){e=fe(e),this.currentTime=e,this.startTime===null||this.holdTime!==null||this.playbackSpeed===0?this.holdTime=e:this.driver&&(this.startTime=this.driver.now()-e/this.playbackSpeed),this.driver?this.driver.start(!1):(this.startTime=0,this.state=`paused`,this.holdTime=e,this.tick(e))}getGeneratorVelocity(){let e=this.currentTime;if(e<=0)return this.options.velocity||0;if(this.generator.velocity)return this.generator.velocity(e);let t=this.generator.next(e).value;return fn(e=>this.generator.next(e).value,e,t)}get speed(){return this.playbackSpeed}set speed(e){let t=this.playbackSpeed!==e;t&&this.driver&&this.updateTime(M.now()),this.playbackSpeed=e,t&&this.driver&&(this.time=O(this.currentTime))}play(){if(this.isStopped)return;let{driver:e=Yt,startTime:t}=this.options;this.driver||=e(e=>this.tick(e)),this.options.onPlay?.();let n=this.driver.now();this.state===`finished`?(this.updateFinished(),this.startTime=n):this.holdTime===null?this.startTime||=t??n:this.startTime=n-this.holdTime,this.state===`finished`&&this.speed<0&&(this.startTime+=this.calculatedDuration),this.holdTime=null,this.state=`running`,this.driver.start()}pause(){this.state=`paused`,this.updateTime(M.now()),this.holdTime=this.currentTime}complete(){this.state!==`running`&&this.play(),this.state=`finished`,this.holdTime=null}finish(){this.notifyFinished(),this.teardown(),this.state=`finished`,this.options.onComplete?.()}cancel(){this.holdTime=null,this.startTime=0,this.tick(0),this.teardown(),this.options.onCancel?.()}teardown(){this.state=`idle`,this.stopDriver(),this.startTime=this.holdTime=null}stopDriver(){this.driver&&=(this.driver.stop(),void 0)}sample(e){return this.startTime=0,this.tick(e,!0)}attachTimeline(e){return this.options.allowFlatten&&(this.options.type=`keyframes`,this.options.ease=`linear`,this.initAnimation()),this.driver?.stop(),e.observe(this)}};function On(e){for(let t=1;te*180/Math.PI,An=e=>Mn(kn(Math.atan2(e[1],e[0]))),jn={x:4,y:5,translateX:4,translateY:5,scaleX:0,scaleY:3,scale:e=>(Math.abs(e[0])+Math.abs(e[3]))/2,rotate:An,rotateZ:An,skewX:e=>kn(Math.atan(e[1])),skewY:e=>kn(Math.atan(e[2])),skew:e=>(Math.abs(e[1])+Math.abs(e[2]))/2},Mn=e=>(e%=360,e<0&&(e+=360),e),Nn=An,Pn=e=>Math.sqrt(e[0]*e[0]+e[1]*e[1]),Fn=e=>Math.sqrt(e[4]*e[4]+e[5]*e[5]),In={x:12,y:13,z:14,translateX:12,translateY:13,translateZ:14,scaleX:Pn,scaleY:Fn,scale:e=>(Pn(e)+Fn(e))/2,rotateX:e=>Mn(kn(Math.atan2(e[6],e[5]))),rotateY:e=>Mn(kn(Math.atan2(-e[2],e[0]))),rotateZ:Nn,rotate:Nn,skewX:e=>kn(Math.atan(e[4])),skewY:e=>kn(Math.atan(e[1])),skew:e=>(Math.abs(e[1])+Math.abs(e[4]))/2};function Ln(e){return+!!e.includes(`scale`)}function Rn(e,t){if(!e||e===`none`)return Ln(t);let n=e.match(/^matrix3d\(([-\d.e\s,]+)\)$/u),r,i;if(n)r=In,i=n;else{let t=e.match(/^matrix\(([-\d.e\s,]+)\)$/u);r=jn,i=t}if(!i)return Ln(t);let a=r[t],o=i[1].split(`,`).map(Bn);return typeof a==`function`?a(o):o[a]}var zn=(e,t)=>{let{transform:n=`none`}=getComputedStyle(e);return Rn(n,t)};function Bn(e){return parseFloat(e.trim())}var Vn=[`transformPerspective`,`x`,`y`,`z`,`translateX`,`translateY`,`translateZ`,`scale`,`scaleX`,`scaleY`,`rotate`,`rotateX`,`rotateY`,`rotateZ`,`skew`,`skewX`,`skewY`],Hn=new Set([...Vn,`pathRotation`]),Un=e=>e===Ye||e===N,Wn=new Set([`x`,`y`,`z`]),Gn=Vn.filter(e=>!Wn.has(e));function Kn(e){let t=[];return Gn.forEach(n=>{let r=e.getValue(n);r!==void 0&&(t.push([n,r.get()]),r.set(+!!n.startsWith(`scale`)))}),t}var qn={width:({x:e},{paddingLeft:t=`0`,paddingRight:n=`0`,boxSizing:r})=>{let i=e.max-e.min;return r===`border-box`?i:i-parseFloat(t)-parseFloat(n)},height:({y:e},{paddingTop:t=`0`,paddingBottom:n=`0`,boxSizing:r})=>{let i=e.max-e.min;return r===`border-box`?i:i-parseFloat(t)-parseFloat(n)},top:(e,{top:t})=>parseFloat(t),left:(e,{left:t})=>parseFloat(t),bottom:({y:e},{top:t})=>parseFloat(t)+(e.max-e.min),right:({x:e},{left:t})=>parseFloat(t)+(e.max-e.min),x:(e,{transform:t})=>Rn(t,`x`),y:(e,{transform:t})=>Rn(t,`y`)};qn.translateX=qn.x,qn.translateY=qn.y;var Jn=new Set,Yn=!1,Xn=!1,Zn=!1;function Qn(){if(Xn){let e=Array.from(Jn).filter(e=>e.needsMeasurement),t=new Set(e.map(e=>e.element)),n=new Map;t.forEach(e=>{let t=Kn(e);t.length&&(n.set(e,t),e.render())}),e.forEach(e=>e.measureInitialState()),t.forEach(e=>{e.render();let t=n.get(e);t&&t.forEach(([t,n])=>{e.getValue(t)?.set(n)})}),e.forEach(e=>e.measureEndState()),e.forEach(e=>{e.suspendedScrollY!==void 0&&window.scrollTo(0,e.suspendedScrollY)})}Xn=!1,Yn=!1,Jn.forEach(e=>e.complete(Zn)),Jn.clear()}function $n(){Jn.forEach(e=>{e.readKeyframes(),e.needsMeasurement&&(Xn=!0)})}function er(){Zn=!0,$n(),Qn(),Zn=!1}var tr=class{constructor(e,t,n,r,i,a=!1){this.state=`pending`,this.isAsync=!1,this.needsMeasurement=!1,this.unresolvedKeyframes=[...e],this.onComplete=t,this.name=n,this.motionValue=r,this.element=i,this.isAsync=a}scheduleResolve(){this.state=`scheduled`,this.isAsync?(Jn.add(this),Yn||(Yn=!0,A.read($n),A.resolveKeyframes(Qn))):(this.readKeyframes(),this.complete())}readKeyframes(){let{unresolvedKeyframes:e,name:t,element:n,motionValue:r}=this;if(e[0]===null){let i=r?.get(),a=e[e.length-1];if(i!==void 0)e[0]=i;else if(n&&t){let r=n.readValue(t,a);r!=null&&(e[0]=r)}e[0]===void 0&&(e[0]=a),r&&i===void 0&&r.set(e[0])}On(e)}setFinalKeyframe(){}measureInitialState(){}renderEndStyles(){}measureEndState(){}complete(e=!1){this.state=`complete`,this.onComplete(this.unresolvedKeyframes,this.finalKeyframe,e),Jn.delete(this)}cancel(){this.state===`scheduled`&&(Jn.delete(this),this.state=`pending`)}resume(){this.state===`pending`&&this.scheduleResolve()}},nr=e=>e.startsWith(`--`);function rr(e,t,n){nr(t)?e.style.setProperty(t,n):e.style[t]=n}var ir={};function ar(e,t){let n=le(e);return()=>ir[t]??n()}var or=ar(()=>window.ScrollTimeline!==void 0,`scrollTimeline`),sr=ar(()=>{try{document.createElement(`div`).animate({opacity:0},{easing:`linear(0, 1)`})}catch{return!1}return!0},`linearEasing`),cr=([e,t,n,r])=>`cubic-bezier(${e}, ${t}, ${n}, ${r})`,lr={linear:`linear`,ease:`ease`,easeIn:`ease-in`,easeOut:`ease-out`,easeInOut:`ease-in-out`,circIn:cr([0,.65,.55,1]),circOut:cr([.55,0,1,.45]),backIn:cr([.31,.01,.66,-.59]),backOut:cr([.33,1.53,.69,.99])};function ur(e,t){if(e)return typeof e==`function`?sr()?Xt(e,t):`ease-out`:je(e)?cr(e):Array.isArray(e)?e.map(e=>ur(e,t)||lr.easeOut):lr[e]}function dr(e,t,n,{delay:r=0,duration:i=300,repeat:a=0,repeatType:o=`loop`,ease:s=`easeOut`,times:c}={},l=void 0){let u={[t]:n};c&&(u.offset=c);let d=ur(s,i);Array.isArray(d)&&(u.easing=d);let f={delay:r,duration:i,easing:Array.isArray(d)?`linear`:d,fill:`both`,iterations:a+1,direction:o===`reverse`?`alternate`:`normal`};return l&&(f.pseudoElement=l),e.animate(u,f)}function fr(e){return typeof e==`function`&&`applyToOptions`in e}function pr({type:e,...t}){return fr(e)&&sr()?e.applyToOptions(t):(t.duration??=300,t.ease??=`easeOut`,t)}var mr=class extends Tn{constructor(e){if(super(),this.finishedTime=null,this.isStopped=!1,this.manualStartTime=null,!e)return;let{element:t,name:n,keyframes:r,pseudoElement:i,allowFlatten:a=!1,finalKeyframe:o,onComplete:s}=e;this.isPseudoElement=!!i,this.allowFlatten=a,this.options=e,e.type;let c=pr(e);this.animation=dr(t,n,r,c,i),c.autoplay===!1&&this.animation.pause(),this.animation.onfinish=()=>{if(this.finishedTime=this.time,!i){let e=Sn(r,this.options,o,this.speed);this.updateMotionValue&&this.updateMotionValue(e),rr(t,n,e),this.animation.cancel()}s?.(),this.notifyFinished()}}play(){this.isStopped||(this.manualStartTime=null,this.animation.play(),this.state===`finished`&&this.updateFinished())}pause(){this.animation.pause()}complete(){this.animation.finish?.()}cancel(){try{this.animation.cancel()}catch{}}stop(){if(this.isStopped)return;this.isStopped=!0;let{state:e}=this;e===`idle`||e===`finished`||(this.updateMotionValue?this.updateMotionValue():this.commitStyles(),this.isPseudoElement||this.cancel())}commitStyles(){let e=this.options?.element;!this.isPseudoElement&&e?.isConnected&&this.animation.commitStyles?.()}get duration(){let e=this.animation.effect?.getComputedTiming?.().duration||0;return O(Number(e))}get iterationDuration(){let{delay:e=0}=this.options||{};return this.duration+O(e)}get time(){return O(Number(this.animation.currentTime)||0)}set time(e){let t=this.finishedTime!==null;this.manualStartTime=null,this.finishedTime=null,this.animation.currentTime=fe(e),t&&this.animation.pause()}get speed(){return this.animation.playbackRate}set speed(e){e<0&&(this.finishedTime=null),this.animation.playbackRate=e}get state(){return this.finishedTime===null?this.animation.playState:`finished`}get startTime(){return this.manualStartTime??Number(this.animation.startTime)}set startTime(e){this.manualStartTime=this.animation.startTime=e}attachTimeline({timeline:e,rangeStart:t,rangeEnd:n,observe:r}){return this.allowFlatten&&this.animation.effect?.updateTiming({easing:`linear`}),this.animation.onfinish=null,e&&or()?(this.animation.timeline=e,t&&(this.animation.rangeStart=t),n&&(this.animation.rangeEnd=n),E):r(this)}},hr={anticipate:Ce,backInOut:Se,circInOut:Ee};function gr(e){return e in hr}function _r(e){typeof e.ease==`string`&&gr(e.ease)&&(e.ease=hr[e.ease])}var vr=10,yr=class extends mr{constructor(e){_r(e),wn(e),super(e),e.startTime!==void 0&&e.autoplay!==!1&&(this.startTime=e.startTime),this.options=e}updateMotionValue(e){let{motionValue:t,onUpdate:n,onComplete:r,element:i,...a}=this.options;if(!t)return;if(e!==void 0){t.set(e);return}let o=new Dn({...a,autoplay:!1}),s=Math.max(vr,M.now()-this.startTime),c=ie(0,vr,s-vr),l=o.sample(s).value,{name:u}=this.options;i&&u&&rr(i,u,l),t.setWithVelocity(o.sample(Math.max(0,s-c)).value,l,c),o.stop()}},br=(e,t)=>t!==`zIndex`&&!!(typeof e==`number`||Array.isArray(e)||typeof e==`string`&&(jt.test(e)||e===`0`)&&!e.startsWith(`url(`));function xr(e){let t=e[0];if(e.length===1)return!0;for(let n=0;nObject.hasOwnProperty.call(Element.prototype,`animate`));function kr(e){let{motionValue:t,name:n,repeatDelay:r,repeatType:i,damping:a,type:o,keyframes:s}=e;if(!(t?.owner?.current instanceof HTMLElement))return!1;let{onUpdate:c,transformTemplate:l}=t.owner.getProps();return Or()&&n&&(wr.has(n)||Dr.has(n)&&Er(s))&&(n!==`transform`||!l)&&!c&&!r&&i!==`mirror`&&a!==0&&o!==`inertia`}var Ar=40,jr=class extends Tn{constructor({autoplay:e=!0,delay:t=0,type:n=`keyframes`,repeat:r=0,repeatDelay:i=0,repeatType:a=`loop`,keyframes:o,name:s,motionValue:c,element:l,...u}){super(),this.stop=()=>{this._animation&&(this._animation.stop(),this.stopTimeline?.()),this.keyframeResolver?.cancel()},this.createdAt=M.now();let d={autoplay:e,delay:t,type:n,repeat:r,repeatDelay:i,repeatType:a,name:s,motionValue:c,element:l,...u},f=l?.KeyframeResolver||tr;this.keyframeResolver=new f(o,(e,t,n)=>this.onKeyframesResolved(e,t,d,!n),s,c,l),this.keyframeResolver?.scheduleResolve()}onKeyframesResolved(e,t,n,r){this.keyframeResolver=void 0;let{name:i,type:a,velocity:o,delay:s,isHandoff:c,onUpdate:l}=n;this.resolvedAt=M.now();let u=!0;Sr(e,i,a,o)||(u=!1,(ae.instantAnimations||!s)&&l?.(Sn(e,n,t)),e[0]=e[e.length-1],Cr(n),n.repeat=0);let d={startTime:r?this.resolvedAt&&this.resolvedAt-this.createdAt>Ar?this.resolvedAt:this.createdAt:void 0,finalKeyframe:t,...n,keyframes:e},f=u&&!c&&kr(d),p=d.motionValue?.owner?.current,m;if(f)try{m=new yr({...d,element:p})}catch{m=new Dn(d)}else m=new Dn(d);m.finished.then(()=>{this.notifyFinished()}).catch(E),this.pendingTimeline&&=(this.stopTimeline=m.attachTimeline(this.pendingTimeline),void 0),this._animation=m}get finished(){return this._animation?this.animation.finished:this._finished}then(e,t){return this.finished.finally(e).then(()=>{})}get animation(){return this._animation||(this.keyframeResolver?.resume(),er()),this._animation}get duration(){return this.animation.duration}get iterationDuration(){return this.animation.iterationDuration}get time(){return this.animation.time}set time(e){this.animation.time=e}get speed(){return this.animation.speed}get state(){return this.animation.state}set speed(e){this.animation.speed=e}get startTime(){return this.animation.startTime}attachTimeline(e){return this._animation?this.stopTimeline=this.animation.attachTimeline(e):this.pendingTimeline=e,()=>this.stop()}play(){this.animation.play()}pause(){this.animation.pause()}complete(){this.animation.complete()}cancel(){this._animation&&this.animation.cancel(),this.keyframeResolver?.cancel()}};function Mr(e,t,n,r=0,i=1){let a=Array.from(e).sort((e,t)=>e.sortNodePosition(t)).indexOf(t),o=e.size,s=(o-1)*r;return typeof n==`function`?n(a,o):i===1?a*r:s-a*r}var Nr=30,Pr=e=>!isNaN(parseFloat(e)),Fr={current:void 0},Ir=class{constructor(e,t={}){this.canTrackVelocity=null,this.events={},this.updateAndNotify=e=>{let t=M.now();if(this.updatedAt!==t&&this.setPrevFrameValue(),this.prev=this.current,this.setCurrent(e),this.current!==this.prev&&(this.events.change?.notify(this.current),this.dependents))for(let e of this.dependents)e.dirty()},this.hasAnimated=!1,this.setCurrent(e),this.owner=t.owner}setCurrent(e){this.current=e,this.updatedAt=M.now(),this.canTrackVelocity===null&&e!==void 0&&(this.canTrackVelocity=Pr(this.current))}setPrevFrameValue(e=this.current){this.prevFrameValue=e,this.prevUpdatedAt=this.updatedAt}onChange(e){return this.on(`change`,e)}on(e,t){this.events[e]||(this.events[e]=new de);let n=this.events[e].add(t);return e===`change`?()=>{n(),A.read(()=>{this.events.change.getSize()||this.stop()})}:n}clearListeners(){for(let e in this.events)this.events[e].clear()}attach(e,t){this.passiveEffect=e,this.stopPassiveEffect=t}set(e){this.passiveEffect?this.passiveEffect(e,this.updateAndNotify):this.updateAndNotify(e)}setWithVelocity(e,t,n){this.set(t),this.prev=void 0,this.prevFrameValue=e,this.prevUpdatedAt=this.updatedAt-n}jump(e,t=!0){this.updateAndNotify(e),this.prev=e,this.prevUpdatedAt=this.prevFrameValue=void 0,t&&this.stop(),this.stopPassiveEffect&&this.stopPassiveEffect()}dirty(){this.events.change?.notify(this.current)}addDependent(e){this.dependents||=new Set,this.dependents.add(e)}removeDependent(e){this.dependents&&this.dependents.delete(e)}get(){return Fr.current&&Fr.current.push(this),this.current}getPrevious(){return this.prev}getVelocity(){let e=M.now();if(!this.canTrackVelocity||this.prevFrameValue===void 0||e-this.updatedAt>Nr)return 0;let t=Math.min(this.updatedAt-this.prevUpdatedAt,Nr);return pe(parseFloat(this.current)-parseFloat(this.prevFrameValue),t)}start(e){return this.stop(),new Promise(t=>{this.hasAnimated=!0,this.animation=e(t),this.events.animationStart&&this.events.animationStart.notify()}).then(()=>{this.events.animationComplete&&this.events.animationComplete.notify(),this.clearAnimation()})}stop(){this.animation&&(this.animation.stop(),this.events.animationCancel&&this.events.animationCancel.notify()),this.clearAnimation()}isAnimating(){return!!this.animation}clearAnimation(){delete this.animation}destroy(){this.dependents?.clear(),this.events.destroy?.notify(),this.clearListeners(),this.stop(),this.stopPassiveEffect&&this.stopPassiveEffect()}};function Lr(e,t){return new Ir(e,t)}function Rr(e,t){if(e?.inherit&&t){let{inherit:n,...r}=e;return{...t,...r}}return e}function zr(e,t){let n=e?.[t]??e?.default??e;return n===e?n:Rr(n,e)}var Br={type:`spring`,stiffness:500,damping:25,restSpeed:10},Vr=e=>({type:`spring`,stiffness:550,damping:e===0?2*Math.sqrt(550):30,restSpeed:10}),Hr={type:`keyframes`,duration:.8},Ur={type:`keyframes`,ease:[.25,.1,.35,1],duration:.3},Wr=(e,{keyframes:t})=>t.length>2?Hr:Hn.has(e)?e.startsWith(`scale`)?Vr(t[1]):Br:Ur,Gr=new Set([`when`,`delay`,`delayChildren`,`staggerChildren`,`staggerDirection`,`repeat`,`repeatType`,`repeatDelay`,`from`,`elapsed`]);function Kr(e){for(let t in e)if(!Gr.has(t))return!0;return!1}var qr=(e,t,n,r={},i,a)=>o=>{let s=zr(r,e)||{},c=s.delay||r.delay||0,{elapsed:l=0}=r;l-=fe(c);let u={keyframes:Array.isArray(n)?n:[null,n],ease:`easeOut`,velocity:t.getVelocity(),...s,delay:-l,onUpdate:e=>{t.set(e),s.onUpdate&&s.onUpdate(e)},onComplete:()=>{o(),s.onComplete&&s.onComplete()},name:e,motionValue:t,element:a?void 0:i};Kr(s)||Object.assign(u,Wr(e,u)),u.duration&&=fe(u.duration),u.repeatDelay&&=fe(u.repeatDelay),u.from!==void 0&&(u.keyframes[0]=u.from);let d=!1;if((u.type===!1||u.duration===0&&!u.repeatDelay)&&(Cr(u),u.delay===0&&(d=!0)),(ae.instantAnimations||ae.skipAnimations||i?.shouldSkipAnimations||s.skipAnimations)&&(d=!0,Cr(u),u.delay=0),u.allowFlatten=!s.type&&!s.ease,d&&!a&&t.get()!==void 0){let e=Sn(u.keyframes,s);if(e!==void 0){A.update(()=>{u.onUpdate(e),u.onComplete()});return}}return s.isSync?new Dn(u):new jr(u)},Jr=/^var\(--(?:([\w-]+)|([\w-]+), ?([a-zA-Z\d ()%#.,-]+))\)/u;function Yr(e){let t=Jr.exec(e);if(!t)return[,];let[,n,r,i]=t;return[`--${n??r}`,i]}function Xr(e,t,n=1){`${e}`;let[r,i]=Yr(e);if(!r)return;let a=window.getComputedStyle(t).getPropertyValue(r);if(a){let e=a.trim();return oe(e)?parseFloat(e):e}return Ke(i)?Xr(i,t,n+1):i}function Zr(e){let t=[{},{}];return e?.values.forEach((e,n)=>{t[0][n]=e.get(),t[1][n]=e.getVelocity()}),t}function Qr(e,t,n,r){if(typeof t==`function`){let[i,a]=Zr(r);t=t(n===void 0?e.custom:n,i,a)}if(typeof t==`string`&&(t=e.variants&&e.variants[t]),typeof t==`function`){let[i,a]=Zr(r);t=t(n===void 0?e.custom:n,i,a)}return t}function $r(e,t,n){let r=e.getProps();return Qr(r,t,n===void 0?r.custom:n,e)}var ei=new Set([`width`,`height`,`top`,`left`,`right`,`bottom`,...Vn]),ti=e=>Array.isArray(e);function ni(e,t,n){e.hasValue(t)?e.getValue(t).set(n):e.addValue(t,Lr(n))}function ri(e){return ti(e)?e[e.length-1]||0:e}function ii(e,t){let{transitionEnd:n={},transition:r={},...i}=$r(e,t)||{};i={...i,...n};for(let t in i)ni(e,t,ri(i[t]))}var L=e=>!!(e&&e.getVelocity);function ai(e){return!!(L(e)&&e.add)}function oi(e,t){let n=e.getValue(`willChange`);if(ai(n))return n.add(t);if(!n&&ae.WillChange){let n=new ae.WillChange(`auto`);e.addValue(`willChange`,n),n.add(t)}}function si(e){return e.replace(/([A-Z])/g,e=>`-${e.toLowerCase()}`)}var ci=`data-`+si(`framerAppearId`);function li(e){return e.props[ci]}function ui({protectedKeys:e,needsAnimating:t},n){let r=e.hasOwnProperty(n)&&t[n]!==!0;return t[n]=!1,r}function di(e,t,{delay:n=0,transitionOverride:r,type:i}={}){let{transition:a,transitionEnd:o,...s}=t,c=e.getDefaultTransition();a=a?Rr(a,c):c;let l=a?.reduceMotion,u=a?.skipAnimations;r&&(a=r);let d=[],f=i&&e.animationState&&e.animationState.getState()[i],p=a?.path;p&&p.animateVisualElement(e,s,a,n,d);for(let t in s){let r=e.getValue(t,e.latestValues[t]??null),i=s[t];if(i===void 0||f&&ui(f,t))continue;let o={delay:n,...zr(a||{},t)};u&&(o.skipAnimations=!0);let c=r.get();if(c!==void 0&&!r.isAnimating()&&!Array.isArray(i)&&i===c&&!o.velocity){A.update(()=>r.set(i));continue}let p=!1;if(window.MotionHandoffAnimation){let n=li(e);if(n){let e=window.MotionHandoffAnimation(n,t,A);e!==null&&(o.startTime=e,p=!0)}}oi(e,t);let m=l??e.shouldReduceMotion;r.start(qr(t,r,i,m&&ei.has(t)?{type:!1}:o,e,p));let h=r.animation;h&&d.push(h)}if(o){let t=()=>A.update(()=>{o&&ii(e,o)});d.length?Promise.all(d).then(t):t()}return d}function fi(e,t,n={}){let r=$r(e,t,n.type===`exit`?e.presenceContext?.custom:void 0),{transition:i=e.getDefaultTransition()||{}}=r||{};n.transitionOverride&&(i=n.transitionOverride);let a=r?()=>Promise.all(di(e,r,n)):()=>Promise.resolve(),o=e.variantChildren&&e.variantChildren.size?(r=0)=>{let{delayChildren:a=0,staggerChildren:o,staggerDirection:s}=i;return pi(e,t,r,a,o,s,n)}:()=>Promise.resolve(),{when:s}=i;if(s){let[e,t]=s===`beforeChildren`?[a,o]:[o,a];return e().then(()=>t())}else return Promise.all([a(),o(n.delay)])}function pi(e,t,n=0,r=0,i=0,a=1,o){let s=[];for(let c of e.variantChildren)c.notify(`AnimationStart`,t),s.push(fi(c,t,{...o,delay:n+(typeof r==`function`?0:r)+Mr(e.variantChildren,c,r,i,a)}).then(()=>c.notify(`AnimationComplete`,t)));return Promise.all(s)}function mi(e,t,n={}){e.notify(`AnimationStart`,t);let r;if(Array.isArray(t)){let i=t.map(t=>fi(e,t,n));r=Promise.all(i)}else if(typeof t==`string`)r=fi(e,t,n);else{let i=typeof t==`function`?$r(e,t,n.custom):t;r=Promise.all(di(e,i,n))}return r.then(()=>{e.notify(`AnimationComplete`,t)})}var hi={test:e=>e===`auto`,parse:e=>e},gi=e=>t=>t.test(e),_i=[Ye,N,dt,ut,pt,ft,hi],vi=e=>_i.find(gi(e));function yi(e){return typeof e==`number`?e===0:e===null||e===`none`||e===`0`||ce(e)}var bi=new Set([`brightness`,`contrast`,`saturate`,`opacity`]);function xi(e){let[t,n]=e.slice(0,-1).split(`(`);if(t===`drop-shadow`)return e;let[r]=n.match($e)||[];if(!r)return e;let i=n.replace(r,``),a=+!!bi.has(t);return r!==n&&(a*=100),t+`(`+a+i+`)`}var Si=/\b([a-z-]*)\(.*?\)/gu,Ci={...jt,getAnimatableNone:e=>{let t=e.match(Si);return t?t.map(xi).join(` `):e}},wi={...jt,getAnimatableNone:e=>{let t=jt.parse(e);return jt.createTransformer(e)(t.map(e=>typeof e==`number`?0:typeof e==`object`?{...e,alpha:1}:e))}},Ti={...Ye,transform:Math.round},Ei={borderWidth:N,borderTopWidth:N,borderRightWidth:N,borderBottomWidth:N,borderLeftWidth:N,borderRadius:N,borderTopLeftRadius:N,borderTopRightRadius:N,borderBottomRightRadius:N,borderBottomLeftRadius:N,width:N,maxWidth:N,height:N,maxHeight:N,top:N,right:N,bottom:N,left:N,inset:N,insetBlock:N,insetBlockStart:N,insetBlockEnd:N,insetInline:N,insetInlineStart:N,insetInlineEnd:N,padding:N,paddingTop:N,paddingRight:N,paddingBottom:N,paddingLeft:N,paddingBlock:N,paddingBlockStart:N,paddingBlockEnd:N,paddingInline:N,paddingInlineStart:N,paddingInlineEnd:N,margin:N,marginTop:N,marginRight:N,marginBottom:N,marginLeft:N,marginBlock:N,marginBlockStart:N,marginBlockEnd:N,marginInline:N,marginInlineStart:N,marginInlineEnd:N,fontSize:N,backgroundPositionX:N,backgroundPositionY:N,rotate:ut,pathRotation:ut,rotateX:ut,rotateY:ut,rotateZ:ut,scale:Ze,scaleX:Ze,scaleY:Ze,scaleZ:Ze,skew:ut,skewX:ut,skewY:ut,distance:N,translateX:N,translateY:N,translateZ:N,x:N,y:N,z:N,perspective:N,transformPerspective:N,opacity:Xe,originX:mt,originY:mt,originZ:N,zIndex:Ti,fillOpacity:Xe,strokeOpacity:Xe,numOctaves:Ti},Di={...Ei,color:P,backgroundColor:P,outlineColor:P,fill:P,stroke:P,borderColor:P,borderTopColor:P,borderRightColor:P,borderBottomColor:P,borderLeftColor:P,filter:Ci,WebkitFilter:Ci,mask:wi,WebkitMask:wi},Oi=e=>Di[e],ki=new Set([Ci,wi]);function Ai(e,t){let n=Oi(e);return ki.has(n)||(n=jt),n.getAnimatableNone?n.getAnimatableNone(t):void 0}var ji=new Set([`auto`,`none`,`0`]);function Mi(e,t,n){let r=0,i;for(;r{e.getValue(t).set(n)}),this.resolveNoneKeyframes()}},Pi=[`borderTopLeftRadius`,`borderTopRightRadius`,`borderBottomRightRadius`,`borderBottomLeftRadius`];function R(e,t,n){if(e==null)return[];if(e instanceof EventTarget)return[e];if(typeof e==`string`){let r=document;t&&(r=t.current);let i=n?.[e]??r.querySelectorAll(e);return i?Array.from(i):[]}return Array.from(e).filter(e=>e!=null)}var z=(e,t)=>t&&typeof e==`number`?t.transform(e):e;function Fi(e){return se(e)&&`offsetHeight`in e&&!(`ownerSVGElement`in e)}var{schedule:Ii,cancel:Li}=Re(queueMicrotask,!1),Ri={x:!1,y:!1};function zi(){return Ri.x||Ri.y}function Bi(e){return e===`x`||e===`y`?Ri[e]?null:(Ri[e]=!0,()=>{Ri[e]=!1}):Ri.x||Ri.y?null:(Ri.x=Ri.y=!0,()=>{Ri.x=Ri.y=!1})}function Vi(e,t){let n=R(e),r=new AbortController;return[n,{passive:!0,...t,signal:r.signal},()=>r.abort()]}function Hi(e){return!(e.pointerType===`touch`||zi())}function Ui(e,t,n={}){let[r,i,a]=Vi(e,n);return r.forEach(e=>{let n=!1,r=!1,a,o=()=>{e.removeEventListener(`pointerleave`,u)},s=e=>{a&&=(a(e),void 0),o()},c=e=>{n=!1,window.removeEventListener(`pointerup`,c),window.removeEventListener(`pointercancel`,c),r&&(r=!1,s(e))},l=()=>{n=!0,window.addEventListener(`pointerup`,c,i),window.addEventListener(`pointercancel`,c,i)},u=e=>{if(e.pointerType!==`touch`){if(n){r=!0;return}s(e)}};e.addEventListener(`pointerenter`,n=>{if(!Hi(n))return;r=!1;let o=t(e,n);typeof o==`function`&&(a=o,e.addEventListener(`pointerleave`,u,i))},i),e.addEventListener(`pointerdown`,l,i)}),a}var Wi=(e,t)=>t?e===t||Wi(e,t.parentElement):!1,Gi=e=>e.pointerType===`mouse`?typeof e.button!=`number`||e.button<=0:e.isPrimary!==!1,Ki=new Set([`BUTTON`,`INPUT`,`SELECT`,`TEXTAREA`,`A`]);function qi(e){return Ki.has(e.tagName)||e.isContentEditable===!0}var Ji=new Set([`INPUT`,`SELECT`,`TEXTAREA`]);function Yi(e){return Ji.has(e.tagName)||e.isContentEditable===!0}var Xi=new WeakSet;function Zi(e){return t=>{t.key===`Enter`&&e(t)}}function Qi(e,t){e.dispatchEvent(new PointerEvent(`pointer`+t,{isPrimary:!0,bubbles:!0}))}var $i=(e,t)=>{let n=e.currentTarget;if(!n)return;let r=Zi(()=>{if(Xi.has(n))return;Qi(n,`down`);let e=Zi(()=>{Qi(n,`up`)});n.addEventListener(`keyup`,e,t),n.addEventListener(`blur`,()=>Qi(n,`cancel`),t)});n.addEventListener(`keydown`,r,t),n.addEventListener(`blur`,()=>n.removeEventListener(`keydown`,r),t)};function ea(e){return Gi(e)&&!zi()}var ta=new WeakSet;function na(e,t,n={}){let[r,i,a]=Vi(e,n),o=e=>{let r=e.currentTarget;if(!ea(e)||ta.has(e))return;Xi.add(r),n.stopPropagation&&ta.add(e);let a=t(r,e),o={...i,capture:!0},s=(e,t)=>{window.removeEventListener(`pointerup`,c,o),window.removeEventListener(`pointercancel`,l,o),Xi.has(r)&&Xi.delete(r),ea(e)&&typeof a==`function`&&a(e,{success:t})},c=e=>{s(e,r===window||r===document||n.useGlobalTarget||Wi(r,e.target))},l=e=>{s(e,!1)};window.addEventListener(`pointerup`,c,o),window.addEventListener(`pointercancel`,l,o)};return r.forEach(e=>{(n.useGlobalTarget?window:e).addEventListener(`pointerdown`,o,i),Fi(e)&&(e.addEventListener(`focus`,e=>$i(e,i)),!qi(e)&&!e.hasAttribute(`tabindex`)&&(e.tabIndex=0))}),a}function ra(e){return se(e)&&`ownerSVGElement`in e}var ia=new WeakMap,aa,oa=(e,t,n)=>(r,i)=>i&&i[0]?i[0][e+`Size`]:ra(r)&&`getBBox`in r?r.getBBox()[t]:r[n],sa=oa(`inline`,`width`,`offsetWidth`),ca=oa(`block`,`height`,`offsetHeight`);function la({target:e,borderBoxSize:t}){ia.get(e)?.forEach(n=>{n(e,{get width(){return sa(e,t)},get height(){return ca(e,t)}})})}function ua(e){e.forEach(la)}function da(){typeof ResizeObserver>`u`||(aa=new ResizeObserver(ua))}function fa(e,t){aa||da();let n=R(e);return n.forEach(e=>{let n=ia.get(e);n||(n=new Set,ia.set(e,n)),n.add(t),aa?.observe(e)}),()=>{n.forEach(e=>{let n=ia.get(e);n?.delete(t),n?.size||aa?.unobserve(e)})}}var pa=new Set,ma;function ha(){ma=()=>{let e={get width(){return window.innerWidth},get height(){return window.innerHeight}};pa.forEach(t=>t(e))},window.addEventListener(`resize`,ma)}function ga(e){return pa.add(e),ma||ha(),()=>{pa.delete(e),!pa.size&&typeof ma==`function`&&(window.removeEventListener(`resize`,ma),ma=void 0)}}function _a(e,t){return typeof e==`function`?ga(e):fa(e,t)}var va={value:null,addProjectionMetrics:null};function ya(e){return ra(e)&&e.tagName===`svg`}var ba=[..._i,P,jt],xa=e=>ba.find(gi(e)),Sa=()=>({translate:0,scale:1,origin:0,originPoint:0}),Ca=()=>({x:Sa(),y:Sa()}),wa=()=>({min:0,max:0}),Ta=()=>({x:wa(),y:wa()}),Ea=new WeakMap;function Da(e){return typeof e==`object`&&!!e&&typeof e.start==`function`}function Oa(e){return typeof e==`string`||Array.isArray(e)}var ka=[`animate`,`whileInView`,`whileFocus`,`whileHover`,`whileTap`,`whileDrag`,`exit`],Aa=[`initial`,...ka];function ja(e){return Da(e.animate)||Aa.some(t=>Oa(e[t]))}function Ma(e){return!!(ja(e)||e.variants)}function Na(e,t,n){for(let r in t){let i=t[r],a=n[r];if(L(i))e.addValue(r,i);else if(L(a))e.addValue(r,Lr(i,{owner:e}));else if(a!==i)if(e.hasValue(r)){let t=e.getValue(r);t.liveStyle===!0?t.jump(i):t.hasAnimated||t.set(i)}else{let t=e.getStaticValue(r);e.addValue(r,Lr(t===void 0?i:t,{owner:e}))}}for(let r in n)t[r]===void 0&&e.removeValue(r);return t}var Pa={current:null},Fa={current:!1},Ia=typeof window<`u`;function La(){if(Fa.current=!0,Ia)if(window.matchMedia){let e=window.matchMedia(`(prefers-reduced-motion)`),t=()=>Pa.current=e.matches;e.addEventListener(`change`,t),t()}else Pa.current=!1}var Ra=[`AnimationStart`,`AnimationComplete`,`Update`,`BeforeLayoutMeasure`,`LayoutMeasure`,`LayoutAnimationStart`,`LayoutAnimationComplete`],za={};function Ba(e){za=e}function Va(){return za}var Ha=class{scrapeMotionValuesFromProps(e,t,n){return{}}constructor({parent:e,props:t,presenceContext:n,reducedMotionConfig:r,skipAnimations:i,blockInitialAnimation:a,visualState:o},s={}){this.current=null,this.children=new Set,this.isVariantNode=!1,this.isControllingVariants=!1,this.shouldReduceMotion=null,this.shouldSkipAnimations=!1,this.values=new Map,this.KeyframeResolver=tr,this.features={},this.valueSubscriptions=new Map,this.prevMotionValues={},this.hasBeenMounted=!1,this.events={},this.propEventSubscriptions={},this.notifyUpdate=()=>this.notify(`Update`,this.latestValues),this.render=()=>{this.current&&(this.triggerBuild(),this.renderInstance(this.current,this.renderState,this.props.style,this.projection))},this.renderScheduledAt=0,this.scheduleRender=()=>{let e=M.now();this.renderScheduledAtthis.bindToMotionValue(t,e)),this.reducedMotionConfig===`never`?this.shouldReduceMotion=!1:this.reducedMotionConfig===`always`?this.shouldReduceMotion=!0:(Fa.current||La(),this.shouldReduceMotion=Pa.current),this.shouldSkipAnimations=this.skipAnimationsConfig??!1,this.parent?.addChild(this),this.update(this.props,this.presenceContext),this.hasBeenMounted=!0}unmount(){this.projection&&this.projection.unmount(),ze(this.notifyUpdate),ze(this.render),this.valueSubscriptions.forEach(e=>e()),this.valueSubscriptions.clear(),this.removeFromVariantTree&&this.removeFromVariantTree(),this.parent?.removeChild(this);for(let e in this.events)this.events[e].clear();for(let e in this.features){let t=this.features[e];t&&(t.unmount(),t.isMounted=!1)}this.current=null}addChild(e){this.children.add(e),this.enteringChildren??=new Set,this.enteringChildren.add(e)}removeChild(e){this.children.delete(e),this.enteringChildren&&this.enteringChildren.delete(e)}bindToMotionValue(e,t){if(this.valueSubscriptions.has(e)&&this.valueSubscriptions.get(e)(),t.accelerate&&wr.has(e)&&this.current instanceof HTMLElement){let{factory:n,keyframes:r,times:i,ease:a,duration:o}=t.accelerate,s=new mr({element:this.current,name:e,keyframes:r,times:i,ease:a,duration:fe(o)}),c=n(s);this.valueSubscriptions.set(e,()=>{c(),s.cancel()});return}let n=Hn.has(e);n&&this.onBindTransform&&this.onBindTransform();let r=t.on(`change`,t=>{this.latestValues[e]=t,this.props.onUpdate&&A.preRender(this.notifyUpdate),n&&this.projection&&(this.projection.isTransformDirty=!0),this.scheduleRender()}),i;typeof window<`u`&&window.MotionCheckAppearSync&&(i=window.MotionCheckAppearSync(this,e,t)),this.valueSubscriptions.set(e,()=>{r(),i&&i()})}sortNodePosition(e){return!this.current||!this.sortInstanceNodePosition||this.type!==e.type?0:this.sortInstanceNodePosition(this.current,e.current)}updateFeatures(){let e=`animation`;for(e in za){let t=za[e];if(!t)continue;let{isEnabled:n,Feature:r}=t;if(!this.features[e]&&r&&n(this.props)&&(this.features[e]=new r(this)),this.features[e]){let t=this.features[e];t.isMounted?t.update():(t.mount(),t.isMounted=!0)}}}triggerBuild(){this.build(this.renderState,this.latestValues,this.props)}measureViewportBox(){return this.current?this.measureInstanceViewportBox(this.current,this.props):Ta()}getStaticValue(e){return this.latestValues[e]}setStaticValue(e,t){this.latestValues[e]=t}update(e,t){(e.transformTemplate||this.props.transformTemplate)&&this.scheduleRender(),this.prevProps=this.props,this.props=e,this.prevPresenceContext=this.presenceContext,this.presenceContext=t;for(let t=0;tt.variantChildren.delete(e)}addValue(e,t){let n=this.values.get(e);t!==n&&(n&&this.removeValue(e),this.bindToMotionValue(e,t),this.values.set(e,t),this.latestValues[e]=t.get())}removeValue(e){this.values.delete(e);let t=this.valueSubscriptions.get(e);t&&(t(),this.valueSubscriptions.delete(e)),delete this.latestValues[e],this.removeValueFromRenderState(e,this.renderState)}hasValue(e){return this.values.has(e)}getValue(e,t){if(this.props.values&&this.props.values[e])return this.props.values[e];let n=this.values.get(e);return n===void 0&&t!==void 0&&(n=Lr(t===null?void 0:t,{owner:this}),this.addValue(e,n)),n}readValue(e,t){let n=this.latestValues[e]!==void 0||!this.current?this.latestValues[e]:this.getBaseTargetFromProps(this.props,e)??this.readValueFromInstance(this.current,e,this.options);return n!=null&&(typeof n==`string`&&(oe(n)||ce(n))?n=parseFloat(n):!xa(n)&&jt.test(t)&&(n=Ai(e,t)),this.setBaseTarget(e,L(n)?n.get():n)),L(n)?n.get():n}setBaseTarget(e,t){this.baseTarget[e]=t}getBaseTarget(e){let{initial:t}=this.props,n;if(typeof t==`string`||typeof t==`object`){let r=Qr(this.props,t,this.presenceContext?.custom);r&&(n=r[e])}if(t&&n!==void 0)return n;let r=this.getBaseTargetFromProps(this.props,e);return r!==void 0&&!L(r)?r:this.initialValues[e]!==void 0&&n===void 0?void 0:this.baseTarget[e]}on(e,t){return this.events[e]||(this.events[e]=new de),this.events[e].add(t)}notify(e,...t){this.events[e]&&this.events[e].notify(...t)}scheduleRenderMicrotask(){Ii.render(this.render)}},Ua=class extends Ha{constructor(){super(...arguments),this.KeyframeResolver=Ni}sortInstanceNodePosition(e,t){return e.compareDocumentPosition(t)&2?1:-1}getBaseTargetFromProps(e,t){let n=e.style;return n?n[t]:void 0}removeValueFromRenderState(e,{vars:t,style:n}){delete t[e],delete n[e]}handleChildMotionValue(){this.childSubscription&&(this.childSubscription(),delete this.childSubscription);let{children:e}=this.props;L(e)&&(this.childSubscription=e.on(`change`,e=>{this.current&&(this.current.textContent=`${e}`)}))}},Wa=class{constructor(e){this.isMounted=!1,this.node=e}update(){}};function Ga({top:e,left:t,right:n,bottom:r}){return{x:{min:t,max:n},y:{min:e,max:r}}}function Ka({x:e,y:t}){return{top:t.min,right:e.max,bottom:t.max,left:e.min}}function qa(e,t){if(!t)return e;let n=t({x:e.left,y:e.top}),r=t({x:e.right,y:e.bottom});return{top:n.y,left:n.x,bottom:r.y,right:r.x}}function Ja(e){return e===void 0||e===1}function Ya({scale:e,scaleX:t,scaleY:n}){return!Ja(e)||!Ja(t)||!Ja(n)}function Xa(e){return Ya(e)||Za(e)||e.z||e.rotate||e.rotateX||e.rotateY||e.skewX||e.skewY}function Za(e){return Qa(e.x)||Qa(e.y)}function Qa(e){return e&&e!==`0%`}function $a(e,t,n){return n+t*(e-n)}function eo(e,t,n,r,i){return i!==void 0&&(e=$a(e,i,r)),$a(e,n,r)+t}function to(e,t=0,n=1,r,i){e.min=eo(e.min,t,n,r,i),e.max=eo(e.max,t,n,r,i)}function no(e,{x:t,y:n}){to(e.x,t.translate,t.scale,t.originPoint),to(e.y,n.translate,n.scale,n.originPoint)}var ro=.999999999999,io=1.0000000000001;function ao(e,t,n,r=!1){let i=n.length;if(!i)return;t.x=t.y=1;let a,o;for(let s=0;sro&&(t.x=1),t.yro&&(t.y=1)}function oo(e,t){e.min+=t,e.max+=t}function so(e,t,n,r,i=.5){to(e,t,n,F(e.min,e.max,i),r)}function co(e,t){return typeof e==`string`?parseFloat(e)/100*(t.max-t.min):e}function lo(e,t,n){let r=n??e;so(e.x,co(t.x,r.x),t.scaleX,t.scale,t.originX),so(e.y,co(t.y,r.y),t.scaleY,t.scale,t.originY)}function uo(e,t){return Ga(qa(e.getBoundingClientRect(),t))}function fo(e,t,n){let r=uo(e,n),{scroll:i}=t;return i&&(oo(r.x,i.offset.x),oo(r.y,i.offset.y)),r}var po={x:`translateX`,y:`translateY`,z:`translateZ`,transformPerspective:`perspective`},B=Vn.length;function V(e,t,n){let r=``,i=!0;for(let a=0;a{if(!t.target)return e;if(typeof e==`string`)if(N.test(e))e=parseFloat(e);else return e;return`${go(e,t.target.x)}% ${go(e,t.target.y)}%`}},vo={correct:(e,{treeScale:t,projectionDelta:n})=>{let r=e,i=jt.parse(e);if(i.length>5)return r;let a=jt.createTransformer(e),o=typeof i[0]==`number`?0:1,s=n.x.scale*t.x,c=n.y.scale*t.y;i[0+o]/=s,i[1+o]/=c;let l=F(s,c,.5);return typeof i[2+o]==`number`&&(i[2+o]/=l),typeof i[3+o]==`number`&&(i[3+o]/=l),a(i)}},yo={borderRadius:{..._o,applyTo:[...Pi]},borderTopLeftRadius:_o,borderTopRightRadius:_o,borderBottomLeftRadius:_o,borderBottomRightRadius:_o,boxShadow:vo};function bo(e,{layout:t,layoutId:n}){return Hn.has(e)||e.startsWith(`origin`)||(t||n!==void 0)&&(!!yo[e]||e===`opacity`)}function xo(e,t,n){let r=e.style,i=t?.style,a={};if(!r)return a;for(let t in r)(L(r[t])||i&&L(i[t])||bo(t,e)||n?.getValue(t)?.liveStyle!==void 0)&&(a[t]=r[t]);return a}function So(e){return window.getComputedStyle(e)}var Co=class extends Ua{constructor(){super(...arguments),this.type=`html`,this.renderInstance=ho}readValueFromInstance(e,t){if(Hn.has(t))return this.projection?.isProjecting?Ln(t):zn(e,t);{let n=So(e),r=(We(t)?n.getPropertyValue(t):n[t])||0;return typeof r==`string`?r.trim():r}}measureInstanceViewportBox(e,{transformPagePoint:t}){return uo(e,t)}build(e,t,n){mo(e,t,n.transformTemplate)}scrapeMotionValuesFromProps(e,t,n){return xo(e,t,n)}},wo={offset:`stroke-dashoffset`,array:`stroke-dasharray`},To={offset:`strokeDashoffset`,array:`strokeDasharray`};function Eo(e,t,n=1,r=0,i=!0){e.pathLength=1;let a=i?wo:To;e[a.offset]=`${-r}`,e[a.array]=`${t} ${n}`}var Do=[`offsetDistance`,`offsetPath`,`offsetRotate`,`offsetAnchor`];function Oo(e,{attrX:t,attrY:n,attrScale:r,pathLength:i,pathSpacing:a=1,pathOffset:o=0,...s},c,l,u){if(mo(e,s,l),c){e.style.viewBox&&(e.attrs.viewBox=e.style.viewBox);return}e.attrs=e.style,e.style={};let{attrs:d,style:f}=e;d.transform&&(f.transform=d.transform,delete d.transform),(f.transform||d.transformOrigin)&&(f.transformOrigin=d.transformOrigin??`50% 50%`,delete d.transformOrigin),f.transform&&(f.transformBox=u?.transformBox??`fill-box`,delete d.transformBox);for(let e of Do)d[e]!==void 0&&(f[e]=d[e],delete d[e]);t!==void 0&&(d.x=t),n!==void 0&&(d.y=n),r!==void 0&&(d.scale=r),i!==void 0&&Eo(d,i,a,o,!1)}var ko=new Set([`baseFrequency`,`diffuseConstant`,`kernelMatrix`,`kernelUnitLength`,`keySplines`,`keyTimes`,`limitingConeAngle`,`markerHeight`,`markerWidth`,`numOctaves`,`targetX`,`targetY`,`surfaceScale`,`specularConstant`,`specularExponent`,`stdDeviation`,`tableValues`,`viewBox`,`gradientTransform`,`pathLength`,`startOffset`,`textLength`,`lengthAdjust`]),Ao=e=>typeof e==`string`&&e.toLowerCase()===`svg`;function jo(e,t,n,r){ho(e,t,void 0,r);for(let n in t.attrs)e.setAttribute(ko.has(n)?n:si(n),t.attrs[n])}function Mo(e,t,n){let r=xo(e,t,n);for(let n in e)if(L(e[n])||L(t[n])){let t=Vn.indexOf(n)===-1?n:`attr`+n.charAt(0).toUpperCase()+n.substring(1);r[t]=e[n]}return r}var No=class extends Ua{constructor(){super(...arguments),this.type=`svg`,this.isSVGTag=!1,this.measureInstanceViewportBox=Ta}getBaseTargetFromProps(e,t){return e[t]}readValueFromInstance(e,t){if(Hn.has(t)){let e=Oi(t);return e&&e.default||0}return t=ko.has(t)?t:si(t),e.getAttribute(t)}scrapeMotionValuesFromProps(e,t,n){return Mo(e,t,n)}build(e,t,n){Oo(e,t,this.isSVGTag,n.transformTemplate,n.style)}renderInstance(e,t,n,r){jo(e,t,n,r)}mount(e){this.isSVGTag=Ao(e.tagName),super.mount(e)}},Po=Aa.length;function Fo(e){if(!e)return;if(!e.isControllingVariants){let t=e.parent&&Fo(e.parent)||{};return e.props.initial!==void 0&&(t.initial=e.props.initial),t}let t={};for(let n=0;nPromise.all(t.map(({animation:t,options:n})=>mi(e,t,n)))}function Bo(e){let t=zo(e),n=Uo(),r=!0,i=!1,a=t=>(n,r)=>{let i=$r(e,r,t===`exit`?e.presenceContext?.custom:void 0);if(i){let{transition:e,transitionEnd:t,...r}=i;n={...n,...r,...t}}return n};function o(n){t=n(e)}function s(o){let{props:s}=e,c=Fo(e.parent)||{},l=[],u=new Set,d={},f=1/0;for(let t=0;tf&&g,x=!1,S=Array.isArray(h)?h:[h],C=S.reduce(a(p),{});_===!1&&(C={});let{prevResolvedValues:w={}}=m,ee={...w,...C},te=t=>{b=!0,u.has(t)&&(x=!0,u.delete(t)),m.needsAnimating[t]=!0;let n=e.getValue(t);n&&(n.liveStyle=!1)};for(let e in ee){let t=C[e],n=w[e];if(d.hasOwnProperty(e))continue;let r=!1;r=ti(t)&&ti(n)?!Io(t,n)||y:t!==n,r?t==null?u.add(e):te(e):t!==void 0&&u.has(e)?te(e):m.protectedKeys[e]=!0}m.prevProp=h,m.prevResolvedValues=C,m.isActive&&(d={...d,...C}),(r||i)&&e.blockInitialAnimation&&(b=!1);let ne=v&&y;b&&(!ne||x)&&l.push(...S.map(t=>{let n={type:p};if(typeof t==`string`&&(r||i)&&!ne&&e.manuallyAnimateOnMount&&e.parent){let{parent:r}=e,i=$r(r,t);if(r.enteringChildren&&i){let{delayChildren:t}=i.transition||{};n.delay=Mr(r.enteringChildren,e,t)}}return{animation:t,options:n}}))}if(u.size){let t={};if(typeof s.initial!=`boolean`){let n=$r(e,Array.isArray(s.initial)?s.initial[0]:s.initial);n&&n.transition&&(t.transition=n.transition)}u.forEach(n=>{let r=e.getBaseTarget(n),i=e.getValue(n);i&&(i.liveStyle=!0),t[n]=r??null}),l.push({animation:t})}let p=!!l.length;return r&&(s.initial===!1||s.initial===s.animate)&&!e.manuallyAnimateOnMount&&(p=!1),r=!1,i=!1,p?t(l):Promise.resolve()}function c(t,r){if(n[t].isActive===r)return Promise.resolve();e.variantChildren?.forEach(e=>e.animationState?.setActive(t,r)),n[t].isActive=r;let i=s(t);for(let e in n)n[e].protectedKeys={};return i}return{animateChanges:s,setActive:c,setAnimateFunction:o,getState:()=>n,reset:()=>{n=Uo(),i=!0}}}function Vo(e,t){return typeof t==`string`?t!==e:Array.isArray(t)?!Io(t,e):!1}function Ho(e=!1){return{isActive:e,protectedKeys:{},needsAnimating:{},prevResolvedValues:{}}}function Uo(){return{animate:Ho(!0),whileInView:Ho(),whileHover:Ho(),whileTap:Ho(),whileDrag:Ho(),whileFocus:Ho(),exit:Ho()}}function Wo(e,t){e.min=t.min,e.max=t.max}function Go(e,t){Wo(e.x,t.x),Wo(e.y,t.y)}function Ko(e,t){e.translate=t.translate,e.scale=t.scale,e.originPoint=t.originPoint,e.origin=t.origin}var qo=.9999,Jo=1.0001,Yo=-.01,Xo=.01;function Zo(e){return e.max-e.min}function Qo(e,t,n){return Math.abs(e-t)<=n}function $o(e,t,n,r=.5){e.origin=r,e.originPoint=F(t.min,t.max,e.origin),e.scale=Zo(n)/Zo(t),e.translate=F(n.min,n.max,e.origin)-e.originPoint,(e.scale>=qo&&e.scale<=Jo||isNaN(e.scale))&&(e.scale=1),(e.translate>=Yo&&e.translate<=Xo||isNaN(e.translate))&&(e.translate=0)}function es(e,t,n,r){$o(e.x,t.x,n.x,r?r.originX:void 0),$o(e.y,t.y,n.y,r?r.originY:void 0)}function ts(e,t,n,r=0){e.min=(r?F(n.min,n.max,r):n.min)+t.min,e.max=e.min+Zo(t)}function ns(e,t,n,r){ts(e.x,t.x,n.x,r?.x),ts(e.y,t.y,n.y,r?.y)}function rs(e,t,n,r=0){let i=r?F(n.min,n.max,r):n.min;e.min=t.min-i,e.max=e.min+Zo(t)}function is(e,t,n,r){rs(e.x,t.x,n.x,r?.x),rs(e.y,t.y,n.y,r?.y)}function as(e,t,n,r,i){return e-=t,e=$a(e,1/n,r),i!==void 0&&(e=$a(e,1/i,r)),e}function os(e,t=0,n=1,r=.5,i,a=e,o=e){if(dt.test(t)&&(t=parseFloat(t),t=F(o.min,o.max,t/100)-o.min),typeof t!=`number`)return;let s=F(a.min,a.max,r);e===a&&(s-=t),e.min=as(e.min,t,n,s,i),e.max=as(e.max,t,n,s,i)}function ss(e,t,[n,r,i],a,o){os(e,t[n],t[r],t[i],t.scale,a,o)}var cs=[`x`,`scaleX`,`originX`],ls=[`y`,`scaleY`,`originY`];function us(e,t,n,r){ss(e.x,t,cs,n?n.x:void 0,r?r.x:void 0),ss(e.y,t,ls,n?n.y:void 0,r?r.y:void 0)}function ds(e){return e.translate===0&&e.scale===1}function fs(e){return ds(e.x)&&ds(e.y)}function ps(e,t){return e.min===t.min&&e.max===t.max}function ms(e,t){return ps(e.x,t.x)&&ps(e.y,t.y)}function hs(e,t){return Math.round(e.min)===Math.round(t.min)&&Math.round(e.max)===Math.round(t.max)}function gs(e,t){return hs(e.x,t.x)&&hs(e.y,t.y)}function _s(e){return Zo(e.x)/Zo(e.y)}function vs(e,t){return e.translate===t.translate&&e.scale===t.scale&&e.originPoint===t.originPoint}function ys(e){return[e(`x`),e(`y`)]}function bs(e,t,n){let r=``,i=e.x.translate/t.x,a=e.y.translate/t.y,o=n?.z||0;if((i||a||o)&&(r=`translate3d(${i}px, ${a}px, ${o}px) `),(t.x!==1||t.y!==1)&&(r+=`scale(${1/t.x}, ${1/t.y}) `),n){let{transformPerspective:e,rotate:t,pathRotation:i,rotateX:a,rotateY:o,skewX:s,skewY:c}=n;e&&(r=`perspective(${e}px) ${r}`),t&&(r+=`rotate(${t}deg) `),i&&(r+=`rotate(${i}deg) `),a&&(r+=`rotateX(${a}deg) `),o&&(r+=`rotateY(${o}deg) `),s&&(r+=`skewX(${s}deg) `),c&&(r+=`skewY(${c}deg) `)}let s=e.x.scale*t.x,c=e.y.scale*t.y;return(s!==1||c!==1)&&(r+=`scale(${s}, ${c})`),r||`none`}var xs=Pi.length,Ss=e=>typeof e==`string`?parseFloat(e):e,Cs=e=>typeof e==`number`||N.test(e);function ws(e,t,n,r,i,a){i?(e.opacity=F(0,n.opacity??1,Es(r)),e.opacityExit=F(t.opacity??1,0,Ds(r))):a&&(e.opacity=F(t.opacity??1,n.opacity??1,r));for(let i=0;irt?1:n(ue(e,t,r))}function ks(e,t,n){let r=L(e)?e:Lr(e);return r.start(qr(``,r,t,n)),r.animation}function As(e,t,n,r={passive:!0}){return e.addEventListener(t,n,r),()=>e.removeEventListener(t,n,r)}var js=(e,t)=>e.depth-t.depth,Ms=class{constructor(){this.children=[],this.isDirty=!1}add(e){T(this.children,e),this.isDirty=!0}remove(e){re(this.children,e),this.isDirty=!0}forEach(e){this.isDirty&&this.children.sort(js),this.isDirty=!1,this.children.forEach(e)}};function Ns(e,t){let n=M.now(),r=({timestamp:i})=>{let a=i-n;a>=t&&(ze(r),e(a-t))};return A.setup(r,!0),()=>ze(r)}function Ps(e){return L(e)?e.get():e}var Fs=class{constructor(){this.members=[]}add(e){T(this.members,e);for(let t=this.members.length-1;t>=0;t--){let n=this.members[t];if(n===e||n===this.lead||n===this.prevLead)continue;let r=n.instance;(!r||r.isConnected===!1)&&!n.snapshot&&(re(this.members,n),n.unmount())}e.scheduleRender()}remove(e){if(re(this.members,e),e===this.prevLead&&(this.prevLead=void 0),e===this.lead){let e=this.members[this.members.length-1];e&&this.promote(e)}}relegate(e){for(let t=this.members.indexOf(e)-1;t>=0;t--){let e=this.members[t];if(e.isPresent!==!1&&e.instance?.isConnected!==!1)return this.promote(e),!0}return!1}promote(e,t){let n=this.lead;if(e!==n&&(this.prevLead=n,this.lead=e,e.show(),n)){n.updateSnapshot(),e.scheduleRender();let{layoutDependency:r}=n.options,{layoutDependency:i}=e.options;(r===void 0||r!==i)&&(e.resumeFrom=n,t&&(n.preserveOpacity=!0),n.snapshot&&(e.snapshot=n.snapshot,e.snapshot.latestValues=n.animationValues||n.latestValues),e.root?.isUpdating&&(e.isLayoutDirty=!0)),e.options.crossfade===!1&&n.hide()}}exitAnimationComplete(){this.members.forEach(e=>{e.options.onExitComplete?.(),e.resumingFrom?.options.onExitComplete?.()})}scheduleRender(){this.members.forEach(e=>e.instance&&e.scheduleRender(!1))}removeLeadSnapshot(){this.lead?.snapshot&&(this.lead.snapshot=void 0)}},Is={hasAnimatedSinceResize:!0,hasEverUpdated:!1},Ls={nodes:0,calculatedTargetDeltas:0,calculatedProjections:0},Rs=[``,`X`,`Y`,`Z`],zs=1e3,Bs=0;function Vs(e,t,n,r){let{latestValues:i}=t;i[e]&&(n[e]=i[e],t.setStaticValue(e,0),r&&(r[e]=0))}function Hs(e){if(e.hasCheckedOptimisedAppear=!0,e.root===e)return;let{visualElement:t}=e.options;if(!t)return;let n=li(t);if(window.MotionHasOptimisedAnimation(n,`transform`)){let{layout:t,layoutId:r}=e.options;window.MotionCancelOptimisedAnimation(n,`transform`,A,!(t||r))}let{parent:r}=e;r&&!r.hasCheckedOptimisedAppear&&Hs(r)}function Us({attachResizeListener:e,defaultParent:t,measureScroll:n,checkIsScrollRoot:r,resetTransform:i}){return class{constructor(e={},n=t?.()){this.id=Bs++,this.animationId=0,this.animationCommitId=0,this.children=new Set,this.options={},this.isTreeAnimating=!1,this.isAnimationBlocked=!1,this.isLayoutDirty=!1,this.isProjectionDirty=!1,this.isSharedProjectionDirty=!1,this.isTransformDirty=!1,this.updateManuallyBlocked=!1,this.updateBlockedByResize=!1,this.isUpdating=!1,this.isSVG=!1,this.needsReset=!1,this.shouldResetTransform=!1,this.hasCheckedOptimisedAppear=!1,this.treeScale={x:1,y:1},this.eventHandlers=new Map,this.hasTreeAnimated=!1,this.layoutVersion=0,this.updateScheduled=!1,this.scheduleUpdate=()=>this.update(),this.projectionUpdateScheduled=!1,this.checkUpdateFailed=()=>{this.isUpdating&&(this.isUpdating=!1,this.clearAllSnapshots())},this.updateProjection=()=>{this.projectionUpdateScheduled=!1,va.value&&(Ls.nodes=Ls.calculatedTargetDeltas=Ls.calculatedProjections=0),this.nodes.forEach(Ks),this.nodes.forEach(tc),this.nodes.forEach(nc),this.nodes.forEach(qs),va.addProjectionMetrics&&va.addProjectionMetrics(Ls)},this.resolvedRelativeTargetAt=0,this.linkedParentVersion=0,this.hasProjected=!1,this.isVisible=!0,this.animationProgress=0,this.sharedNodes=new Map,this.latestValues=e,this.root=n?n.root||n:this,this.path=n?[...n.path,n]:[],this.parent=n,this.depth=n?n.depth+1:0;for(let e=0;ethis.root.updateBlockedByResize=!1;A.read(()=>{r=window.innerWidth}),e(t,()=>{let e=window.innerWidth;e!==r&&(r=e,this.root.updateBlockedByResize=!0,n&&n(),n=Ns(i,250),Is.hasAnimatedSinceResize&&(Is.hasAnimatedSinceResize=!1,this.nodes.forEach(ec)))})}n&&this.root.registerSharedNode(n,this),this.options.animate!==!1&&i&&(n||r)&&this.addEventListener(`didUpdate`,({delta:e,hasLayoutChanged:t,hasRelativeLayoutChanged:n,layout:r})=>{if(this.isTreeAnimationBlocked()){this.target=void 0,this.relativeTarget=void 0;return}let a=this.options.transition||i.getDefaultTransition()||lc,{onLayoutAnimationStart:o,onLayoutAnimationComplete:s}=i.getProps(),c=!this.targetLayout||!gs(this.targetLayout,r),l=!t&&n;if(this.options.layoutRoot||this.resumeFrom||l||t&&(c||!this.currentAnimation)){this.resumeFrom&&(this.resumingFrom=this.resumeFrom,this.resumingFrom.resumingFrom=void 0);let t={...zr(a,`layout`),onPlay:o,onComplete:s};(i.shouldReduceMotion||this.options.layoutRoot)&&(t.delay=0,t.type=!1),this.startAnimation(t),this.setAnimationOrigin(e,l,t.path)}else t||ec(this),this.isLead()&&this.options.onExitComplete&&this.options.onExitComplete();this.targetLayout=r})}unmount(){this.options.layoutId&&this.willUpdate(),this.root.nodes.remove(this);let e=this.getStack();e&&e.remove(this),this.parent&&this.parent.children.delete(this),this.instance=void 0,this.eventHandlers.clear(),ze(this.updateProjection)}blockUpdate(){this.updateManuallyBlocked=!0}unblockUpdate(){this.updateManuallyBlocked=!1}isUpdateBlocked(){return this.updateManuallyBlocked||this.updateBlockedByResize}isTreeAnimationBlocked(){return this.isAnimationBlocked||this.parent&&this.parent.isTreeAnimationBlocked()||!1}startUpdate(){this.isUpdateBlocked()||(this.isUpdating=!0,this.nodes&&this.nodes.forEach(rc),this.animationId++)}getTransformTemplate(){let{visualElement:e}=this.options;return e&&e.getProps().transformTemplate}willUpdate(e=!0){if(this.root.hasTreeAnimated=!0,this.root.isUpdateBlocked()){this.options.onExitComplete&&this.options.onExitComplete();return}if(window.MotionCancelOptimisedAnimation&&!this.hasCheckedOptimisedAppear&&Hs(this),!this.root.isUpdating&&this.root.startUpdate(),this.isLayoutDirty)return;this.isLayoutDirty=!0;for(let e=0;e{this.isLayoutDirty?this.root.didUpdate():this.root.checkUpdateFailed()})}updateSnapshot(){this.snapshot||!this.instance||(this.snapshot=this.measure(),this.snapshot&&!Zo(this.snapshot.measuredBox.x)&&!Zo(this.snapshot.measuredBox.y)&&(this.snapshot=void 0))}updateLayout(){if(!this.instance||(this.updateScroll(),!(this.options.alwaysMeasureLayout&&this.isLead())&&!this.isLayoutDirty))return;if(this.resumeFrom&&!this.resumeFrom.instance)for(let e=0;e{let n=t/1e3,r=p?.(n);r?(o.x.translate=r.x,o.x.scale=F(e.x.scale,1,n),o.x.origin=e.x.origin,o.x.originPoint=e.x.originPoint,o.y.translate=r.y,o.y.scale=F(e.y.scale,1,n),o.y.origin=e.y.origin,o.y.originPoint=e.y.originPoint):(ac(o.x,e.x,n),ac(o.y,e.y,n)),this.setTargetDelta(o),this.relativeTarget&&this.relativeTargetOrigin&&this.layout&&this.relativeParent&&this.relativeParent.layout&&(is(s,this.layout.layoutBox,this.relativeParent.layout.layoutBox,this.options.layoutAnchor||void 0),sc(this.relativeTarget,this.relativeTargetOrigin,s,n),f&&ms(this.relativeTarget,f)&&(this.isProjectionDirty=!1),f||=Ta(),Go(f,this.relativeTarget)),c&&(this.animationValues=a,ws(a,i,this.latestValues,n,d,u)),r&&r.rotate!==void 0&&(this.animationValues||=a,this.animationValues.pathRotation=r.rotate),this.root.scheduleUpdateProjection(),this.scheduleRender(),this.animationProgress=n},this.mixTargetDelta(this.options.layoutRoot?1e3:0)}startAnimation(e){this.notifyListeners(`animationStart`),this.currentAnimation?.stop(),this.resumingFrom?.currentAnimation?.stop(),this.pendingAnimation&&=(ze(this.pendingAnimation),void 0),this.pendingAnimation=A.update(()=>{Is.hasAnimatedSinceResize=!0,this.motionValue||=Lr(0),this.motionValue.jump(0,!1),this.currentAnimation=ks(this.motionValue,[0,1e3],{...e,velocity:0,isSync:!0,onUpdate:t=>{this.mixTargetDelta(t),e.onUpdate&&e.onUpdate(t)},onComplete:()=>{e.onComplete&&e.onComplete(),this.completeAnimation()}}),this.resumingFrom&&(this.resumingFrom.currentAnimation=this.currentAnimation),this.pendingAnimation=void 0})}completeAnimation(){this.resumingFrom&&(this.resumingFrom.currentAnimation=void 0,this.resumingFrom.preserveOpacity=void 0);let e=this.getStack();e&&e.exitAnimationComplete(),this.resumingFrom=this.currentAnimation=this.animationValues=void 0,this.notifyListeners(`animationComplete`)}finishAnimation(){this.currentAnimation&&(this.mixTargetDelta&&this.mixTargetDelta(zs),this.currentAnimation.stop()),this.completeAnimation()}applyTransformsToTarget(){let e=this.getLead(),{targetWithTransforms:t,target:n,layout:r,latestValues:i}=e;if(!(!t||!n||!r)){if(this!==e&&this.layout&&r&&mc(this.options.animationType,this.layout.layoutBox,r.layoutBox)){n=this.target||Ta();let t=Zo(this.layout.layoutBox.x);n.x.min=e.target.x.min,n.x.max=n.x.min+t;let r=Zo(this.layout.layoutBox.y);n.y.min=e.target.y.min,n.y.max=n.y.min+r}Go(t,n),lo(t,i),es(this.projectionDeltaWithTransform,this.layoutCorrected,t,i)}}registerSharedNode(e,t){this.sharedNodes.has(e)||this.sharedNodes.set(e,new Fs),this.sharedNodes.get(e).add(t);let n=t.options.initialPromotionConfig;t.promote({transition:n?n.transition:void 0,preserveFollowOpacity:n&&n.shouldPreserveFollowOpacity?n.shouldPreserveFollowOpacity(t):void 0})}isLead(){let e=this.getStack();return!e||e.lead===this}getLead(){let{layoutId:e}=this.options;return e&&this.getStack()?.lead||this}getPrevLead(){let{layoutId:e}=this.options;return e?this.getStack()?.prevLead:void 0}getStack(){let{layoutId:e}=this.options;if(e)return this.root.sharedNodes.get(e)}promote({needsReset:e,transition:t,preserveFollowOpacity:n}={}){let r=this.getStack();r&&r.promote(this,n),e&&(this.projectionDelta=void 0,this.needsReset=!0),t&&this.setOptions({transition:t})}relegate(){let e=this.getStack();return e?e.relegate(this):!1}resetSkewAndRotation(){let{visualElement:e}=this.options;if(!e)return;let t=!1,{latestValues:n}=e;if((n.z||n.rotate||n.rotateX||n.rotateY||n.rotateZ||n.skewX||n.skewY)&&(t=!0),!t)return;let r={};n.z&&Vs(`z`,e,r,this.animationValues);for(let t=0;te.currentAnimation?.stop()),this.root.nodes.forEach(Ys),this.root.sharedNodes.clear()}}}function Ws(e){e.updateLayout()}function Gs(e){let t=e.resumeFrom?.snapshot||e.snapshot;if(e.isLead()&&e.layout&&t&&e.hasListeners(`didUpdate`)){let{layoutBox:n,measuredBox:r}=e.layout,{animationType:i}=e.options,a=t.source!==e.layout.source;if(i===`size`)ys(e=>{let r=a?t.measuredBox[e]:t.layoutBox[e],i=Zo(r);r.min=n[e].min,r.max=r.min+i});else if(i===`x`||i===`y`){let e=i===`x`?`y`:`x`;Wo(a?t.measuredBox[e]:t.layoutBox[e],n[e])}else mc(i,t.layoutBox,n)&&ys(r=>{let i=a?t.measuredBox[r]:t.layoutBox[r],o=Zo(n[r]);i.max=i.min+o,e.relativeTarget&&!e.currentAnimation&&(e.isProjectionDirty=!0,e.relativeTarget[r].max=e.relativeTarget[r].min+o)});let o=Ca();es(o,n,t.layoutBox);let s=Ca();a?es(s,e.applyTransform(r,!0),t.measuredBox):es(s,n,t.layoutBox);let c=!fs(o),l=!1;if(!e.resumeFrom){let r=e.getClosestProjectingParent();if(r&&!r.resumeFrom){let{snapshot:i,layout:a}=r;if(i&&a){let o=e.options.layoutAnchor||void 0,s=Ta();is(s,t.layoutBox,i.layoutBox,o);let c=Ta();is(c,n,a.layoutBox,o),gs(s,c)||(l=!0),r.options.layoutRoot&&(e.relativeTarget=c,e.relativeTargetOrigin=s,e.relativeParent=r)}}}e.notifyListeners(`didUpdate`,{layout:n,snapshot:t,delta:s,layoutDelta:o,hasLayoutChanged:c,hasRelativeLayoutChanged:l})}else if(e.isLead()){let{onExitComplete:t}=e.options;t&&t()}e.options.transition=void 0}function Ks(e){va.value&&Ls.nodes++,e.parent&&(e.isProjecting()||(e.isProjectionDirty=e.parent.isProjectionDirty),e.isSharedProjectionDirty||=!!(e.isProjectionDirty||e.parent.isProjectionDirty||e.parent.isSharedProjectionDirty),e.isTransformDirty||=e.parent.isTransformDirty)}function qs(e){e.isProjectionDirty=e.isSharedProjectionDirty=e.isTransformDirty=!1}function Js(e){e.clearSnapshot()}function Ys(e){e.clearMeasurements()}function Xs(e){e.isLayoutDirty=!0,e.updateLayout()}function Zs(e){e.isLayoutDirty=!1}function Qs(e){e.isAnimationBlocked&&e.layout&&!e.isLayoutDirty&&(e.snapshot=e.layout,e.isLayoutDirty=!0)}function $s(e){let{visualElement:t}=e.options;t&&t.getProps().onBeforeLayoutMeasure&&t.notify(`BeforeLayoutMeasure`),e.resetTransform()}function ec(e){e.finishAnimation(),e.targetDelta=e.relativeTarget=e.target=void 0,e.isProjectionDirty=!0}function tc(e){e.resolveTargetDelta()}function nc(e){e.calcProjection()}function rc(e){e.resetSkewAndRotation()}function ic(e){e.removeLeadSnapshot()}function ac(e,t,n){e.translate=F(t.translate,0,n),e.scale=F(t.scale,1,n),e.origin=t.origin,e.originPoint=t.originPoint}function oc(e,t,n,r){e.min=F(t.min,n.min,r),e.max=F(t.max,n.max,r)}function sc(e,t,n,r){oc(e.x,t.x,n.x,r),oc(e.y,t.y,n.y,r)}function cc(e){return e.animationValues&&e.animationValues.opacityExit!==void 0}var lc={duration:.45,ease:[.4,0,.1,1]},uc=e=>typeof navigator<`u`&&navigator.userAgent&&navigator.userAgent.toLowerCase().includes(e),dc=uc(`applewebkit/`)&&!uc(`chrome/`)?Math.round:E;function fc(e){e.min=dc(e.min),e.max=dc(e.max)}function pc(e){fc(e.x),fc(e.y)}function mc(e,t,n){return e===`position`||e===`preserve-aspect`&&!Qo(_s(t),_s(n),.2)}function hc(e){return e!==e.root&&e.scroll?.wasRoot}var gc=Us({attachResizeListener:(e,t)=>As(e,`resize`,t),measureScroll:()=>({x:document.documentElement.scrollLeft||document.body?.scrollLeft||0,y:document.documentElement.scrollTop||document.body?.scrollTop||0}),checkIsScrollRoot:()=>!0}),_c=e=>!e.isLayoutDirty&&e.willUpdate(!1);function vc(){let e=new Set,t=new WeakMap,n=()=>e.forEach(_c);return{add:r=>{e.add(r),t.set(r,r.addEventListener(`willUpdate`,n))},remove:r=>{e.delete(r);let i=t.get(r);i&&(i(),t.delete(r)),n()},dirty:n}}var yc={current:void 0},bc=Us({measureScroll:e=>({x:e.scrollLeft,y:e.scrollTop}),defaultParent:()=>{if(!yc.current){let e=new gc({});e.mount(window),e.setOptions({layoutScroll:!0}),yc.current=e}return yc.current},resetTransform:(e,t)=>{e.style.transform=t===void 0?`none`:t},checkIsScrollRoot:e=>window.getComputedStyle(e).position===`fixed`}),xc=(0,b.createContext)({transformPagePoint:e=>e,isStatic:!1,reducedMotion:`never`});function Sc(e=!0){let t=(0,b.useContext)(ne);if(t===null)return[!0,null];let{isPresent:n,onExitComplete:r,register:i}=t,a=(0,b.useId)();(0,b.useEffect)(()=>{if(e)return i(a)},[e]);let o=(0,b.useCallback)(()=>e&&r&&r(a),[a,r,e]);return!n&&r?[!1,o]:[!0]}var Cc=(0,b.createContext)(null);function wc(){let e=(0,b.useRef)(!1);return te(()=>(e.current=!0,()=>{e.current=!1}),[]),e}function Tc(){let e=wc(),[t,n]=(0,b.useState)(0),r=(0,b.useCallback)(()=>{e.current&&n(t+1)},[t]);return[(0,b.useCallback)(()=>A.postRender(r),[r]),t]}var H=C(),Ec=e=>e===!0,Dc=e=>Ec(e===!0)||e===`id`,Oc=({children:e,id:t,inherit:n=!0})=>{let r=(0,b.useContext)(w),i=(0,b.useContext)(Cc),[a,o]=Tc(),s=(0,b.useRef)(null),c=r.id||i;s.current===null&&(Dc(n)&&c&&(t=t?c+`-`+t:c),s.current={id:t,group:Ec(n)&&r.group||vc()});let l=(0,b.useMemo)(()=>({...s.current,forceRender:a}),[o]);return(0,H.jsx)(w.Provider,{value:l,children:e})},kc=(0,b.createContext)({strict:!1}),Ac={animation:[`animate`,`variants`,`whileHover`,`whileTap`,`exit`,`whileInView`,`whileFocus`,`whileDrag`],exit:[`exit`],drag:[`drag`,`dragControls`],focus:[`whileFocus`],hover:[`whileHover`,`onHoverStart`,`onHoverEnd`],tap:[`whileTap`,`onTap`,`onTapStart`,`onTapCancel`],pan:[`onPan`,`onPanStart`,`onPanSessionStart`,`onPanEnd`],inView:[`whileInView`,`onViewportEnter`,`onViewportLeave`],layout:[`layout`,`layoutId`]},jc=!1;function Mc(){if(jc)return;let e={};for(let t in Ac)e[t]={isEnabled:e=>Ac[t].some(t=>!!e[t])};Ba(e),jc=!0}function Nc(){return Mc(),Va()}function Pc(e){let t=Nc();for(let n in e)t[n]={...t[n],...e[n]};Ba(t)}var Fc=new Set(`animate.exit.variants.initial.style.values.variants.transition.transformTemplate.custom.inherit.onBeforeLayoutMeasure.onAnimationStart.onAnimationComplete.onUpdate.onDragStart.onDrag.onDragEnd.onMeasureDragConstraints.onDirectionLock.onDragTransitionEnd._dragX._dragY.onHoverStart.onHoverEnd.onViewportEnter.onViewportLeave.globalTapTarget.propagate.ignoreStrict.viewport`.split(`.`));function Ic(e){return e.startsWith(`while`)||e.startsWith(`drag`)&&e!==`draggable`||e.startsWith(`layout`)||e.startsWith(`onTap`)||e.startsWith(`onPan`)||e.startsWith(`onLayout`)||Fc.has(e)}var Lc=c({default:()=>Rc}),Rc,U=o((()=>{throw Rc={},Error(`Could not resolve "@emotion/is-prop-valid" imported by "framer-motion". Is it installed?`)})),zc=e=>!Ic(e);function Bc(e){typeof e==`function`&&(zc=t=>t.startsWith(`on`)?!Ic(t):e(t))}try{Bc((U(),d(Lc)).default)}catch{}function Vc(e,t,n){let r={};for(let i in e)i===`values`&&typeof e.values==`object`||L(e[i])||(zc(i)||n===!0&&Ic(i)||!t&&!Ic(i)||e.draggable&&i.startsWith(`onDrag`))&&(r[i]=e[i]);return r}var Hc=(0,b.createContext)({});function Uc(e,t){if(ja(e)){let{initial:t,animate:n}=e;return{initial:t===!1||Oa(t)?t:void 0,animate:Oa(n)?n:void 0}}return e.inherit===!1?{}:t}function Wc(e){let{initial:t,animate:n}=Uc(e,(0,b.useContext)(Hc));return(0,b.useMemo)(()=>({initial:t,animate:n}),[Gc(t),Gc(n)])}function Gc(e){return Array.isArray(e)?e.join(` `):e}var Kc=()=>({style:{},transform:{},transformOrigin:{},vars:{}});function qc(e,t,n){for(let r in t)!L(t[r])&&!bo(r,n)&&(e[r]=t[r])}function Jc({transformTemplate:e},t){return(0,b.useMemo)(()=>{let n=Kc();return mo(n,t,e),Object.assign({},n.vars,n.style)},[t])}function Yc(e,t){let n=e.style||{},r={};return qc(r,n,e),Object.assign(r,Jc(e,t)),r}function Xc(e,t){let n={},r=Yc(e,t);return e.drag&&e.dragListener!==!1&&(n.draggable=!1,r.userSelect=r.WebkitUserSelect=r.WebkitTouchCallout=`none`,r.touchAction=e.drag===!0?`none`:`pan-${e.drag===`x`?`y`:`x`}`),e.tabIndex===void 0&&(e.onTap||e.onTapStart||e.whileTap)&&(n.tabIndex=0),n.style=r,n}var Zc=()=>({...Kc(),attrs:{}});function Qc(e,t,n,r){let i=(0,b.useMemo)(()=>{let n=Zc();return Oo(n,t,Ao(r),e.transformTemplate,e.style),{...n.attrs,style:{...n.style}}},[t]);if(e.style){let t={};qc(t,e.style,e),i.style={...t,...i.style}}return i}var $c=[`animate`,`circle`,`defs`,`desc`,`ellipse`,`g`,`image`,`line`,`filter`,`marker`,`mask`,`metadata`,`path`,`pattern`,`polygon`,`polyline`,`rect`,`stop`,`switch`,`symbol`,`svg`,`text`,`tspan`,`use`,`view`];function el(e){return typeof e!=`string`||e.includes(`-`)?!1:!!($c.indexOf(e)>-1||/[A-Z]/u.test(e))}function tl(e,t,n,{latestValues:r},i,a=!1,o){let s=(o??el(e)?Qc:Xc)(t,r,i,e),c=Vc(t,typeof e==`string`,a),l=e===b.Fragment?{}:{...c,...s,ref:n},{children:u}=t,d=(0,b.useMemo)(()=>L(u)?u.get():u,[u]);return(0,b.createElement)(e,{...l,children:d})}function nl({scrapeMotionValuesFromProps:e,createRenderState:t},n,r,i){return{latestValues:rl(n,r,i,e),renderState:t()}}function rl(e,t,n,r){let i={},a=r(e,{});for(let e in a)i[e]=Ps(a[e]);let{initial:o,animate:s}=e,c=ja(e),l=Ma(e);t&&l&&!c&&e.inherit!==!1&&(o===void 0&&(o=t.initial),s===void 0&&(s=t.animate));let u=n?n.initial===!1:!1;u||=o===!1;let d=u?s:o;if(d&&typeof d!=`boolean`&&!Da(d)){let t=Array.isArray(d)?d:[d];for(let n=0;n(t,n)=>{let r=(0,b.useContext)(Hc),i=(0,b.useContext)(ne),a=()=>nl(e,t,r,i);return n?a():ee(a)},al=il({scrapeMotionValuesFromProps:xo,createRenderState:Kc}),ol=il({scrapeMotionValuesFromProps:Mo,createRenderState:Zc}),sl=Symbol.for(`motionComponentSymbol`);function cl(e,t,n){let r=(0,b.useRef)(n);(0,b.useInsertionEffect)(()=>{r.current=n});let i=(0,b.useRef)(null);return(0,b.useCallback)(n=>{n&&e.onMount?.(n),t&&(n?t.mount(n):t.unmount());let a=r.current;if(typeof a==`function`)if(n){let e=a(n);typeof e==`function`&&(i.current=e)}else i.current?(i.current(),i.current=null):a(n);else a&&(a.current=n)},[t])}var W=(0,b.createContext)({});function ll(e){return e&&typeof e==`object`&&Object.prototype.hasOwnProperty.call(e,`current`)}function ul(e,t,n,r,i,a){let{visualElement:o}=(0,b.useContext)(Hc),s=(0,b.useContext)(kc),c=(0,b.useContext)(ne),l=(0,b.useContext)(xc),u=l.reducedMotion,d=l.skipAnimations,f=(0,b.useRef)(null),p=(0,b.useRef)(!1);r||=s.renderer,!f.current&&r&&(f.current=r(e,{visualState:t,parent:o,props:n,presenceContext:c,blockInitialAnimation:c?c.initial===!1:!1,reducedMotionConfig:u,skipAnimations:d,isSVG:a}),p.current&&f.current&&(f.current.manuallyAnimateOnMount=!0));let m=f.current,h=(0,b.useContext)(W);m&&!m.projection&&i&&(m.type===`html`||m.type===`svg`)&&dl(f.current,n,i,h);let g=(0,b.useRef)(!1);(0,b.useInsertionEffect)(()=>{m&&g.current&&m.update(n,c)});let _=n[ci],v=(0,b.useRef)(!!_&&typeof window<`u`&&!window.MotionHandoffIsComplete?.(_)&&window.MotionHasOptimisedAnimation?.(_));return te(()=>{p.current=!0,m&&(g.current=!0,window.MotionIsMounted=!0,m.updateFeatures(),m.scheduleRenderMicrotask(),v.current&&m.animationState&&m.animationState.animateChanges())}),(0,b.useEffect)(()=>{m&&(!v.current&&m.animationState&&m.animationState.animateChanges(),v.current&&=(queueMicrotask(()=>{window.MotionHandoffMarkAsComplete?.(_)}),!1),m.enteringChildren=void 0)}),m}function dl(e,t,n,r){let{layoutId:i,layout:a,drag:o,dragConstraints:s,layoutScroll:c,layoutRoot:l,layoutAnchor:u,layoutCrossfade:d}=t;e.projection=new n(e.latestValues,t[`data-framer-portal-id`]?void 0:fl(e.parent)),e.projection.setOptions({layoutId:i,layout:a,alwaysMeasureLayout:!!o||s&&ll(s),visualElement:e,animationType:typeof a==`string`?a:`both`,initialPromotionConfig:r,crossfade:d,layoutScroll:c,layoutRoot:l,layoutAnchor:u})}function fl(e){if(e)return e.options.allowProjection===!1?fl(e.parent):e.projection}function pl(e,{forwardMotionProps:t=!1,type:n}={},r,i){r&&Pc(r);let a=n?n===`svg`:el(e),o=a?ol:al;function s(n,s){let c,l={...(0,b.useContext)(xc),...n,layoutId:ml(n)},{isStatic:u}=l,d=Wc(n),f=o(n,u);if(!u&&typeof window<`u`){hl(l,r);let t=gl(l);c=t.MeasureLayout,d.visualElement=ul(e,f,l,i,t.ProjectionNode,a)}return(0,H.jsxs)(Hc.Provider,{value:d,children:[c&&d.visualElement?(0,H.jsx)(c,{visualElement:d.visualElement,...l}):null,tl(e,n,cl(f,d.visualElement,s),f,u,t,a)]})}s.displayName=`motion.${typeof e==`string`?e:`create(${e.displayName??e.name??``})`}`;let c=(0,b.forwardRef)(s);return c[sl]=e,c}function ml({layoutId:e}){let t=(0,b.useContext)(w).id;return t&&e!==void 0?t+`-`+e:e}function hl(e,t){(0,b.useContext)(kc).strict}function gl(e){let{drag:t,layout:n}=Nc();if(!t&&!n)return{};let r={...t,...n};return{MeasureLayout:t?.isEnabled(e)||n?.isEnabled(e)?r.MeasureLayout:void 0,ProjectionNode:r.ProjectionNode}}function _l(e,t){if(typeof Proxy>`u`)return pl;let n=new Map,r=(n,r)=>pl(n,r,e,t);return new Proxy((e,t)=>r(e,t),{get:(i,a)=>a===`create`?r:(n.has(a)||n.set(a,pl(a,void 0,e,t)),n.get(a))})}var vl=(e,t)=>t.isSVG??el(e)?new No(t):new Co(t,{allowProjection:e!==b.Fragment}),yl=class extends Wa{constructor(e){super(e),e.animationState||=Bo(e)}updateAnimationControlsSubscription(){let{animate:e}=this.node.getProps();Da(e)&&(this.unmountControls=e.subscribe(this.node))}mount(){this.updateAnimationControlsSubscription()}update(){let{animate:e}=this.node.getProps(),{animate:t}=this.node.prevProps||{};e!==t&&this.updateAnimationControlsSubscription()}unmount(){this.node.animationState.reset(),this.unmountControls?.()}},bl=0,xl={animation:{Feature:yl},exit:{Feature:class extends Wa{constructor(){super(...arguments),this.id=bl++,this.isExitComplete=!1}update(){if(!this.node.presenceContext)return;let{isPresent:e,onExitComplete:t}=this.node.presenceContext,{isPresent:n}=this.node.prevPresenceContext||{};if(!this.node.animationState||e===n)return;if(e&&n===!1){if(this.isExitComplete){let{initial:e,custom:t}=this.node.getProps();if(typeof e==`string`||typeof e==`object`&&e&&!Array.isArray(e)){let n=$r(this.node,e,t);if(n){let{transition:e,transitionEnd:t,...r}=n;for(let e in r)this.node.getValue(e)?.jump(r[e])}}this.node.animationState.reset(),this.node.animationState.animateChanges()}else this.node.animationState.setActive(`exit`,!1);this.isExitComplete=!1;return}let r=this.node.animationState.setActive(`exit`,!e);t&&!e&&r.then(()=>{this.isExitComplete=!0,t(this.id)})}mount(){let{register:e,onExitComplete:t}=this.node.presenceContext||{};t&&t(this.id),e&&(this.unmount=e(this.id))}unmount(){}}}};function Sl(e){return{point:{x:e.pageX,y:e.pageY}}}var Cl=e=>t=>Gi(t)&&e(t,Sl(t));function wl(e,t,n,r){return As(e,t,Cl(n),r)}var Tl=({current:e})=>e?e.ownerDocument.defaultView:null,El=(e,t)=>Math.abs(e-t);function Dl(e,t){let n=El(e.x,t.x),r=El(e.y,t.y);return Math.sqrt(n**2+r**2)}var Ol=new Set([`auto`,`scroll`]),kl=class{constructor(e,t,{transformPagePoint:n,contextWindow:r=window,dragSnapToOrigin:i=!1,distanceThreshold:a=3,element:o}={}){if(this.startEvent=null,this.lastMoveEvent=null,this.lastMoveEventInfo=null,this.lastRawMoveEventInfo=null,this.handlers={},this.contextWindow=window,this.scrollPositions=new Map,this.removeScrollListeners=null,this.onElementScroll=e=>{this.handleScroll(e.target)},this.onWindowScroll=()=>{this.handleScroll(window)},this.updatePoint=()=>{if(!(this.lastMoveEvent&&this.lastMoveEventInfo))return;this.lastRawMoveEventInfo&&(this.lastMoveEventInfo=Al(this.lastRawMoveEventInfo,this.transformPagePoint));let e=Ml(this.lastMoveEventInfo,this.history),t=this.startEvent!==null,n=Dl(e.offset,{x:0,y:0})>=this.distanceThreshold;if(!t&&!n)return;let{point:r}=e,{timestamp:i}=j;this.history.push({...r,timestamp:i});let{onStart:a,onMove:o}=this.handlers;t||(a&&a(this.lastMoveEvent,e),this.startEvent=this.lastMoveEvent),o&&o(this.lastMoveEvent,e)},this.handlePointerMove=(e,t)=>{this.lastMoveEvent=e,this.lastRawMoveEventInfo=t,this.lastMoveEventInfo=Al(t,this.transformPagePoint),A.update(this.updatePoint,!0)},this.handlePointerUp=(e,t)=>{this.end();let{onEnd:n,onSessionEnd:r,resumeAnimation:i}=this.handlers;if((this.dragSnapToOrigin||!this.startEvent)&&i&&i(),!(this.lastMoveEvent&&this.lastMoveEventInfo))return;let a=Ml(e.type===`pointercancel`?this.lastMoveEventInfo:Al(t,this.transformPagePoint),this.history);this.startEvent&&n&&n(e,a),r&&r(e,a)},!Gi(e))return;this.dragSnapToOrigin=i,this.handlers=t,this.transformPagePoint=n,this.distanceThreshold=a,this.contextWindow=r||window;let s=Al(Sl(e),this.transformPagePoint),{point:c}=s,{timestamp:l}=j;this.history=[{...c,timestamp:l}];let{onSessionStart:u}=t;u&&u(e,Ml(s,this.history));let d={passive:!0,capture:!0};this.removeListeners=D(wl(this.contextWindow,`pointermove`,this.handlePointerMove,d),wl(this.contextWindow,`pointerup`,this.handlePointerUp,d),wl(this.contextWindow,`pointercancel`,this.handlePointerUp,d)),o&&this.startScrollTracking(o)}startScrollTracking(e){let t=e.parentElement;for(;t;){let e=getComputedStyle(t);(Ol.has(e.overflowX)||Ol.has(e.overflowY))&&this.scrollPositions.set(t,{x:t.scrollLeft,y:t.scrollTop}),t=t.parentElement}this.scrollPositions.set(window,{x:window.scrollX,y:window.scrollY}),window.addEventListener(`scroll`,this.onElementScroll,{capture:!0}),window.addEventListener(`scroll`,this.onWindowScroll),this.removeScrollListeners=()=>{window.removeEventListener(`scroll`,this.onElementScroll,{capture:!0}),window.removeEventListener(`scroll`,this.onWindowScroll)}}handleScroll(e){let t=this.scrollPositions.get(e);if(!t)return;let n=e===window,r=n?{x:window.scrollX,y:window.scrollY}:{x:e.scrollLeft,y:e.scrollTop},i={x:r.x-t.x,y:r.y-t.y};i.x===0&&i.y===0||(n?this.lastMoveEventInfo&&(this.lastMoveEventInfo.point.x+=i.x,this.lastMoveEventInfo.point.y+=i.y):this.history.length>0&&(this.history[0].x-=i.x,this.history[0].y-=i.y),this.scrollPositions.set(e,r),A.update(this.updatePoint,!0))}updateHandlers(e){this.handlers=e}end(){this.removeListeners&&this.removeListeners(),this.removeScrollListeners&&this.removeScrollListeners(),this.scrollPositions.clear(),ze(this.updatePoint)}};function Al(e,t){return t?{point:t(e.point)}:e}function jl(e,t){return{x:e.x-t.x,y:e.y-t.y}}function Ml({point:e},t){return{point:e,delta:jl(e,Pl(t)),offset:jl(e,Nl(t)),velocity:Fl(t,.1)}}function Nl(e){return e[0]}function Pl(e){return e[e.length-1]}function Fl(e,t){if(e.length<2)return{x:0,y:0};let n=e.length-1,r=null,i=Pl(e);for(;n>=0&&(r=e[n],!(i.timestamp-r.timestamp>fe(t)));)n--;if(!r)return{x:0,y:0};r===e[0]&&e.length>2&&i.timestamp-r.timestamp>fe(t)*2&&(r=e[1]);let a=O(i.timestamp-r.timestamp);if(a===0)return{x:0,y:0};let o={x:(i.x-r.x)/a,y:(i.y-r.y)/a};return o.x===1/0&&(o.x=0),o.y===1/0&&(o.y=0),o}function Il(e,{min:t,max:n},r){return t!==void 0&&en&&(e=r?F(n,e,r.max):Math.min(e,n)),e}function Ll(e,t,n){return{min:t===void 0?void 0:e.min+t,max:n===void 0?void 0:e.max+n-(e.max-e.min)}}function Rl(e,{top:t,left:n,bottom:r,right:i}){return{x:Ll(e.x,n,i),y:Ll(e.y,t,r)}}function zl(e,t){let n=t.min-e.min,r=t.max-e.max;return t.max-t.minr?n=ue(t.min,t.max-r,e.min):r>i&&(n=ue(e.min,e.max-i,t.min)),ie(0,1,n)}function q(e,t){let n={};return t.min!==void 0&&(n.min=t.min-e.min),t.max!==void 0&&(n.max=t.max-e.min),n}var J=.35;function Y(e=J){return e===!1?e=0:e===!0&&(e=J),{x:Bl(e,`left`,`right`),y:Bl(e,`top`,`bottom`)}}function Bl(e,t,n){return{min:Vl(e,t),max:Vl(e,n)}}function Vl(e,t){return typeof e==`number`?e:e[t]||0}var Hl=new WeakMap,Ul=class{constructor(e){this.openDragLock=null,this.isDragging=!1,this.currentDirection=null,this.originPoint={x:0,y:0},this.constraints=!1,this.hasMutatedConstraints=!1,this.elastic=Ta(),this.latestPointerEvent=null,this.latestPanInfo=null,this.visualElement=e}start(e,{snapToCursor:t=!1,distanceThreshold:n}={}){let{presenceContext:r}=this.visualElement;if(r&&r.isPresent===!1)return;let i=e=>{t&&this.snapToCursor(Sl(e).point),this.stopAnimation()},a=(e,t)=>{let{drag:n,dragPropagation:r,onDragStart:i}=this.getProps();if(n&&!r&&(this.openDragLock&&this.openDragLock(),this.openDragLock=Bi(n),!this.openDragLock))return;this.latestPointerEvent=e,this.latestPanInfo=t,this.isDragging=!0,this.currentDirection=null,this.resolveConstraints(),this.visualElement.projection&&(this.visualElement.projection.isAnimationBlocked=!0,this.visualElement.projection.target=void 0),ys(e=>{let t=this.getAxisMotionValue(e).get()||0;if(dt.test(t)){let{projection:n}=this.visualElement;if(n&&n.layout){let r=n.layout.layoutBox[e];r&&(t=Zo(r)*(parseFloat(t)/100))}}this.originPoint[e]=t}),i&&A.update(()=>i(e,t),!1,!0),oi(this.visualElement,`transform`);let{animationState:a}=this.visualElement;a&&a.setActive(`whileDrag`,!0)},o=(e,t)=>{this.latestPointerEvent=e,this.latestPanInfo=t;let{dragPropagation:n,dragDirectionLock:r,onDirectionLock:i,onDrag:a}=this.getProps();if(!n&&!this.openDragLock)return;let{offset:o}=t;if(r&&this.currentDirection===null){this.currentDirection=ql(o),this.currentDirection!==null&&i&&i(this.currentDirection);return}this.updateAxis(`x`,t.point,o),this.updateAxis(`y`,t.point,o),this.visualElement.render(),a&&A.update(()=>a(e,t),!1,!0)},s=(e,t)=>{this.latestPointerEvent=e,this.latestPanInfo=t,this.stop(e,t),this.latestPointerEvent=null,this.latestPanInfo=null},c=()=>{let{dragSnapToOrigin:e}=this.getProps();(e||this.constraints)&&this.startAnimation({x:0,y:0})},{dragSnapToOrigin:l}=this.getProps();this.panSession=new kl(e,{onSessionStart:i,onStart:a,onMove:o,onSessionEnd:s,resumeAnimation:c},{transformPagePoint:this.visualElement.getTransformPagePoint(),dragSnapToOrigin:l,distanceThreshold:n,contextWindow:Tl(this.visualElement),element:this.visualElement.current})}stop(e,t){let n=e||this.latestPointerEvent,r=t||this.latestPanInfo,i=this.isDragging;if(this.cancel(),!i||!r||!n)return;let{velocity:a}=r;this.startAnimation(a);let{onDragEnd:o}=this.getProps();o&&A.postRender(()=>o(n,r))}cancel(){this.isDragging=!1;let{projection:e,animationState:t}=this.visualElement;e&&(e.isAnimationBlocked=!1),this.endPanSession();let{dragPropagation:n}=this.getProps();!n&&this.openDragLock&&(this.openDragLock(),this.openDragLock=null),t&&t.setActive(`whileDrag`,!1)}endPanSession(){this.panSession&&this.panSession.end(),this.panSession=void 0}updateAxis(e,t,n){let{drag:r}=this.getProps();if(!n||!Kl(e,r,this.currentDirection))return;let i=this.getAxisMotionValue(e),a=this.originPoint[e]+n[e];this.constraints&&this.constraints[e]&&(a=Il(a,this.constraints[e],this.elastic[e])),i.set(a)}resolveConstraints(){let{dragConstraints:e,dragElastic:t}=this.getProps(),n=this.visualElement.projection&&!this.visualElement.projection.layout?this.visualElement.projection.measure(!1):this.visualElement.projection?.layout,r=this.constraints;e&&ll(e)?this.constraints||=this.resolveRefConstraints():e&&n?this.constraints=Rl(n.layoutBox,e):this.constraints=!1,this.elastic=Y(t),r!==this.constraints&&!ll(e)&&n&&this.constraints&&!this.hasMutatedConstraints&&ys(e=>{this.constraints!==!1&&this.getAxisMotionValue(e)&&(this.constraints[e]=q(n.layoutBox[e],this.constraints[e]))})}resolveRefConstraints(){let{dragConstraints:e,onMeasureDragConstraints:t}=this.getProps();if(!e||!ll(e))return!1;let n=e.current,{projection:r}=this.visualElement;if(!r||!r.layout)return!1;r.root&&(r.root.scroll=void 0,r.root.updateScroll());let i=fo(n,r.root,this.visualElement.getTransformPagePoint()),a=G(r.layout.layoutBox,i);if(t){let e=t(Ka(a));this.hasMutatedConstraints=!!e,e&&(a=Ga(e))}return a}startAnimation(e){let{drag:t,dragMomentum:n,dragElastic:r,dragTransition:i,dragSnapToOrigin:a,onDragTransitionEnd:o}=this.getProps(),s=this.constraints||{},c=ys(o=>{if(!Kl(o,t,this.currentDirection))return;let c=s&&s[o]||{};(a===!0||a===o)&&(c={min:0,max:0});let l=r?200:1e6,u=r?40:1e7,d={type:`inertia`,velocity:n?e[o]:0,bounceStiffness:l,bounceDamping:u,timeConstant:750,restDelta:1,restSpeed:10,...i,...c};return this.startAxisValueAnimation(o,d)});return Promise.all(c).then(o)}startAxisValueAnimation(e,t){let n=this.getAxisMotionValue(e);return oi(this.visualElement,e),n.start(qr(e,n,0,t,this.visualElement,!1))}stopAnimation(){ys(e=>this.getAxisMotionValue(e).stop())}getAxisMotionValue(e){let t=`_drag${e.toUpperCase()}`;return this.visualElement.getProps()[t]||this.visualElement.getValue(e,this.visualElement.latestValues[e]??0)}snapToCursor(e){ys(t=>{let{drag:n}=this.getProps();if(!Kl(t,n,this.currentDirection))return;let{projection:r}=this.visualElement,i=this.getAxisMotionValue(t);if(r&&r.layout){let{min:n,max:a}=r.layout.layoutBox[t],o=i.get()||0;i.set(e[t]-F(n,a,.5)+o)}})}scalePositionWithinConstraints(){if(!this.visualElement.current)return;let{drag:e,dragConstraints:t}=this.getProps(),{projection:n}=this.visualElement;if(!ll(t)||!n||!this.constraints)return;this.stopAnimation();let r={x:0,y:0};ys(e=>{let t=this.getAxisMotionValue(e);if(t&&this.constraints!==!1){let n=t.get();r[e]=K({min:n,max:n},this.constraints[e])}});let{transformTemplate:i}=this.visualElement.getProps();this.visualElement.current.style.transform=i?i({},``):`none`,n.root&&n.root.updateScroll(),n.updateLayout(),this.constraints=!1,this.resolveConstraints(),ys(t=>{if(!Kl(t,e,null))return;let n=this.getAxisMotionValue(t),{min:i,max:a}=this.constraints[t];n.set(F(i,a,r[t]))}),this.visualElement.render()}addListeners(){if(!this.visualElement.current)return;Hl.set(this.visualElement,this);let e=this.visualElement.current,t=wl(e,`pointerdown`,t=>{let{drag:n,dragListener:r=!0}=this.getProps(),i=t.target,a=i!==e&&Yi(i);n&&r&&!a&&this.start(t)}),n,r=()=>{let{dragConstraints:t}=this.getProps();ll(t)&&t.current&&(this.constraints=this.resolveRefConstraints(),n||=Gl(e,t.current,()=>this.scalePositionWithinConstraints()))},{projection:i}=this.visualElement,a=i.addEventListener(`measure`,r);i&&!i.layout&&(i.root&&i.root.updateScroll(),i.updateLayout()),A.read(r);let o=As(window,`resize`,()=>this.scalePositionWithinConstraints()),s=i.addEventListener(`didUpdate`,(({delta:e,hasLayoutChanged:t})=>{this.isDragging&&t&&(ys(t=>{let n=this.getAxisMotionValue(t);n&&(this.originPoint[t]+=e[t].translate,n.set(n.get()+e[t].translate))}),this.visualElement.render())}));return()=>{o(),t(),a(),s&&s(),n&&n()}}getProps(){let e=this.visualElement.getProps(),{drag:t=!1,dragDirectionLock:n=!1,dragPropagation:r=!1,dragConstraints:i=!1,dragElastic:a=J,dragMomentum:o=!0}=e;return{...e,drag:t,dragDirectionLock:n,dragPropagation:r,dragConstraints:i,dragElastic:a,dragMomentum:o}}};function Wl(e){let t=!0;return()=>{if(t){t=!1;return}e()}}function Gl(e,t,n){let r=_a(e,Wl(n)),i=_a(t,Wl(n));return()=>{r(),i()}}function Kl(e,t,n){return(t===!0||t===e)&&(n===null||n===e)}function ql(e,t=10){let n=null;return Math.abs(e.y)>t?n=`y`:Math.abs(e.x)>t&&(n=`x`),n}var Jl=class extends Wa{constructor(e){super(e),this.removeGroupControls=E,this.removeListeners=E,this.controls=new Ul(e)}mount(){let{dragControls:e}=this.node.getProps();e&&(this.removeGroupControls=e.subscribe(this.controls)),this.removeListeners=this.controls.addListeners()||E}update(){let{dragControls:e}=this.node.getProps(),{dragControls:t}=this.node.prevProps||{};e!==t&&(this.removeGroupControls(),e&&(this.removeGroupControls=e.subscribe(this.controls)))}unmount(){this.removeGroupControls(),this.removeListeners(),this.controls.isDragging||this.controls.endPanSession()}},Yl=e=>(t,n)=>{e&&A.update(()=>e(t,n),!1,!0)},Xl=class extends Wa{constructor(){super(...arguments),this.removePointerDownListener=E}onPointerDown(e){this.session=new kl(e,this.createPanHandlers(),{transformPagePoint:this.node.getTransformPagePoint(),contextWindow:Tl(this.node)})}createPanHandlers(){let{onPanSessionStart:e,onPanStart:t,onPan:n,onPanEnd:r}=this.node.getProps();return{onSessionStart:Yl(e),onStart:Yl(t),onMove:Yl(n),onEnd:(e,t)=>{delete this.session,r&&A.postRender(()=>r(e,t))}}}mount(){this.removePointerDownListener=wl(this.node.current,`pointerdown`,e=>this.onPointerDown(e))}update(){this.session&&this.session.updateHandlers(this.createPanHandlers())}unmount(){this.removePointerDownListener(),this.session&&this.session.end()}},Zl=!1,Ql=class extends b.Component{componentDidMount(){let{visualElement:e,layoutGroup:t,switchLayoutGroup:n,layoutId:r}=this.props,{projection:i}=e;i&&(t.group&&t.group.add(i),n&&n.register&&r&&n.register(i),Zl&&i.root.didUpdate(),i.addEventListener(`animationComplete`,()=>{this.safeToRemove()}),i.setOptions({...i.options,layoutDependency:this.props.layoutDependency,onExitComplete:()=>this.safeToRemove()})),Is.hasEverUpdated=!0}getSnapshotBeforeUpdate(e){let{layoutDependency:t,visualElement:n,drag:r,isPresent:i}=this.props,{projection:a}=n;return a?(a.isPresent=i,e.layoutDependency!==t&&a.setOptions({...a.options,layoutDependency:t}),Zl=!0,r||e.layoutDependency!==t||t===void 0||e.isPresent!==i?a.willUpdate():this.safeToRemove(),e.isPresent!==i&&(i?a.promote():a.relegate()||A.postRender(()=>{let e=a.getStack();(!e||!e.members.length)&&this.safeToRemove()})),null):null}componentDidUpdate(){let{visualElement:e,layoutAnchor:t}=this.props,{projection:n}=e;n&&(n.options.layoutAnchor=t,n.root.didUpdate(),Ii.postRender(()=>{!n.currentAnimation&&n.isLead()&&this.safeToRemove()}))}componentWillUnmount(){let{visualElement:e,layoutGroup:t,switchLayoutGroup:n}=this.props,{projection:r}=e;Zl=!0,r&&(r.scheduleCheckAfterUnmount(),t&&t.group&&t.group.remove(r),n&&n.deregister&&n.deregister(r))}safeToRemove(){let{safeToRemove:e}=this.props;e&&e()}render(){return null}};function $l(e){let[t,n]=Sc(),r=(0,b.useContext)(w);return(0,H.jsx)(Ql,{...e,layoutGroup:r,switchLayoutGroup:(0,b.useContext)(W),isPresent:t,safeToRemove:n})}var eu={pan:{Feature:Xl},drag:{Feature:Jl,ProjectionNode:bc,MeasureLayout:$l}};function tu(e,t,n){let{props:r}=e;e.animationState&&r.whileHover&&e.animationState.setActive(`whileHover`,n===`Start`);let i=r[`onHover`+n];i&&A.postRender(()=>i(t,Sl(t)))}var nu=class extends Wa{mount(){let{current:e}=this.node;e&&(this.unmount=Ui(e,(e,t)=>(tu(this.node,t,`Start`),e=>tu(this.node,e,`End`))))}unmount(){}},ru=class extends Wa{constructor(){super(...arguments),this.isActive=!1}onFocus(){let e=!1;try{e=this.node.current.matches(`:focus-visible`)}catch{e=!0}!e||!this.node.animationState||(this.node.animationState.setActive(`whileFocus`,!0),this.isActive=!0)}onBlur(){!this.isActive||!this.node.animationState||(this.node.animationState.setActive(`whileFocus`,!1),this.isActive=!1)}mount(){this.unmount=D(As(this.node.current,`focus`,()=>this.onFocus()),As(this.node.current,`blur`,()=>this.onBlur()))}unmount(){}};function iu(e,t,n){let{props:r}=e;if(e.current instanceof HTMLButtonElement&&e.current.disabled)return;e.animationState&&r.whileTap&&e.animationState.setActive(`whileTap`,n===`Start`);let i=r[`onTap`+(n===`End`?``:n)];i&&A.postRender(()=>i(t,Sl(t)))}var au=class extends Wa{mount(){let{current:e}=this.node;if(!e)return;let{globalTapTarget:t,propagate:n}=this.node.props;this.unmount=na(e,(e,t)=>(iu(this.node,t,`Start`),(e,{success:t})=>iu(this.node,e,t?`End`:`Cancel`)),{useGlobalTarget:t,stopPropagation:n?.tap===!1})}unmount(){}},ou=new WeakMap,su=new WeakMap,cu=e=>{let t=ou.get(e.target);t&&t(e)},lu=e=>{e.forEach(cu)};function uu({root:e,...t}){let n=e||document;su.has(n)||su.set(n,{});let r=su.get(n),i=JSON.stringify(t);return r[i]||(r[i]=new IntersectionObserver(lu,{root:e,...t})),r[i]}function du(e,t,n){let r=uu(t);return ou.set(e,n),r.observe(e),()=>{ou.delete(e),r.unobserve(e)}}var fu={some:0,all:1},pu=class extends Wa{constructor(){super(...arguments),this.hasEnteredView=!1,this.isInView=!1}startObserver(){this.stopObserver?.();let{viewport:e={}}=this.node.getProps(),{root:t,margin:n,amount:r=`some`,once:i}=e,a={root:t?t.current:void 0,rootMargin:n,threshold:typeof r==`number`?r:fu[r]},o=e=>{let{isIntersecting:t}=e;if(this.isInView===t||(this.isInView=t,i&&!t&&this.hasEnteredView))return;t&&(this.hasEnteredView=!0),this.node.animationState&&this.node.animationState.setActive(`whileInView`,t);let{onViewportEnter:n,onViewportLeave:r}=this.node.getProps(),a=t?n:r;a&&a(e)};this.stopObserver=du(this.node.current,a,o)}mount(){this.startObserver()}update(){if(typeof IntersectionObserver>`u`)return;let{props:e,prevProps:t}=this.node;[`amount`,`margin`,`root`].some(mu(e,t))&&this.startObserver()}unmount(){this.stopObserver?.(),this.hasEnteredView=!1,this.isInView=!1}};function mu({viewport:e={}},{viewport:t={}}={}){return n=>e[n]!==t[n]}var hu={inView:{Feature:pu},tap:{Feature:au},focus:{Feature:ru},hover:{Feature:nu}},gu={layout:{ProjectionNode:bc,MeasureLayout:$l}},_u=_l({...xl,...hu,...eu,...gu},vl),vu=new Map([[`bold`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M208.49,152.49l-72,72a12,12,0,0,1-17,0l-72-72a12,12,0,0,1,17-17L116,187V40a12,12,0,0,1,24,0V187l51.51-51.52a12,12,0,0,1,17,17Z`}))],[`duotone`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M200,144l-72,72L56,144Z`,opacity:`0.2`}),b.createElement(`path`,{d:`M207.39,140.94A8,8,0,0,0,200,136H136V40a8,8,0,0,0-16,0v96H56a8,8,0,0,0-5.66,13.66l72,72a8,8,0,0,0,11.32,0l72-72A8,8,0,0,0,207.39,140.94ZM128,204.69,75.31,152H180.69Z`}))],[`fill`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M205.66,149.66l-72,72a8,8,0,0,1-11.32,0l-72-72A8,8,0,0,1,56,136h64V40a8,8,0,0,1,16,0v96h64a8,8,0,0,1,5.66,13.66Z`}))],[`light`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M204.24,148.24l-72,72a6,6,0,0,1-8.48,0l-72-72a6,6,0,0,1,8.48-8.48L122,201.51V40a6,6,0,0,1,12,0V201.51l61.76-61.75a6,6,0,0,1,8.48,8.48Z`}))],[`regular`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M205.66,149.66l-72,72a8,8,0,0,1-11.32,0l-72-72a8,8,0,0,1,11.32-11.32L120,196.69V40a8,8,0,0,1,16,0V196.69l58.34-58.35a8,8,0,0,1,11.32,11.32Z`}))],[`thin`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M202.83,146.83l-72,72a4,4,0,0,1-5.66,0l-72-72a4,4,0,0,1,5.66-5.66L124,206.34V40a4,4,0,0,1,8,0V206.34l65.17-65.17a4,4,0,0,1,5.66,5.66Z`}))]]),yu=new Map([[`bold`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M228,128a12,12,0,0,1-12,12H69l51.52,51.51a12,12,0,0,1-17,17l-72-72a12,12,0,0,1,0-17l72-72a12,12,0,0,1,17,17L69,116H216A12,12,0,0,1,228,128Z`}))],[`duotone`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M112,56V200L40,128Z`,opacity:`0.2`}),b.createElement(`path`,{d:`M216,120H120V56a8,8,0,0,0-13.66-5.66l-72,72a8,8,0,0,0,0,11.32l72,72A8,8,0,0,0,120,200V136h96a8,8,0,0,0,0-16ZM104,180.69,51.31,128,104,75.31Z`}))],[`fill`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M224,128a8,8,0,0,1-8,8H120v64a8,8,0,0,1-13.66,5.66l-72-72a8,8,0,0,1,0-11.32l72-72A8,8,0,0,1,120,56v64h96A8,8,0,0,1,224,128Z`}))],[`light`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M222,128a6,6,0,0,1-6,6H54.49l61.75,61.76a6,6,0,1,1-8.48,8.48l-72-72a6,6,0,0,1,0-8.48l72-72a6,6,0,0,1,8.48,8.48L54.49,122H216A6,6,0,0,1,222,128Z`}))],[`regular`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M224,128a8,8,0,0,1-8,8H59.31l58.35,58.34a8,8,0,0,1-11.32,11.32l-72-72a8,8,0,0,1,0-11.32l72-72a8,8,0,0,1,11.32,11.32L59.31,120H216A8,8,0,0,1,224,128Z`}))],[`thin`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M220,128a4,4,0,0,1-4,4H49.66l65.17,65.17a4,4,0,0,1-5.66,5.66l-72-72a4,4,0,0,1,0-5.66l72-72a4,4,0,0,1,5.66,5.66L49.66,124H216A4,4,0,0,1,220,128Z`}))]]),bu=new Map([[`bold`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M224.49,136.49l-72,72a12,12,0,0,1-17-17L187,140H40a12,12,0,0,1,0-24H187L135.51,64.48a12,12,0,0,1,17-17l72,72A12,12,0,0,1,224.49,136.49Z`}))],[`duotone`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M216,128l-72,72V56Z`,opacity:`0.2`}),b.createElement(`path`,{d:`M221.66,122.34l-72-72A8,8,0,0,0,136,56v64H40a8,8,0,0,0,0,16h96v64a8,8,0,0,0,13.66,5.66l72-72A8,8,0,0,0,221.66,122.34ZM152,180.69V75.31L204.69,128Z`}))],[`fill`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M221.66,133.66l-72,72A8,8,0,0,1,136,200V136H40a8,8,0,0,1,0-16h96V56a8,8,0,0,1,13.66-5.66l72,72A8,8,0,0,1,221.66,133.66Z`}))],[`light`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M220.24,132.24l-72,72a6,6,0,0,1-8.48-8.48L201.51,134H40a6,6,0,0,1,0-12H201.51L139.76,60.24a6,6,0,0,1,8.48-8.48l72,72A6,6,0,0,1,220.24,132.24Z`}))],[`regular`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M221.66,133.66l-72,72a8,8,0,0,1-11.32-11.32L196.69,136H40a8,8,0,0,1,0-16H196.69L138.34,61.66a8,8,0,0,1,11.32-11.32l72,72A8,8,0,0,1,221.66,133.66Z`}))],[`thin`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M218.83,130.83l-72,72a4,4,0,0,1-5.66-5.66L206.34,132H40a4,4,0,0,1,0-8H206.34L141.17,58.83a4,4,0,0,1,5.66-5.66l72,72A4,4,0,0,1,218.83,130.83Z`}))]]),xu=new Map([[`bold`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M208.49,120.49a12,12,0,0,1-17,0L140,69V216a12,12,0,0,1-24,0V69L64.49,120.49a12,12,0,0,1-17-17l72-72a12,12,0,0,1,17,0l72,72A12,12,0,0,1,208.49,120.49Z`}))],[`duotone`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M200,112H56l72-72Z`,opacity:`0.2`}),b.createElement(`path`,{d:`M205.66,106.34l-72-72a8,8,0,0,0-11.32,0l-72,72A8,8,0,0,0,56,120h64v96a8,8,0,0,0,16,0V120h64a8,8,0,0,0,5.66-13.66ZM75.31,104,128,51.31,180.69,104Z`}))],[`fill`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M207.39,115.06A8,8,0,0,1,200,120H136v96a8,8,0,0,1-16,0V120H56a8,8,0,0,1-5.66-13.66l72-72a8,8,0,0,1,11.32,0l72,72A8,8,0,0,1,207.39,115.06Z`}))],[`light`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M204.24,116.24a6,6,0,0,1-8.48,0L134,54.49V216a6,6,0,0,1-12,0V54.49L60.24,116.24a6,6,0,0,1-8.48-8.48l72-72a6,6,0,0,1,8.48,0l72,72A6,6,0,0,1,204.24,116.24Z`}))],[`regular`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M205.66,117.66a8,8,0,0,1-11.32,0L136,59.31V216a8,8,0,0,1-16,0V59.31L61.66,117.66a8,8,0,0,1-11.32-11.32l72-72a8,8,0,0,1,11.32,0l72,72A8,8,0,0,1,205.66,117.66Z`}))],[`thin`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M202.83,114.83a4,4,0,0,1-5.66,0L132,49.66V216a4,4,0,0,1-8,0V49.66L58.83,114.83a4,4,0,0,1-5.66-5.66l72-72a4,4,0,0,1,5.66,0l72,72A4,4,0,0,1,202.83,114.83Z`}))]]),Su=new Map([[`bold`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M236,208a12,12,0,0,1-12,12H32a12,12,0,0,1-12-12V48a12,12,0,0,1,24,0v99l43.51-43.52a12,12,0,0,1,17,0L128,127l43-43H160a12,12,0,0,1,0-24h40a12,12,0,0,1,12,12v40a12,12,0,0,1-24,0V101l-51.51,51.52a12,12,0,0,1-17,0L96,129,44,181v15H224A12,12,0,0,1,236,208Z`}))],[`duotone`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M224,64V208H32V48H208A16,16,0,0,1,224,64Z`,opacity:`0.2`}),b.createElement(`path`,{d:`M232,208a8,8,0,0,1-8,8H32a8,8,0,0,1-8-8V48a8,8,0,0,1,16,0V156.69l50.34-50.35a8,8,0,0,1,11.32,0L128,132.69,180.69,80H160a8,8,0,0,1,0-16h40a8,8,0,0,1,8,8v40a8,8,0,0,1-16,0V91.31l-58.34,58.35a8,8,0,0,1-11.32,0L96,123.31l-56,56V200H224A8,8,0,0,1,232,208Z`}))],[`fill`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M216,40H40A16,16,0,0,0,24,56V200a16,16,0,0,0,16,16H216a16,16,0,0,0,16-16V56A16,16,0,0,0,216,40ZM200,192H56a8,8,0,0,1-8-8V72a8,8,0,0,1,16,0v76.69l34.34-34.35a8,8,0,0,1,11.32,0L128,132.69,172.69,88H144a8,8,0,0,1,0-16h48a8,8,0,0,1,8,8v48a8,8,0,0,1-16,0V99.31l-50.34,50.35a8,8,0,0,1-11.32,0L104,131.31l-40,40V176H200a8,8,0,0,1,0,16Z`}))],[`light`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M230,208a6,6,0,0,1-6,6H32a6,6,0,0,1-6-6V48a6,6,0,0,1,12,0V161.52l53.76-53.76a6,6,0,0,1,8.48,0L128,135.51,185.52,78H160a6,6,0,0,1,0-12h40a6,6,0,0,1,6,6v40a6,6,0,0,1-12,0V86.48l-61.76,61.76a6,6,0,0,1-8.48,0L96,120.49l-58,58V202H224A6,6,0,0,1,230,208Z`}))],[`regular`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M232,208a8,8,0,0,1-8,8H32a8,8,0,0,1-8-8V48a8,8,0,0,1,16,0V156.69l50.34-50.35a8,8,0,0,1,11.32,0L128,132.69,180.69,80H160a8,8,0,0,1,0-16h40a8,8,0,0,1,8,8v40a8,8,0,0,1-16,0V91.31l-58.34,58.35a8,8,0,0,1-11.32,0L96,123.31l-56,56V200H224A8,8,0,0,1,232,208Z`}))],[`thin`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M228,208a4,4,0,0,1-4,4H32a4,4,0,0,1-4-4V48a4,4,0,0,1,8,0V166.34l57.17-57.17a4,4,0,0,1,5.66,0L128,138.34,190.34,76H160a4,4,0,0,1,0-8h40a4,4,0,0,1,4,4v40a4,4,0,0,1-8,0V81.66l-65.17,65.17a4,4,0,0,1-5.66,0L96,117.66l-60,60V204H224A4,4,0,0,1,228,208Z`}))]]),Cu=new Map([[`bold`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M232.49,80.49l-128,128a12,12,0,0,1-17,0l-56-56a12,12,0,1,1,17-17L96,183,215.51,63.51a12,12,0,0,1,17,17Z`}))],[`duotone`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M232,56V200a16,16,0,0,1-16,16H40a16,16,0,0,1-16-16V56A16,16,0,0,1,40,40H216A16,16,0,0,1,232,56Z`,opacity:`0.2`}),b.createElement(`path`,{d:`M205.66,85.66l-96,96a8,8,0,0,1-11.32,0l-40-40a8,8,0,0,1,11.32-11.32L104,164.69l90.34-90.35a8,8,0,0,1,11.32,11.32Z`}))],[`fill`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M216,40H40A16,16,0,0,0,24,56V200a16,16,0,0,0,16,16H216a16,16,0,0,0,16-16V56A16,16,0,0,0,216,40ZM205.66,85.66l-96,96a8,8,0,0,1-11.32,0l-40-40a8,8,0,0,1,11.32-11.32L104,164.69l90.34-90.35a8,8,0,0,1,11.32,11.32Z`}))],[`light`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M228.24,76.24l-128,128a6,6,0,0,1-8.48,0l-56-56a6,6,0,0,1,8.48-8.48L96,191.51,219.76,67.76a6,6,0,0,1,8.48,8.48Z`}))],[`regular`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M229.66,77.66l-128,128a8,8,0,0,1-11.32,0l-56-56a8,8,0,0,1,11.32-11.32L96,188.69,218.34,66.34a8,8,0,0,1,11.32,11.32Z`}))],[`thin`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M226.83,74.83l-128,128a4,4,0,0,1-5.66,0l-56-56a4,4,0,0,1,5.66-5.66L96,194.34,221.17,69.17a4,4,0,1,1,5.66,5.66Z`}))]]),wu=new Map([[`bold`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M176.49,95.51a12,12,0,0,1,0,17l-56,56a12,12,0,0,1-17,0l-24-24a12,12,0,1,1,17-17L112,143l47.51-47.52A12,12,0,0,1,176.49,95.51ZM236,128A108,108,0,1,1,128,20,108.12,108.12,0,0,1,236,128Zm-24,0a84,84,0,1,0-84,84A84.09,84.09,0,0,0,212,128Z`}))],[`duotone`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M224,128a96,96,0,1,1-96-96A96,96,0,0,1,224,128Z`,opacity:`0.2`}),b.createElement(`path`,{d:`M173.66,98.34a8,8,0,0,1,0,11.32l-56,56a8,8,0,0,1-11.32,0l-24-24a8,8,0,0,1,11.32-11.32L112,148.69l50.34-50.35A8,8,0,0,1,173.66,98.34ZM232,128A104,104,0,1,1,128,24,104.11,104.11,0,0,1,232,128Zm-16,0a88,88,0,1,0-88,88A88.1,88.1,0,0,0,216,128Z`}))],[`fill`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm45.66,85.66-56,56a8,8,0,0,1-11.32,0l-24-24a8,8,0,0,1,11.32-11.32L112,148.69l50.34-50.35a8,8,0,0,1,11.32,11.32Z`}))],[`light`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M172.24,99.76a6,6,0,0,1,0,8.48l-56,56a6,6,0,0,1-8.48,0l-24-24a6,6,0,0,1,8.48-8.48L112,151.51l51.76-51.75A6,6,0,0,1,172.24,99.76ZM230,128A102,102,0,1,1,128,26,102.12,102.12,0,0,1,230,128Zm-12,0a90,90,0,1,0-90,90A90.1,90.1,0,0,0,218,128Z`}))],[`regular`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M173.66,98.34a8,8,0,0,1,0,11.32l-56,56a8,8,0,0,1-11.32,0l-24-24a8,8,0,0,1,11.32-11.32L112,148.69l50.34-50.35A8,8,0,0,1,173.66,98.34ZM232,128A104,104,0,1,1,128,24,104.11,104.11,0,0,1,232,128Zm-16,0a88,88,0,1,0-88,88A88.1,88.1,0,0,0,216,128Z`}))],[`thin`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M170.83,101.17a4,4,0,0,1,0,5.66l-56,56a4,4,0,0,1-5.66,0l-24-24a4,4,0,0,1,5.66-5.66L112,154.34l53.17-53.17A4,4,0,0,1,170.83,101.17ZM228,128A100,100,0,1,1,128,28,100.11,100.11,0,0,1,228,128Zm-8,0a92,92,0,1,0-92,92A92.1,92.1,0,0,0,220,128Z`}))]]),Tu=new Map([[`bold`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M236,137A108.13,108.13,0,1,1,119,20,12,12,0,0,1,121,44,84.12,84.12,0,1,0,212,135,12,12,0,1,1,236,137ZM116,76v52a12,12,0,0,0,12,12h52a12,12,0,0,0,0-24H140V76a12,12,0,0,0-24,0Zm92,20a16,16,0,1,0-16-16A16,16,0,0,0,208,96ZM176,64a16,16,0,1,0-16-16A16,16,0,0,0,176,64Z`}))],[`duotone`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M224,128a96,96,0,1,1-96-96A96,96,0,0,1,224,128Z`,opacity:`0.2`}),b.createElement(`path`,{d:`M232,136.66A104.12,104.12,0,1,1,119.34,24,8,8,0,0,1,120.66,40,88.12,88.12,0,1,0,216,135.34,8,8,0,0,1,232,136.66ZM120,72v56a8,8,0,0,0,8,8h56a8,8,0,0,0,0-16H136V72a8,8,0,0,0-16,0Zm40-24a12,12,0,1,0-12-12A12,12,0,0,0,160,48Zm36,24a12,12,0,1,0-12-12A12,12,0,0,0,196,72Zm24,36a12,12,0,1,0-12-12A12,12,0,0,0,220,108Z`}))],[`fill`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M208,96a12,12,0,1,1,12,12A12,12,0,0,1,208,96ZM196,72a12,12,0,1,0-12-12A12,12,0,0,0,196,72Zm28.66,56a8,8,0,0,0-8.63,7.31A88.12,88.12,0,1,1,120.66,40,8,8,0,0,0,119.34,24,104.12,104.12,0,1,0,232,136.66,8,8,0,0,0,224.66,128ZM128,56a72,72,0,1,1-72,72A72.08,72.08,0,0,1,128,56Zm-8,72a8,8,0,0,0,8,8h48a8,8,0,0,0,0-16H136V80a8,8,0,0,0-16,0Zm40-80a12,12,0,1,0-12-12A12,12,0,0,0,160,48Z`}))],[`light`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M230,136.49A102.12,102.12,0,1,1,119.51,26a6,6,0,0,1,1,12A90.13,90.13,0,1,0,218,135.51a6,6,0,1,1,12,1ZM122,72v56a6,6,0,0,0,6,6h56a6,6,0,0,0,0-12H134V72a6,6,0,0,0-12,0Zm38-26a10,10,0,1,0-10-10A10,10,0,0,0,160,46Zm36,24a10,10,0,1,0-10-10A10,10,0,0,0,196,70Zm24,36a10,10,0,1,0-10-10A10,10,0,0,0,220,106Z`}))],[`regular`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M232,136.66A104.12,104.12,0,1,1,119.34,24,8,8,0,0,1,120.66,40,88.12,88.12,0,1,0,216,135.34,8,8,0,0,1,232,136.66ZM120,72v56a8,8,0,0,0,8,8h56a8,8,0,0,0,0-16H136V72a8,8,0,0,0-16,0Zm40-24a12,12,0,1,0-12-12A12,12,0,0,0,160,48Zm36,24a12,12,0,1,0-12-12A12,12,0,0,0,196,72Zm24,36a12,12,0,1,0-12-12A12,12,0,0,0,220,108Z`}))],[`thin`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M228,136.33A100.13,100.13,0,1,1,119.67,28a4,4,0,1,1,.66,8A92.13,92.13,0,1,0,220,135.67a4,4,0,1,1,8,.66ZM128,132h56a4,4,0,0,0,0-8H132V72a4,4,0,0,0-8,0v56A4,4,0,0,0,128,132Zm32-88a8,8,0,1,0-8-8A8,8,0,0,0,160,44Zm36,24a8,8,0,1,0-8-8A8,8,0,0,0,196,68Zm24,36a8,8,0,1,0-8-8A8,8,0,0,0,220,104Z`}))]]),Eu=new Map([[`bold`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M178,36c-20.09,0-37.92,7.93-50,21.56C115.92,43.93,98.09,36,78,36a66.08,66.08,0,0,0-66,66c0,72.34,105.81,130.14,110.31,132.57a12,12,0,0,0,11.38,0C138.19,232.14,244,174.34,244,102A66.08,66.08,0,0,0,178,36Zm-5.49,142.36A328.69,328.69,0,0,1,128,210.16a328.69,328.69,0,0,1-44.51-31.8C61.82,159.77,36,131.42,36,102A42,42,0,0,1,78,60c17.8,0,32.7,9.4,38.89,24.54a12,12,0,0,0,22.22,0C145.3,69.4,160.2,60,178,60a42,42,0,0,1,42,42C220,131.42,194.18,159.77,172.51,178.36Z`}))],[`duotone`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M232,102c0,66-104,122-104,122S24,168,24,102A54,54,0,0,1,78,48c22.59,0,41.94,12.31,50,32,8.06-19.69,27.41-32,50-32A54,54,0,0,1,232,102Z`,opacity:`0.2`}),b.createElement(`path`,{d:`M178,40c-20.65,0-38.73,8.88-50,23.89C116.73,48.88,98.65,40,78,40a62.07,62.07,0,0,0-62,62c0,70,103.79,126.66,108.21,129a8,8,0,0,0,7.58,0C136.21,228.66,240,172,240,102A62.07,62.07,0,0,0,178,40ZM128,214.8C109.74,204.16,32,155.69,32,102A46.06,46.06,0,0,1,78,56c19.45,0,35.78,10.36,42.6,27a8,8,0,0,0,14.8,0c6.82-16.67,23.15-27,42.6-27a46.06,46.06,0,0,1,46,46C224,155.61,146.24,204.15,128,214.8Z`}))],[`fill`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M240,102c0,70-103.79,126.66-108.21,129a8,8,0,0,1-7.58,0C119.79,228.66,16,172,16,102A62.07,62.07,0,0,1,78,40c20.65,0,38.73,8.88,50,23.89C139.27,48.88,157.35,40,178,40A62.07,62.07,0,0,1,240,102Z`}))],[`light`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M178,42c-21,0-39.26,9.47-50,25.34C117.26,51.47,99,42,78,42a60.07,60.07,0,0,0-60,60c0,29.2,18.2,59.59,54.1,90.31a334.68,334.68,0,0,0,53.06,37,6,6,0,0,0,5.68,0,334.68,334.68,0,0,0,53.06-37C219.8,161.59,238,131.2,238,102A60.07,60.07,0,0,0,178,42ZM128,217.11C111.59,207.64,30,157.72,30,102A48.05,48.05,0,0,1,78,54c20.28,0,37.31,10.83,44.45,28.27a6,6,0,0,0,11.1,0C140.69,64.83,157.72,54,178,54a48.05,48.05,0,0,1,48,48C226,157.72,144.41,207.64,128,217.11Z`}))],[`regular`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M178,40c-20.65,0-38.73,8.88-50,23.89C116.73,48.88,98.65,40,78,40a62.07,62.07,0,0,0-62,62c0,70,103.79,126.66,108.21,129a8,8,0,0,0,7.58,0C136.21,228.66,240,172,240,102A62.07,62.07,0,0,0,178,40ZM128,214.8C109.74,204.16,32,155.69,32,102A46.06,46.06,0,0,1,78,56c19.45,0,35.78,10.36,42.6,27a8,8,0,0,0,14.8,0c6.82-16.67,23.15-27,42.6-27a46.06,46.06,0,0,1,46,46C224,155.61,146.24,204.15,128,214.8Z`}))],[`thin`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M178,44c-21.44,0-39.92,10.19-50,27.07C117.92,54.19,99.44,44,78,44a58.07,58.07,0,0,0-58,58c0,28.59,18,58.47,53.4,88.79a333.81,333.81,0,0,0,52.7,36.73,4,4,0,0,0,3.8,0,333.81,333.81,0,0,0,52.7-36.73C218,160.47,236,130.59,236,102A58.07,58.07,0,0,0,178,44ZM128,219.42c-14-8-100-59.35-100-117.42A50.06,50.06,0,0,1,78,52c21.11,0,38.85,11.31,46.3,29.51a4,4,0,0,0,7.4,0C139.15,63.31,156.89,52,178,52a50.06,50.06,0,0,1,50,50C228,160,142,211.46,128,219.42Z`}))]]),Du=new Map([[`bold`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M208,76H180V56A52,52,0,0,0,76,56V76H48A20,20,0,0,0,28,96V208a20,20,0,0,0,20,20H208a20,20,0,0,0,20-20V96A20,20,0,0,0,208,76ZM100,56a28,28,0,0,1,56,0V76H100ZM204,204H52V100H204Zm-76-92a32,32,0,0,0-12,61.66V180a12,12,0,0,0,24,0v-6.34A32,32,0,0,0,128,112Zm0,24a8,8,0,1,1-8,8A8,8,0,0,1,128,136Z`}))],[`duotone`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M208,88H48a8,8,0,0,0-8,8V208a8,8,0,0,0,8,8H208a8,8,0,0,0,8-8V96A8,8,0,0,0,208,88Zm-80,72a20,20,0,1,1,20-20A20,20,0,0,1,128,160Z`,opacity:`0.2`}),b.createElement(`path`,{d:`M208,80H176V56a48,48,0,0,0-96,0V80H48A16,16,0,0,0,32,96V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V96A16,16,0,0,0,208,80ZM96,56a32,32,0,0,1,64,0V80H96ZM208,208H48V96H208V208Zm-80-96a28,28,0,0,0-8,54.83V184a8,8,0,0,0,16,0V166.83A28,28,0,0,0,128,112Zm0,40a12,12,0,1,1,12-12A12,12,0,0,1,128,152Z`}))],[`fill`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M208,80H176V56a48,48,0,0,0-96,0V80H48A16,16,0,0,0,32,96V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V96A16,16,0,0,0,208,80Zm-72,78.63V184a8,8,0,0,1-16,0V158.63a24,24,0,1,1,16,0ZM160,80H96V56a32,32,0,0,1,64,0Z`}))],[`light`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M208,82H174V56a46,46,0,0,0-92,0V82H48A14,14,0,0,0,34,96V208a14,14,0,0,0,14,14H208a14,14,0,0,0,14-14V96A14,14,0,0,0,208,82ZM94,56a34,34,0,0,1,68,0V82H94ZM210,208a2,2,0,0,1-2,2H48a2,2,0,0,1-2-2V96a2,2,0,0,1,2-2H208a2,2,0,0,1,2,2Zm-82-94a26,26,0,0,0-6,51.29V184a6,6,0,0,0,12,0V165.29A26,26,0,0,0,128,114Zm0,40a14,14,0,1,1,14-14A14,14,0,0,1,128,154Z`}))],[`regular`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M128,112a28,28,0,0,0-8,54.83V184a8,8,0,0,0,16,0V166.83A28,28,0,0,0,128,112Zm0,40a12,12,0,1,1,12-12A12,12,0,0,1,128,152Zm80-72H176V56a48,48,0,0,0-96,0V80H48A16,16,0,0,0,32,96V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V96A16,16,0,0,0,208,80ZM96,56a32,32,0,0,1,64,0V80H96ZM208,208H48V96H208V208Z`}))],[`thin`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M208,84H172V56a44,44,0,0,0-88,0V84H48A12,12,0,0,0,36,96V208a12,12,0,0,0,12,12H208a12,12,0,0,0,12-12V96A12,12,0,0,0,208,84ZM92,56a36,36,0,0,1,72,0V84H92ZM212,208a4,4,0,0,1-4,4H48a4,4,0,0,1-4-4V96a4,4,0,0,1,4-4H208a4,4,0,0,1,4,4Zm-84-92a24,24,0,0,0-4,47.66V184a4,4,0,0,0,8,0V163.66A24,24,0,0,0,128,116Zm0,40a16,16,0,1,1,16-16A16,16,0,0,1,128,156Z`}))]]),Ou=new Map([[`bold`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M228,128a12,12,0,0,1-12,12H40a12,12,0,0,1,0-24H216A12,12,0,0,1,228,128Z`}))],[`duotone`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M216,56V200a16,16,0,0,1-16,16H56a16,16,0,0,1-16-16V56A16,16,0,0,1,56,40H200A16,16,0,0,1,216,56Z`,opacity:`0.2`}),b.createElement(`path`,{d:`M224,128a8,8,0,0,1-8,8H40a8,8,0,0,1,0-16H216A8,8,0,0,1,224,128Z`}))],[`fill`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M208,32H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM184,136H72a8,8,0,0,1,0-16H184a8,8,0,0,1,0,16Z`}))],[`light`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M222,128a6,6,0,0,1-6,6H40a6,6,0,0,1,0-12H216A6,6,0,0,1,222,128Z`}))],[`regular`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M224,128a8,8,0,0,1-8,8H40a8,8,0,0,1,0-16H216A8,8,0,0,1,224,128Z`}))],[`thin`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M220,128a4,4,0,0,1-4,4H40a4,4,0,0,1,0-8H216A4,4,0,0,1,220,128Z`}))]]),ku=new Map([[`bold`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M200,164a36.07,36.07,0,0,0-33.94,24H72a28,28,0,0,1,0-56h96a44,44,0,0,0,0-88H72a12,12,0,0,0,0,24h96a20,20,0,0,1,0,40H72a52,52,0,0,0,0,104h94.06A36,36,0,1,0,200,164Zm0,48a12,12,0,1,1,12-12A12,12,0,0,1,200,212Z`}))],[`duotone`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M224,200a24,24,0,1,1-24-24A24,24,0,0,1,224,200Z`,opacity:`0.2`}),b.createElement(`path`,{d:`M200,168a32.06,32.06,0,0,0-31,24H72a32,32,0,0,1,0-64h96a40,40,0,0,0,0-80H72a8,8,0,0,0,0,16h96a24,24,0,0,1,0,48H72a48,48,0,0,0,0,96h97a32,32,0,1,0,31-40Zm0,48a16,16,0,1,1,16-16A16,16,0,0,1,200,216Z`}))],[`fill`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M228,200a28,28,0,0,1-54.83,8H72a48,48,0,0,1,0-96h96a24,24,0,0,0,0-48H72a8,8,0,0,1,0-16h96a40,40,0,0,1,0,80H72a32,32,0,0,0,0,64H173.17A28,28,0,0,1,228,200Z`}))],[`light`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M200,170a30.05,30.05,0,0,0-29.4,24H72a34,34,0,0,1,0-68h96a38,38,0,0,0,0-76H72a6,6,0,0,0,0,12h96a26,26,0,0,1,0,52H72a46,46,0,0,0,0,92h98.6A30,30,0,1,0,200,170Zm0,48a18,18,0,1,1,18-18A18,18,0,0,1,200,218Z`}))],[`regular`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M200,168a32.06,32.06,0,0,0-31,24H72a32,32,0,0,1,0-64h96a40,40,0,0,0,0-80H72a8,8,0,0,0,0,16h96a24,24,0,0,1,0,48H72a48,48,0,0,0,0,96h97a32,32,0,1,0,31-40Zm0,48a16,16,0,1,1,16-16A16,16,0,0,1,200,216Z`}))],[`thin`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M200,172a28,28,0,0,0-27.71,24H72a36,36,0,0,1,0-72h96a36,36,0,0,0,0-72H72a4,4,0,0,0,0,8h96a28,28,0,0,1,0,56H72a44,44,0,0,0,0,88H172.29A28,28,0,1,0,200,172Zm0,48a20,20,0,1,1,20-20A20,20,0,0,1,200,220Z`}))]]),Au=new Map([[`bold`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M199,125.31l-49.88-18.39L130.69,57a19.92,19.92,0,0,0-37.38,0L74.92,106.92,25,125.31a19.92,19.92,0,0,0,0,37.38l49.88,18.39L93.31,231a19.92,19.92,0,0,0,37.38,0l18.39-49.88L199,162.69a19.92,19.92,0,0,0,0-37.38Zm-63.38,35.16a12,12,0,0,0-7.11,7.11L112,212.28l-16.47-44.7a12,12,0,0,0-7.11-7.11L43.72,144l44.7-16.47a12,12,0,0,0,7.11-7.11L112,75.72l16.47,44.7a12,12,0,0,0,7.11,7.11L180.28,144ZM140,40a12,12,0,0,1,12-12h12V16a12,12,0,0,1,24,0V28h12a12,12,0,0,1,0,24H188V64a12,12,0,0,1-24,0V52H152A12,12,0,0,1,140,40ZM252,88a12,12,0,0,1-12,12h-4v4a12,12,0,0,1-24,0v-4h-4a12,12,0,0,1,0-24h4V72a12,12,0,0,1,24,0v4h4A12,12,0,0,1,252,88Z`}))],[`duotone`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M194.82,151.43l-55.09,20.3-20.3,55.09a7.92,7.92,0,0,1-14.86,0l-20.3-55.09-55.09-20.3a7.92,7.92,0,0,1,0-14.86l55.09-20.3,20.3-55.09a7.92,7.92,0,0,1,14.86,0l20.3,55.09,55.09,20.3A7.92,7.92,0,0,1,194.82,151.43Z`,opacity:`0.2`}),b.createElement(`path`,{d:`M197.58,129.06,146,110l-19-51.62a15.92,15.92,0,0,0-29.88,0L78,110l-51.62,19a15.92,15.92,0,0,0,0,29.88L78,178l19,51.62a15.92,15.92,0,0,0,29.88,0L146,178l51.62-19a15.92,15.92,0,0,0,0-29.88ZM137,164.22a8,8,0,0,0-4.74,4.74L112,223.85,91.78,169A8,8,0,0,0,87,164.22L32.15,144,87,123.78A8,8,0,0,0,91.78,119L112,64.15,132.22,119a8,8,0,0,0,4.74,4.74L191.85,144ZM144,40a8,8,0,0,1,8-8h16V16a8,8,0,0,1,16,0V32h16a8,8,0,0,1,0,16H184V64a8,8,0,0,1-16,0V48H152A8,8,0,0,1,144,40ZM248,88a8,8,0,0,1-8,8h-8v8a8,8,0,0,1-16,0V96h-8a8,8,0,0,1,0-16h8V72a8,8,0,0,1,16,0v8h8A8,8,0,0,1,248,88Z`}))],[`fill`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M208,144a15.78,15.78,0,0,1-10.42,14.94L146,178l-19,51.62a15.92,15.92,0,0,1-29.88,0L78,178l-51.62-19a15.92,15.92,0,0,1,0-29.88L78,110l19-51.62a15.92,15.92,0,0,1,29.88,0L146,110l51.62,19A15.78,15.78,0,0,1,208,144ZM152,48h16V64a8,8,0,0,0,16,0V48h16a8,8,0,0,0,0-16H184V16a8,8,0,0,0-16,0V32H152a8,8,0,0,0,0,16Zm88,32h-8V72a8,8,0,0,0-16,0v8h-8a8,8,0,0,0,0,16h8v8a8,8,0,0,0,16,0V96h8a8,8,0,0,0,0-16Z`}))],[`light`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M196.89,130.94,144.4,111.6,125.06,59.11a13.92,13.92,0,0,0-26.12,0L79.6,111.6,27.11,130.94a13.92,13.92,0,0,0,0,26.12L79.6,176.4l19.34,52.49a13.92,13.92,0,0,0,26.12,0L144.4,176.4l52.49-19.34a13.92,13.92,0,0,0,0-26.12Zm-4.15,14.86-55.08,20.3a6,6,0,0,0-3.56,3.56l-20.3,55.08a1.92,1.92,0,0,1-3.6,0L89.9,169.66a6,6,0,0,0-3.56-3.56L31.26,145.8a1.92,1.92,0,0,1,0-3.6l55.08-20.3a6,6,0,0,0,3.56-3.56l20.3-55.08a1.92,1.92,0,0,1,3.6,0l20.3,55.08a6,6,0,0,0,3.56,3.56l55.08,20.3a1.92,1.92,0,0,1,0,3.6ZM146,40a6,6,0,0,1,6-6h18V16a6,6,0,0,1,12,0V34h18a6,6,0,0,1,0,12H182V64a6,6,0,0,1-12,0V46H152A6,6,0,0,1,146,40ZM246,88a6,6,0,0,1-6,6H230v10a6,6,0,0,1-12,0V94H208a6,6,0,0,1,0-12h10V72a6,6,0,0,1,12,0V82h10A6,6,0,0,1,246,88Z`}))],[`regular`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M197.58,129.06,146,110l-19-51.62a15.92,15.92,0,0,0-29.88,0L78,110l-51.62,19a15.92,15.92,0,0,0,0,29.88L78,178l19,51.62a15.92,15.92,0,0,0,29.88,0L146,178l51.62-19a15.92,15.92,0,0,0,0-29.88ZM137,164.22a8,8,0,0,0-4.74,4.74L112,223.85,91.78,169A8,8,0,0,0,87,164.22L32.15,144,87,123.78A8,8,0,0,0,91.78,119L112,64.15,132.22,119a8,8,0,0,0,4.74,4.74L191.85,144ZM144,40a8,8,0,0,1,8-8h16V16a8,8,0,0,1,16,0V32h16a8,8,0,0,1,0,16H184V64a8,8,0,0,1-16,0V48H152A8,8,0,0,1,144,40ZM248,88a8,8,0,0,1-8,8h-8v8a8,8,0,0,1-16,0V96h-8a8,8,0,0,1,0-16h8V72a8,8,0,0,1,16,0v8h8A8,8,0,0,1,248,88Z`}))],[`thin`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M196.2,132.81l-53.36-19.65L123.19,59.8a11.93,11.93,0,0,0-22.38,0L81.16,113.16,27.8,132.81a11.93,11.93,0,0,0,0,22.38l53.36,19.65,19.65,53.36a11.93,11.93,0,0,0,22.38,0l19.65-53.36,53.36-19.65a11.93,11.93,0,0,0,0-22.38Zm-2.77,14.87L138.35,168a4,4,0,0,0-2.37,2.37l-20.3,55.08a3.92,3.92,0,0,1-7.36,0L88,170.35A4,4,0,0,0,85.65,168l-55.08-20.3a3.92,3.92,0,0,1,0-7.36L85.65,120A4,4,0,0,0,88,117.65l20.3-55.08a3.92,3.92,0,0,1,7.36,0L136,117.65a4,4,0,0,0,2.37,2.37l55.08,20.3a3.92,3.92,0,0,1,0,7.36ZM148,40a4,4,0,0,1,4-4h20V16a4,4,0,0,1,8,0V36h20a4,4,0,0,1,0,8H180V64a4,4,0,0,1-8,0V44H152A4,4,0,0,1,148,40Zm96,48a4,4,0,0,1-4,4H228v12a4,4,0,0,1-8,0V92H208a4,4,0,0,1,0-8h12V72a4,4,0,0,1,8,0V84h12A4,4,0,0,1,244,88Z`}))]]),ju=new Map([[`bold`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M119.51,143.51l88-88a12,12,0,1,1,17,17l-88,88a12,12,0,1,1-17-17Zm14.23-43.2a12,12,0,1,0,2.62-23.85A75.15,75.15,0,0,0,128,76a76.08,76.08,0,0,0-76,76,12,12,0,0,0,24,0,52.06,52.06,0,0,1,52-52A54.75,54.75,0,0,1,133.74,100.31Zm101.54,7.5A12,12,0,0,0,213.09,117a92.47,92.47,0,0,1,2.58,63H40.34A92.23,92.23,0,0,1,128,60h.84a91.43,91.43,0,0,1,34.2,6.91,12,12,0,0,0,9.14-22.19A116.07,116.07,0,0,0,18.57,190.58,20.09,20.09,0,0,0,37.46,204H218.53a20.06,20.06,0,0,0,18.88-13.38,116.39,116.39,0,0,0-2.13-82.81Z`}))],[`duotone`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M232,152a103.93,103.93,0,0,1-5.9,34.63,8,8,0,0,1-7.57,5.37H37.46a8.05,8.05,0,0,1-7.57-5.41A104.06,104.06,0,0,1,24,151.19C24.44,94,71.73,47.49,129,48A104,104,0,0,1,232,152Z`,opacity:`0.2`}),b.createElement(`path`,{d:`M114.34,154.34l96-96a8,8,0,0,1,11.32,11.32l-96,96a8,8,0,0,1-11.32-11.32ZM128,88a63.9,63.9,0,0,1,20.44,3.33,8,8,0,1,0,5.11-15.16A80,80,0,0,0,48.49,160.88,8,8,0,0,0,56.43,168c.29,0,.59,0,.89-.05a8,8,0,0,0,7.07-8.83A64.92,64.92,0,0,1,64,152,64.07,64.07,0,0,1,128,88Zm99.74,13a8,8,0,0,0-14.24,7.3,96.27,96.27,0,0,1,5,75.71l-181.1-.07A96.24,96.24,0,0,1,128,56h.88a95,95,0,0,1,42.82,10.5A8,8,0,1,0,179,52.27,110.8,110.8,0,0,0,129,40h-1A112.05,112.05,0,0,0,22.35,189.25,16.07,16.07,0,0,0,37.46,200H218.53a16,16,0,0,0,15.11-10.71,112.35,112.35,0,0,0-5.9-88.3Z`}))],[`fill`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M221.87,90.86a4,4,0,0,0-6.17-.62l-75.42,75.42A8,8,0,0,1,129,154.35l92.7-92.69a8,8,0,0,0-11.32-11.32L197,63.73A112.05,112.05,0,0,0,22.34,189.25,16.09,16.09,0,0,0,37.46,200H218.53a16,16,0,0,0,15.11-10.71,112.28,112.28,0,0,0-11.77-98.43ZM57.44,166.41a8,8,0,0,1-6.25,9.43,7.89,7.89,0,0,1-1.6.16,8,8,0,0,1-7.83-6.41A88.06,88.06,0,0,1,143.59,65.38a8,8,0,0,1-2.82,15.75,72.07,72.07,0,0,0-83.33,85.28Z`}))],[`light`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M115.76,155.76l96-96a6,6,0,0,1,8.48,8.48l-96,96a6,6,0,0,1-8.48-8.48ZM128,86a65.9,65.9,0,0,1,21.08,3.44,6,6,0,0,0,3.83-11.38,78,78,0,0,0-102.43,82.6,6,6,0,0,0,6,5.34,5.12,5.12,0,0,0,.67,0,6,6,0,0,0,5.3-6.62A69,69,0,0,1,62,152,66.08,66.08,0,0,1,128,86Zm98,15.9a6,6,0,1,0-10.68,5.48,98.35,98.35,0,0,1,5.16,77.25,2,2,0,0,1-1.91,1.37H37.46a2.07,2.07,0,0,1-1.91-1.41A98.23,98.23,0,0,1,128,54h.9a97,97,0,0,1,43.71,10.72A6,6,0,1,0,178.1,54,108.92,108.92,0,0,0,129,42h-1A110.06,110.06,0,0,0,24.23,188.58,14.08,14.08,0,0,0,37.46,198H218.53a14.06,14.06,0,0,0,13.22-9.37A110.34,110.34,0,0,0,226,101.9Z`}))],[`regular`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M114.34,154.34l96-96a8,8,0,0,1,11.32,11.32l-96,96a8,8,0,0,1-11.32-11.32ZM128,88a63.9,63.9,0,0,1,20.44,3.33,8,8,0,1,0,5.11-15.16A80,80,0,0,0,48.49,160.88,8,8,0,0,0,56.43,168c.29,0,.59,0,.89-.05a8,8,0,0,0,7.07-8.83A64.92,64.92,0,0,1,64,152,64.07,64.07,0,0,1,128,88Zm99.74,13a8,8,0,0,0-14.24,7.3,96.27,96.27,0,0,1,5,75.71l-181.1-.07A96.24,96.24,0,0,1,128,56h.88a95,95,0,0,1,42.82,10.5A8,8,0,1,0,179,52.27a112,112,0,0,0-156.66,137A16.07,16.07,0,0,0,37.46,200H218.53a16,16,0,0,0,15.11-10.71,112.35,112.35,0,0,0-5.9-88.3Z`}))],[`thin`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M117.17,157.17l96-96a4,4,0,1,1,5.66,5.66l-96,96a4,4,0,0,1-5.66-5.66ZM128,84a67.94,67.94,0,0,1,21.72,3.54A4,4,0,1,0,152.27,80,76,76,0,0,0,52,152a79.27,79.27,0,0,0,.46,8.44,4,4,0,0,0,4,3.56l.45,0a4,4,0,0,0,3.54-4.42A68,68,0,0,1,128,84Zm96.17,18.82a4,4,0,1,0-7.11,3.64,100.34,100.34,0,0,1,5.26,78.84,4,4,0,0,1-3.79,2.7H37.46a4.07,4.07,0,0,1-3.8-2.74A100.05,100.05,0,0,1,173.54,62.94a4,4,0,1,0,3.64-7.12A107,107,0,0,0,129,44h-1A108.06,108.06,0,0,0,26.12,187.92,12.07,12.07,0,0,0,37.46,196H218.53a12,12,0,0,0,11.34-8,108.31,108.31,0,0,0-5.7-85.14Z`}))]]),Mu=new Map([[`bold`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M100,36H56A20,20,0,0,0,36,56v44a20,20,0,0,0,20,20h44a20,20,0,0,0,20-20V56A20,20,0,0,0,100,36ZM96,96H60V60H96ZM200,36H156a20,20,0,0,0-20,20v44a20,20,0,0,0,20,20h44a20,20,0,0,0,20-20V56A20,20,0,0,0,200,36Zm-4,60H160V60h36Zm-96,40H56a20,20,0,0,0-20,20v44a20,20,0,0,0,20,20h44a20,20,0,0,0,20-20V156A20,20,0,0,0,100,136Zm-4,60H60V160H96Zm104-60H156a20,20,0,0,0-20,20v44a20,20,0,0,0,20,20h44a20,20,0,0,0,20-20V156A20,20,0,0,0,200,136Zm-4,60H160V160h36Z`}))],[`duotone`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M112,56v48a8,8,0,0,1-8,8H56a8,8,0,0,1-8-8V56a8,8,0,0,1,8-8h48A8,8,0,0,1,112,56Zm88-8H152a8,8,0,0,0-8,8v48a8,8,0,0,0,8,8h48a8,8,0,0,0,8-8V56A8,8,0,0,0,200,48Zm-96,96H56a8,8,0,0,0-8,8v48a8,8,0,0,0,8,8h48a8,8,0,0,0,8-8V152A8,8,0,0,0,104,144Zm96,0H152a8,8,0,0,0-8,8v48a8,8,0,0,0,8,8h48a8,8,0,0,0,8-8V152A8,8,0,0,0,200,144Z`,opacity:`0.2`}),b.createElement(`path`,{d:`M200,136H152a16,16,0,0,0-16,16v48a16,16,0,0,0,16,16h48a16,16,0,0,0,16-16V152A16,16,0,0,0,200,136Zm0,64H152V152h48v48ZM104,40H56A16,16,0,0,0,40,56v48a16,16,0,0,0,16,16h48a16,16,0,0,0,16-16V56A16,16,0,0,0,104,40Zm0,64H56V56h48v48Zm96-64H152a16,16,0,0,0-16,16v48a16,16,0,0,0,16,16h48a16,16,0,0,0,16-16V56A16,16,0,0,0,200,40Zm0,64H152V56h48v48Zm-96,32H56a16,16,0,0,0-16,16v48a16,16,0,0,0,16,16h48a16,16,0,0,0,16-16V152A16,16,0,0,0,104,136Zm0,64H56V152h48v48Z`}))],[`fill`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M120,56v48a16,16,0,0,1-16,16H56a16,16,0,0,1-16-16V56A16,16,0,0,1,56,40h48A16,16,0,0,1,120,56Zm80-16H152a16,16,0,0,0-16,16v48a16,16,0,0,0,16,16h48a16,16,0,0,0,16-16V56A16,16,0,0,0,200,40Zm-96,96H56a16,16,0,0,0-16,16v48a16,16,0,0,0,16,16h48a16,16,0,0,0,16-16V152A16,16,0,0,0,104,136Zm96,0H152a16,16,0,0,0-16,16v48a16,16,0,0,0,16,16h48a16,16,0,0,0,16-16V152A16,16,0,0,0,200,136Z`}))],[`light`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M104,42H56A14,14,0,0,0,42,56v48a14,14,0,0,0,14,14h48a14,14,0,0,0,14-14V56A14,14,0,0,0,104,42Zm2,62a2,2,0,0,1-2,2H56a2,2,0,0,1-2-2V56a2,2,0,0,1,2-2h48a2,2,0,0,1,2,2Zm94-62H152a14,14,0,0,0-14,14v48a14,14,0,0,0,14,14h48a14,14,0,0,0,14-14V56A14,14,0,0,0,200,42Zm2,62a2,2,0,0,1-2,2H152a2,2,0,0,1-2-2V56a2,2,0,0,1,2-2h48a2,2,0,0,1,2,2Zm-98,34H56a14,14,0,0,0-14,14v48a14,14,0,0,0,14,14h48a14,14,0,0,0,14-14V152A14,14,0,0,0,104,138Zm2,62a2,2,0,0,1-2,2H56a2,2,0,0,1-2-2V152a2,2,0,0,1,2-2h48a2,2,0,0,1,2,2Zm94-62H152a14,14,0,0,0-14,14v48a14,14,0,0,0,14,14h48a14,14,0,0,0,14-14V152A14,14,0,0,0,200,138Zm2,62a2,2,0,0,1-2,2H152a2,2,0,0,1-2-2V152a2,2,0,0,1,2-2h48a2,2,0,0,1,2,2Z`}))],[`regular`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M104,40H56A16,16,0,0,0,40,56v48a16,16,0,0,0,16,16h48a16,16,0,0,0,16-16V56A16,16,0,0,0,104,40Zm0,64H56V56h48v48Zm96-64H152a16,16,0,0,0-16,16v48a16,16,0,0,0,16,16h48a16,16,0,0,0,16-16V56A16,16,0,0,0,200,40Zm0,64H152V56h48v48Zm-96,32H56a16,16,0,0,0-16,16v48a16,16,0,0,0,16,16h48a16,16,0,0,0,16-16V152A16,16,0,0,0,104,136Zm0,64H56V152h48v48Zm96-64H152a16,16,0,0,0-16,16v48a16,16,0,0,0,16,16h48a16,16,0,0,0,16-16V152A16,16,0,0,0,200,136Zm0,64H152V152h48v48Z`}))],[`thin`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M104,44H56A12,12,0,0,0,44,56v48a12,12,0,0,0,12,12h48a12,12,0,0,0,12-12V56A12,12,0,0,0,104,44Zm4,60a4,4,0,0,1-4,4H56a4,4,0,0,1-4-4V56a4,4,0,0,1,4-4h48a4,4,0,0,1,4,4Zm92-60H152a12,12,0,0,0-12,12v48a12,12,0,0,0,12,12h48a12,12,0,0,0,12-12V56A12,12,0,0,0,200,44Zm4,60a4,4,0,0,1-4,4H152a4,4,0,0,1-4-4V56a4,4,0,0,1,4-4h48a4,4,0,0,1,4,4ZM104,140H56a12,12,0,0,0-12,12v48a12,12,0,0,0,12,12h48a12,12,0,0,0,12-12V152A12,12,0,0,0,104,140Zm4,60a4,4,0,0,1-4,4H56a4,4,0,0,1-4-4V152a4,4,0,0,1,4-4h48a4,4,0,0,1,4,4Zm92-60H152a12,12,0,0,0-12,12v48a12,12,0,0,0,12,12h48a12,12,0,0,0,12-12V152A12,12,0,0,0,200,140Zm4,60a4,4,0,0,1-4,4H152a4,4,0,0,1-4-4V152a4,4,0,0,1,4-4h48a4,4,0,0,1,4,4Z`}))]]),Nu=new Map([[`bold`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M243,96a20.33,20.33,0,0,0-17.74-14l-56.59-4.57L146.83,24.62a20.36,20.36,0,0,0-37.66,0L87.35,77.44,30.76,82A20.45,20.45,0,0,0,19.1,117.88l43.18,37.24-13.2,55.7A20.37,20.37,0,0,0,79.57,233L128,203.19,176.43,233a20.39,20.39,0,0,0,30.49-22.15l-13.2-55.7,43.18-37.24A20.43,20.43,0,0,0,243,96ZM172.53,141.7a12,12,0,0,0-3.84,11.86L181.58,208l-47.29-29.08a12,12,0,0,0-12.58,0L74.42,208l12.89-54.4a12,12,0,0,0-3.84-11.86L41.2,105.24l55.4-4.47a12,12,0,0,0,10.13-7.38L128,41.89l21.27,51.5a12,12,0,0,0,10.13,7.38l55.4,4.47Z`}))],[`duotone`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M229.06,108.79l-48.7,42,14.88,62.79a8.4,8.4,0,0,1-12.52,9.17L128,189.09,73.28,222.74a8.4,8.4,0,0,1-12.52-9.17l14.88-62.79-48.7-42A8.46,8.46,0,0,1,31.73,94L95.64,88.8l24.62-59.6a8.36,8.36,0,0,1,15.48,0l24.62,59.6L224.27,94A8.46,8.46,0,0,1,229.06,108.79Z`,opacity:`0.2`}),b.createElement(`path`,{d:`M239.18,97.26A16.38,16.38,0,0,0,224.92,86l-59-4.76L143.14,26.15a16.36,16.36,0,0,0-30.27,0L90.11,81.23,31.08,86a16.46,16.46,0,0,0-9.37,28.86l45,38.83L53,211.75a16.38,16.38,0,0,0,24.5,17.82L128,198.49l50.53,31.08A16.4,16.4,0,0,0,203,211.75l-13.76-58.07,45-38.83A16.43,16.43,0,0,0,239.18,97.26Zm-15.34,5.47-48.7,42a8,8,0,0,0-2.56,7.91l14.88,62.8a.37.37,0,0,1-.17.48c-.18.14-.23.11-.38,0l-54.72-33.65a8,8,0,0,0-8.38,0L69.09,215.94c-.15.09-.19.12-.38,0a.37.37,0,0,1-.17-.48l14.88-62.8a8,8,0,0,0-2.56-7.91l-48.7-42c-.12-.1-.23-.19-.13-.5s.18-.27.33-.29l63.92-5.16A8,8,0,0,0,103,91.86l24.62-59.61c.08-.17.11-.25.35-.25s.27.08.35.25L153,91.86a8,8,0,0,0,6.75,4.92l63.92,5.16c.15,0,.24,0,.33.29S224,102.63,223.84,102.73Z`}))],[`fill`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M234.29,114.85l-45,38.83L203,211.75a16.4,16.4,0,0,1-24.5,17.82L128,198.49,77.47,229.57A16.4,16.4,0,0,1,53,211.75l13.76-58.07-45-38.83A16.46,16.46,0,0,1,31.08,86l59-4.76,22.76-55.08a16.36,16.36,0,0,1,30.27,0l22.75,55.08,59,4.76a16.46,16.46,0,0,1,9.37,28.86Z`}))],[`light`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M237.28,97.87A14.18,14.18,0,0,0,224.76,88l-60.25-4.87-23.22-56.2a14.37,14.37,0,0,0-26.58,0L91.49,83.11,31.24,88a14.18,14.18,0,0,0-12.52,9.89A14.43,14.43,0,0,0,23,113.32L69,152.93l-14,59.25a14.4,14.4,0,0,0,5.59,15,14.1,14.1,0,0,0,15.91.6L128,196.12l51.58,31.71a14.1,14.1,0,0,0,15.91-.6,14.4,14.4,0,0,0,5.59-15l-14-59.25L233,113.32A14.43,14.43,0,0,0,237.28,97.87Zm-12.14,6.37-48.69,42a6,6,0,0,0-1.92,5.92l14.88,62.79a2.35,2.35,0,0,1-.95,2.57,2.24,2.24,0,0,1-2.6.1L131.14,184a6,6,0,0,0-6.28,0L70.14,217.61a2.24,2.24,0,0,1-2.6-.1,2.35,2.35,0,0,1-1-2.57l14.88-62.79a6,6,0,0,0-1.92-5.92l-48.69-42a2.37,2.37,0,0,1-.73-2.65,2.28,2.28,0,0,1,2.07-1.65l63.92-5.16a6,6,0,0,0,5.06-3.69l24.63-59.6a2.35,2.35,0,0,1,4.38,0l24.63,59.6a6,6,0,0,0,5.06,3.69l63.92,5.16a2.28,2.28,0,0,1,2.07,1.65A2.37,2.37,0,0,1,225.14,104.24Z`}))],[`regular`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M239.18,97.26A16.38,16.38,0,0,0,224.92,86l-59-4.76L143.14,26.15a16.36,16.36,0,0,0-30.27,0L90.11,81.23,31.08,86a16.46,16.46,0,0,0-9.37,28.86l45,38.83L53,211.75a16.38,16.38,0,0,0,24.5,17.82L128,198.49l50.53,31.08A16.4,16.4,0,0,0,203,211.75l-13.76-58.07,45-38.83A16.43,16.43,0,0,0,239.18,97.26Zm-15.34,5.47-48.7,42a8,8,0,0,0-2.56,7.91l14.88,62.8a.37.37,0,0,1-.17.48c-.18.14-.23.11-.38,0l-54.72-33.65a8,8,0,0,0-8.38,0L69.09,215.94c-.15.09-.19.12-.38,0a.37.37,0,0,1-.17-.48l14.88-62.8a8,8,0,0,0-2.56-7.91l-48.7-42c-.12-.1-.23-.19-.13-.5s.18-.27.33-.29l63.92-5.16A8,8,0,0,0,103,91.86l24.62-59.61c.08-.17.11-.25.35-.25s.27.08.35.25L153,91.86a8,8,0,0,0,6.75,4.92l63.92,5.16c.15,0,.24,0,.33.29S224,102.63,223.84,102.73Z`}))],[`thin`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M235.36,98.49A12.21,12.21,0,0,0,224.59,90l-61.47-5L139.44,27.67a12.37,12.37,0,0,0-22.88,0L92.88,85,31.41,90a12.45,12.45,0,0,0-7.07,21.84l46.85,40.41L56.87,212.64a12.35,12.35,0,0,0,18.51,13.49L128,193.77l52.62,32.36a12.12,12.12,0,0,0,13.69-.51,12.28,12.28,0,0,0,4.82-13l-14.32-60.42,46.85-40.41A12.29,12.29,0,0,0,235.36,98.49Zm-8.93,7.26-48.68,42a4,4,0,0,0-1.28,3.95l14.87,62.79a4.37,4.37,0,0,1-1.72,4.65,4.24,4.24,0,0,1-4.81.18L130.1,185.67a4,4,0,0,0-4.2,0L71.19,219.32a4.24,4.24,0,0,1-4.81-.18,4.37,4.37,0,0,1-1.72-4.65L79.53,151.7a4,4,0,0,0-1.28-3.95l-48.68-42A4.37,4.37,0,0,1,28.25,101a4.31,4.31,0,0,1,3.81-3L96,92.79a4,4,0,0,0,3.38-2.46L124,30.73a4.35,4.35,0,0,1,8.08,0l24.62,59.6A4,4,0,0,0,160,92.79l63.9,5.15a4.31,4.31,0,0,1,3.81,3A4.37,4.37,0,0,1,226.43,105.75Z`}))]]),Pu=new Map([[`bold`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M229.26,90.4a108,108,0,0,1-177.63,114A108,108,0,0,1,195.41,43.63l20.1-20.11a12,12,0,0,1,17,17l-96,96a12,12,0,1,1-17-17l24-24a36,36,0,1,0,19.76,39.65,12,12,0,0,1,23.53,4.74,60,60,0,1,1-25.73-62L178.3,60.74a84,84,0,1,0,28.46,38,12,12,0,1,1,22.5-8.35Z`}))],[`duotone`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M176,128a48,48,0,1,1-48-48A48,48,0,0,1,176,128Z`,opacity:`0.2`}),b.createElement(`path`,{d:`M221.87,83.16A104.1,104.1,0,1,1,195.67,49l22.67-22.68a8,8,0,0,1,11.32,11.32l-96,96a8,8,0,0,1-11.32-11.32l27.72-27.72a40,40,0,1,0,17.87,31.09,8,8,0,1,1,16-.9,56,56,0,1,1-22.38-41.65L184.3,60.39a87.88,87.88,0,1,0,23.13,29.67,8,8,0,0,1,14.44-6.9Z`}))],[`fill`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M221.87,83.16A104.1,104.1,0,1,1,195.67,49l22.67-22.68a8,8,0,0,1,11.32,11.32L167.6,99.71h0l-37.71,37.71-23.95,23.95a40,40,0,0,0,62-35.67,8,8,0,1,1,16-.9,56,56,0,0,1-95.5,42.79h0a56,56,0,0,1,73.13-84.43L184.3,60.39a87.88,87.88,0,1,0,23.13,29.67,8,8,0,0,1,14.44-6.9Z`}))],[`light`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M220.06,84a102.06,102.06,0,1,1-24.31-32.27l24-24a6,6,0,0,1,8.48,8.49l-96,96a6,6,0,1,1-8.48-8.49l29.39-29.4a42,42,0,1,0,16.78,31.24,6,6,0,1,1,12-.68A54,54,0,1,1,161.7,85.83l25.54-25.55a89.91,89.91,0,1,0,22,28.93A6,6,0,1,1,220.06,84Z`}))],[`regular`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M221.87,83.16A104.1,104.1,0,1,1,195.67,49l22.67-22.68a8,8,0,0,1,11.32,11.32l-96,96a8,8,0,0,1-11.32-11.32l27.72-27.72a40,40,0,1,0,17.87,31.09,8,8,0,1,1,16-.9,56,56,0,1,1-22.38-41.65L184.3,60.39a87.88,87.88,0,1,0,23.13,29.67,8,8,0,0,1,14.44-6.9Z`}))],[`thin`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M218.26,84.89a100.16,100.16,0,1,1-22.44-30.37l25.35-25.35a4,4,0,1,1,5.66,5.66l-96,96a4,4,0,0,1-5.66-5.66l31-31a44,44,0,1,0,15.78,31.3,4,4,0,0,1,8-.46,52,52,0,1,1-18.1-36.51l28.34-28.33A92,92,0,0,0,63,193.05,92,92,0,0,0,211,88.33a4,4,0,1,1,7.22-3.44Z`}))]]),Fu=new Map([[`bold`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M128,44a96,96,0,1,0,96,96A96.11,96.11,0,0,0,128,44Zm0,168a72,72,0,1,1,72-72A72.08,72.08,0,0,1,128,212ZM164.49,99.51a12,12,0,0,1,0,17l-28,28a12,12,0,0,1-17-17l28-28A12,12,0,0,1,164.49,99.51ZM92,16A12,12,0,0,1,104,4h48a12,12,0,0,1,0,24H104A12,12,0,0,1,92,16Z`}))],[`duotone`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M216,136a88,88,0,1,1-88-88A88,88,0,0,1,216,136Z`,opacity:`0.2`}),b.createElement(`path`,{d:`M128,40a96,96,0,1,0,96,96A96.11,96.11,0,0,0,128,40Zm0,176a80,80,0,1,1,80-80A80.09,80.09,0,0,1,128,216ZM173.66,90.34a8,8,0,0,1,0,11.32l-40,40a8,8,0,0,1-11.32-11.32l40-40A8,8,0,0,1,173.66,90.34ZM96,16a8,8,0,0,1,8-8h48a8,8,0,0,1,0,16H104A8,8,0,0,1,96,16Z`}))],[`fill`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M128,40a96,96,0,1,0,96,96A96.11,96.11,0,0,0,128,40Zm45.66,61.66-40,40a8,8,0,0,1-11.32-11.32l40-40a8,8,0,0,1,11.32,11.32ZM96,16a8,8,0,0,1,8-8h48a8,8,0,0,1,0,16H104A8,8,0,0,1,96,16Z`}))],[`light`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M128,42a94,94,0,1,0,94,94A94.11,94.11,0,0,0,128,42Zm0,176a82,82,0,1,1,82-82A82.1,82.1,0,0,1,128,218ZM172.24,91.76a6,6,0,0,1,0,8.48l-40,40a6,6,0,1,1-8.48-8.48l40-40A6,6,0,0,1,172.24,91.76ZM98,16a6,6,0,0,1,6-6h48a6,6,0,0,1,0,12H104A6,6,0,0,1,98,16Z`}))],[`regular`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M128,40a96,96,0,1,0,96,96A96.11,96.11,0,0,0,128,40Zm0,176a80,80,0,1,1,80-80A80.09,80.09,0,0,1,128,216ZM173.66,90.34a8,8,0,0,1,0,11.32l-40,40a8,8,0,0,1-11.32-11.32l40-40A8,8,0,0,1,173.66,90.34ZM96,16a8,8,0,0,1,8-8h48a8,8,0,0,1,0,16H104A8,8,0,0,1,96,16Z`}))],[`thin`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M128,44a92,92,0,1,0,92,92A92.1,92.1,0,0,0,128,44Zm0,176a84,84,0,1,1,84-84A84.09,84.09,0,0,1,128,220ZM170.83,93.17a4,4,0,0,1,0,5.66l-40,40a4,4,0,1,1-5.66-5.66l40-40A4,4,0,0,1,170.83,93.17ZM100,16a4,4,0,0,1,4-4h48a4,4,0,0,1,0,8H104A4,4,0,0,1,100,16Z`}))]]),Iu=new Map([[`bold`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M208.49,191.51a12,12,0,0,1-17,17L128,145,64.49,208.49a12,12,0,0,1-17-17L111,128,47.51,64.49a12,12,0,0,1,17-17L128,111l63.51-63.52a12,12,0,0,1,17,17L145,128Z`}))],[`duotone`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M216,56V200a16,16,0,0,1-16,16H56a16,16,0,0,1-16-16V56A16,16,0,0,1,56,40H200A16,16,0,0,1,216,56Z`,opacity:`0.2`}),b.createElement(`path`,{d:`M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z`}))],[`fill`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M208,32H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM181.66,170.34a8,8,0,0,1-11.32,11.32L128,139.31,85.66,181.66a8,8,0,0,1-11.32-11.32L116.69,128,74.34,85.66A8,8,0,0,1,85.66,74.34L128,116.69l42.34-42.35a8,8,0,0,1,11.32,11.32L139.31,128Z`}))],[`light`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M204.24,195.76a6,6,0,1,1-8.48,8.48L128,136.49,60.24,204.24a6,6,0,0,1-8.48-8.48L119.51,128,51.76,60.24a6,6,0,0,1,8.48-8.48L128,119.51l67.76-67.75a6,6,0,0,1,8.48,8.48L136.49,128Z`}))],[`regular`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z`}))],[`thin`,b.createElement(b.Fragment,null,b.createElement(`path`,{d:`M202.83,197.17a4,4,0,0,1-5.66,5.66L128,133.66,58.83,202.83a4,4,0,0,1-5.66-5.66L122.34,128,53.17,58.83a4,4,0,0,1,5.66-5.66L128,122.34l69.17-69.17a4,4,0,1,1,5.66,5.66L133.66,128Z`}))]]),Lu=(0,b.createContext)({color:`currentColor`,size:`1em`,weight:`regular`,mirrored:!1}),Ru=b.forwardRef((e,t)=>{let{alt:n,color:r,size:i,weight:a,mirrored:o,children:s,weights:c,...l}=e,{color:u=`currentColor`,size:d,weight:f=`regular`,mirrored:p=!1,...m}=b.useContext(Lu);return b.createElement(`svg`,{ref:t,xmlns:`http://www.w3.org/2000/svg`,width:i??d,height:i??d,fill:r??u,viewBox:`0 0 256 256`,transform:o||p?`scale(-1, 1)`:void 0,...m,...l},!!n&&b.createElement(`title`,null,n),s,c.get(a??f))});Ru.displayName=`IconBase`;var zu=b.forwardRef((e,t)=>b.createElement(Ru,{ref:t,...e,weights:vu}));zu.displayName=`ArrowDownIcon`;var Bu=zu,Vu=b.forwardRef((e,t)=>b.createElement(Ru,{ref:t,...e,weights:yu}));Vu.displayName=`ArrowLeftIcon`;var Hu=Vu,Uu=b.forwardRef((e,t)=>b.createElement(Ru,{ref:t,...e,weights:bu}));Uu.displayName=`ArrowRightIcon`;var Wu=Uu,Gu=b.forwardRef((e,t)=>b.createElement(Ru,{ref:t,...e,weights:xu}));Gu.displayName=`ArrowUpIcon`;var X=Gu,Ku=b.forwardRef((e,t)=>b.createElement(Ru,{ref:t,...e,weights:Su}));Ku.displayName=`ChartLineUpIcon`;var qu=Ku,Ju=b.forwardRef((e,t)=>b.createElement(Ru,{ref:t,...e,weights:Cu}));Ju.displayName=`CheckIcon`;var Yu=Ju,Xu=b.forwardRef((e,t)=>b.createElement(Ru,{ref:t,...e,weights:wu}));Xu.displayName=`CheckCircleIcon`;var Zu=Xu,Qu=b.forwardRef((e,t)=>b.createElement(Ru,{ref:t,...e,weights:Tu}));Qu.displayName=`ClockCountdownIcon`;var $u=Qu,ed=b.forwardRef((e,t)=>b.createElement(Ru,{ref:t,...e,weights:Eu}));ed.displayName=`HeartIcon`;var td=ed,nd=b.forwardRef((e,t)=>b.createElement(Ru,{ref:t,...e,weights:Du}));nd.displayName=`LockKeyIcon`;var rd=nd,id=b.forwardRef((e,t)=>b.createElement(Ru,{ref:t,...e,weights:Ou}));id.displayName=`MinusIcon`;var ad=id,od=b.forwardRef((e,t)=>b.createElement(Ru,{ref:t,...e,weights:ku}));od.displayName=`PathIcon`;var sd=od,cd=b.forwardRef((e,t)=>b.createElement(Ru,{ref:t,...e,weights:Au}));cd.displayName=`SparkleIcon`;var ld=cd,ud=b.forwardRef((e,t)=>b.createElement(Ru,{ref:t,...e,weights:ju}));ud.displayName=`SpeedometerIcon`;var dd=ud,fd=b.forwardRef((e,t)=>b.createElement(Ru,{ref:t,...e,weights:Mu}));fd.displayName=`SquaresFourIcon`;var pd=fd,md=b.forwardRef((e,t)=>b.createElement(Ru,{ref:t,...e,weights:Nu}));md.displayName=`StarIcon`;var hd=md,gd=b.forwardRef((e,t)=>b.createElement(Ru,{ref:t,...e,weights:Pu}));gd.displayName=`TargetIcon`;var _d=gd,vd=b.forwardRef((e,t)=>b.createElement(Ru,{ref:t,...e,weights:Fu}));vd.displayName=`TimerIcon`;var yd=vd,bd=b.forwardRef((e,t)=>b.createElement(Ru,{ref:t,...e,weights:Iu}));bd.displayName=`XIcon`;var Z=bd,xd=[`/assets/brain/symbols/camera.png`,`/assets/brain/symbols/sun.png`,`/assets/brain/symbols/squares.png`,`/assets/brain/symbols/lock.png`,`/assets/brain/symbols/lightning.png`,`/assets/brain/symbols/moon.png`,`/assets/brain/symbols/gear.png`,`/assets/brain/symbols/star.png`,`/assets/brain/symbols/puzzle.png`,`/assets/brain/symbols/coffee.png`],Sd=[{name:`全麦面包`,image:`/assets/brain/memory/bread.png`,tone:`amber`},{name:`胡萝卜`,image:`/assets/brain/memory/carrot.png`,tone:`coral`},{name:`奶酪`,image:`/assets/brain/memory/cheese.png`,tone:`yellow`},{name:`咖啡`,image:`/assets/brain/memory/coffee.png`,tone:`violet`},{name:`曲奇`,image:`/assets/brain/memory/cookie.png`,tone:`pink`},{name:`鸡蛋`,image:`/assets/brain/memory/egg.png`,tone:`blue`},{name:`鲜鱼`,image:`/assets/brain/memory/fish.png`,tone:`cyan`},{name:`橙子`,image:`/assets/brain/memory/orange.png`,tone:`orange`}],Cd={blue:`/assets/brain/planes/teal.png`,orange:`/assets/brain/planes/coral.png`},wd={symbol:`/assets/ui/finish-symbol.png`,trail:`/assets/ui/finish-trail.png`,attention:`/assets/ui/finish-attention.png`,memory:`/assets/ui/finish-memory.png`,money:`/assets/ui/finish-all.png`},Td=[`up`,`right`,`down`,`left`],Ed={up:X,right:Wu,down:Bu,left:Hu},Dd={up:`向上`,right:`向右`,down:`向下`,left:`向左`},Od={up:-90,right:0,down:90,left:180},kd={score:0,correct:0,total:0,errors:0,completion:0},Ad=[{value:.5,image:`/assets/money/money-05.png`},{value:1,image:`/assets/money/money-1.png`},{value:2,image:`/assets/money/money-2.png`},{value:5,image:`/assets/money/money-5.png`},{value:10,image:`/assets/money/money-10.png`},{value:20,image:`/assets/money/money-20.png`}],jd=[0,35,40,45],Md=[{price:13,payment:20,target:7,seconds:40},{price:26.5,payment:40,target:13.5,seconds:45},{price:41.5,payment:60,target:18.5,seconds:50}];function Nd(e){return Ad.find(t=>t.value===e)?.image??Ad[0].image}var Q=Array.from({length:20},(e,t)=>({kind:t%2==0?`number`:`shape`,rank:Math.floor(t/2)+1})),Pd=[{x:42,y:58},{x:57,y:43},{x:74,y:54},{x:66,y:69},{x:50,y:75},{x:34,y:65},{x:18,y:78},{x:11,y:58},{x:24,y:43},{x:14,y:25},{x:31,y:16},{x:45,y:29},{x:57,y:15},{x:69,y:31},{x:80,y:17},{x:91,y:31},{x:84,y:48},{x:92,y:68},{x:78,y:82},{x:58,y:85}];function $(e){let t=[...e];for(let e=t.length-1;e>0;--e){let n=Math.floor(Math.random()*(e+1));[t[e],t[n]]=[t[n],t[e]]}return t}function Fd(){return Td[Math.floor(Math.random()*Td.length)]}function Id(e,t,n,r){let i=Math.min(1,t/r),a=Math.max(t,e+n),o=a?e/a:0;return{score:Math.max(20,Math.min(98,Math.round(o*72+i*28))),correct:e,total:t,errors:n,completion:Math.round(i*100)}}function Ld(){let e=Math.random()>.5,t=Math.random()>.5;return Pd.map((n,r)=>({x:(e?100-n.x:n.x)+(r%3-1)*.7,y:(t?100-n.y:n.y)+((r+1)%3-1)*.6}))}function Rd(e,t,n){let r=e<3?1:e<10?3:e<20?5:7,i=Math.floor(Math.random()*r);return Array.from({length:r},(e,r)=>{let a=r===i,o=a?t:t===`blue`?`orange`:`blue`;return{id:Date.now()+r,target:a,direction:a?n:Fd(),color:o,lane:12+(r*17+Math.floor(Math.random()*10))%72,duration:6.7+Math.random()*1.5,delay:r*.38}})}function zd(){return(0,H.jsxs)(`div`,{className:`brand`,children:[(0,H.jsx)(`span`,{children:(0,H.jsx)(pd,{size:24,weight:`fill`})}),(0,H.jsx)(`b`,{children:`脑晴测`}),(0,H.jsx)(`em`,{children:`COGNITIVE STUDIO`})]})}function Bd({children:e,onClick:t,disabled:n,secondary:r=!1}){return(0,H.jsx)(`button`,{className:`primary-button ${r?`secondary`:``}`,onClick:t,disabled:n,children:e})}function Vd({seconds:e,onBack:t}){return(0,H.jsxs)(`header`,{className:`game-header`,children:[(0,H.jsx)(`button`,{className:`round-button`,onClick:t,"aria-label":`退出当前测试`,children:(0,H.jsx)(Hu,{weight:`bold`})}),(0,H.jsxs)(`div`,{className:`timer`,children:[(0,H.jsx)(yd,{weight:`fill`}),(0,H.jsxs)(`b`,{children:[String(Math.floor(e/60)).padStart(2,`0`),`:`,String(e%60).padStart(2,`0`)]})]})]})}function Hd({target:e,text:t,onTargetClick:n}){let[r,i]=(0,b.useState)(null);if((0,b.useLayoutEffect)(()=>{let t=()=>{let t=document.querySelector(e);if(!t)return;let n=t.getBoundingClientRect();i({left:Math.max(4,n.left-9),top:Math.max(4,n.top-9),width:Math.min(window.innerWidth-8,n.width+18),height:Math.min(window.innerHeight-8,n.height+18)})};t();let n=new ResizeObserver(t),r=document.querySelector(e);return r&&n.observe(r),window.addEventListener(`resize`,t),()=>{n.disconnect(),window.removeEventListener(`resize`,t)}},[e]),!r)return null;let a=Math.min(292,window.innerWidth-24),o=r.top$(Array.from({length:10},(e,t)=>t))),ne=(0,b.useRef)(0),T=(0,b.useRef)(0),[re,ie]=(0,b.useState)(0),[ae,oe]=(0,b.useState)(Ld),se=(0,b.useRef)(0),[ce,le]=(0,b.useState)(0),[E,D]=(0,b.useState)(`right`),[ue,de]=(0,b.useState)(`blue`),[fe,O]=(0,b.useState)(3),[pe,k]=(0,b.useState)(()=>Rd(0,`blue`,`right`)),me=(0,b.useRef)(0),he=(0,b.useRef)(0),[ge,_e]=(0,b.useState)(1),[ve,ye]=(0,b.useState)(`study`),[be,xe]=(0,b.useState)(()=>$([0,1,2,3,4,5,6,7]).slice(0,2)),[Se,Ce]=(0,b.useState)([]),[we,Te]=(0,b.useState)([]),[Ee,De]=(0,b.useState)(()=>$([0,1,2,3,4,5,6,7])),[Oe,ke]=(0,b.useState)(!1),[Ae,je]=(0,b.useState)(1),[Me,Ne]=(0,b.useState)(0),[Pe,Fe]=(0,b.useState)([]),Ie=(0,b.useRef)(0),Le=(0,b.useRef)(0),Re=(0,b.useRef)(0),A=(0,b.useRef)(0),ze=(0,b.useRef)(0),j=(0,b.useRef)(null),Be=(0,b.useRef)([]),Ve=(0,b.useRef)(0),He=(0,b.useRef)(0),M=(0,b.useRef)(0),Ue=[`symbol`,`trail`,`attention`,`memory`,`money`].includes(e)&&!n&&!u&&!(e===`memory`&&(ve===`study`||Oe));(0,b.useEffect)(()=>{if(!Ue||o<=0)return;let e=window.setInterval(()=>s(e=>e-1),1e3);return()=>window.clearInterval(e)},[Ue,o]),(0,b.useEffect)(()=>{window.scrollTo({top:0,behavior:`smooth`})},[e]);let We=e=>{l(e),window.setTimeout(()=>l(null),620)},Ge=()=>{n!==`memory`&&j.current!==null&&(ze.current+=Date.now()-j.current,j.current=null),ke(!1)},Ke=()=>{if(Oe){Ge();return}n!==`memory`&&(A.current+=1,j.current=Date.now()),ke(!0)},qe=()=>{let e=Id(Ie.current,Le.current,Re.current,9),t=Math.round(ze.current/1e3),n=Math.min(20,A.current*4+Math.floor(t/5));return{...e,score:Math.max(20,e.score-n)}},Je=e=>{t(e),r(e),p(0),ke(!1)},Ye=()=>{Be.current.forEach(e=>window.clearTimeout(e)),Be.current=[]},Xe=e=>{if(r(null),s(e===`trail`?90:e===`memory`?jd[1]:60),e===`symbol`){let e=Math.floor(Math.random()*10);for(;e===C;)e=Math.floor(Math.random()*10);S(0),w(e),te($(Array.from({length:10},(e,t)=>t))),ne.current=0,T.current=0}if(e===`trail`){let e=Ld(),t=0;for(;e.every((e,t)=>e.x===ae[t].x&&e.y===ae[t].y)&&t<6;)e=Ld(),t+=1;ie(0),oe(e),se.current=0}if(e===`attention`){let e=Td[(Td.indexOf(E)+1+Math.floor(Math.random()*3))%Td.length],t=Math.random()>.5?`blue`:`orange`;le(0),O(3),D(e),de(t),k(Rd(0,t,e)),me.current=0,he.current=0}if(e===`memory`){let e=$([0,1,2,3,4,5,6,7]).slice(0,2),t=[...be.slice(0,2)].sort().join(`-`);for(;[...e].sort().join(`-`)===t;)e=$([0,1,2,3,4,5,6,7]).slice(0,2);_e(1),ye(`study`),xe(e),Ce([]),Te([]),De($([0,1,2,3,4,5,6,7])),ke(!1),Fe([]),Ie.current=0,Le.current=0,Re.current=0,A.current=0,ze.current=0,j.current=null}e===`money`&&(je(1),Ne(0),Fe([]),s(Md[0].seconds),Ve.current=0,He.current=0,M.current=0)},Ze=(n,i,a)=>{y(e=>({...e,[n]:i})),h(e),_(a),t(`complete`),r(null)},Qe=e=>{if(He.current+=1,e&&(Ve.current+=1),Fe([]),Ne(0),Ae{e===`symbol`&&Ze(`speed`,Id(ne.current,x,T.current,30),`trail`),e===`trail`&&Ze(`executive`,Id(re,re,se.current,20),`attention`),e===`attention`&&Ze(`attention`,Id(me.current,ce,he.current,20),`memory`),e===`memory`&&ve===`conveyor`&&it(Se),e===`money`&&(M.current+=1,Qe(!1))};(0,b.useEffect)(()=>{!Ue||o!==0||$e()},[Ue,o]);let et=()=>{y({speed:kd,executive:kd,attention:kd,memory:kd,calculation:kd}),S(0),te($(Array.from({length:10},(e,t)=>t))),w(Math.floor(Math.random()*10)),ne.current=0,T.current=0,ie(0),oe(Ld()),se.current=0,le(0),O(3),D(`right`),de(`blue`),k(Rd(0,`blue`,`right`)),me.current=0,he.current=0,_e(1),ye(`study`),xe($([0,1,2,3,4,5,6,7]).slice(0,2)),Ce([]),Te([]),De($([0,1,2,3,4,5,6,7])),Fe([]),Ie.current=0,Le.current=0,Re.current=0,A.current=0,ze.current=0,j.current=null,je(1),Ne(0),Fe([]),Ve.current=0,He.current=0,M.current=0},tt=e=>{if(n===`symbol`){if(e!==ee.indexOf(C))return;if(We(`correct`),f>=1){p(2);return}let t=Math.floor(Math.random()*10);for(;t===C;)t=Math.floor(Math.random()*10);w(t),te(e=>$(e)),p(1);return}let t=ee.indexOf(C)===e;if(t?ne.current+=1:T.current+=1,We(t?`correct`:`wrong`),x>=29){Ze(`speed`,Id(ne.current,30,T.current,30),`trail`);return}let r=Math.floor(Math.random()*10);for(;r===C;)r=Math.floor(Math.random()*10);w(r),te(e=>$(e)),S(e=>e+1)},nt=e=>{if(n===`trail`){if(e!==f)return;We(`correct`),p(e=>e>=3?4:e+1);return}if(e!==re){se.current+=1,We(`wrong`);return}if(We(`correct`),e===19){Ze(`executive`,Id(20,20,se.current,20),`attention`);return}ie(e+1)},rt=e=>{if(n===`attention`){if(e!==E)return;if(We(`correct`),f>=1){p(2);return}let t=Td[(Td.indexOf(E)+1+Math.floor(Math.random()*3))%Td.length];D(t),de(e=>e===`blue`?`orange`:`blue`),p(1);return}let t=e===E;t?me.current+=1:(he.current+=1,O(e=>Math.max(0,e-1))),We(t?`correct`:`wrong`);let r=t?fe:fe-1;if(ce>=19||r<=0){Ze(`attention`,Id(me.current,ce+1,he.current,20),`memory`);return}let i=ce+1,a=Fd(),o=Math.random()>.5?`blue`:`orange`;le(i),D(a),de(o),k(Rd(i,o,a))},it=e=>{Ye();let t=be.filter(t=>e.includes(t)).length,n=e.filter(e=>!be.includes(e)).length;if(Ie.current+=t,Le.current+=be.length,Re.current+=n+be.length-t,We(n===0&&t===be.length?`correct`:`wrong`),ge<3){let e=ge+1;_e(e),xe($([0,1,2,3,4,5,6,7]).slice(0,e+1)),Ce([]),Te([]),De($([0,1,2,3,4,5,6,7])),ye(`study`),s(jd[e])}else Ge(),Ze(`memory`,qe(),`money`)},at=(e,t)=>{if(be.every(e=>Se.includes(e))||Se.includes(e))return;if(!be.includes(e)){Re.current+=1,We(`wrong`);return}let n=[...Se,e];if(Ce(n),We(`correct`),be.every(e=>n.includes(e))){window.setTimeout(()=>it(n),180);return}if(!t)return;let r=window.setInterval(()=>{if(!document.body.contains(t)){window.clearInterval(r);return}t.getBoundingClientRect().left<=window.innerWidth||(window.clearInterval(r),Te(t=>t.includes(e)?t:[...t,e]))},120);Be.current.push(r)},ot=Md[Ae-1],st=ot.target,ct=Pe.reduce((e,t)=>e+t,0),lt=()=>{let e=Math.abs(ct-st)<.01;if(We(e?`correct`:`wrong`),e){Qe(!0);return}if(M.current+=1,Me===0){Ne(1),Fe([]);return}Qe(!1)},ut=e=>{let t=be[f-2];n!==`memory`||f<2||f>3||e!==t||(We(`correct`),p(e=>e+1))},dt=e=>{n===`money`&&(f===0&&e===1?(Fe([1]),p(1)):f===1&&e===2&&(Fe([1,2]),p(2)))},N=e=>{Fe(t=>t.filter((t,n)=>n!==e))},ft=()=>{if(g===`report`){t(`report`);return}Je(g)},pt=Math.round(Object.values(v).reduce((e,t)=>e+(t.score||70),0)/5),mt=[[`speed`,`处理速度`,dd],[`executive`,`执行功能`,sd],[`attention`,`注意力`,_d],[`memory`,`工作记忆`,pd],[`calculation`,`计算能力`,qu]],ht=[...mt].sort((e,t)=>v[t[0]].score-v[e[0]].score),P=ht[0][1],gt=ht[ht.length-1][1],_t=Object.values(v).reduce((e,t)=>e+t.correct,0),vt=Object.values(v).reduce((e,t)=>e+t.errors,0),yt=Math.round(Object.values(v).reduce((e,t)=>e+t.completion,0)/5),bt=Math.round(ze.current/1e3),xt={symbol:`符号速配`,trail:`交替连线`,attention:`方向追踪`,memory:`购物记忆`,money:`零钱计算`}[m],St=n===`symbol`?f>=2:n===`trail`?f>=4:n===`attention`?f>=2:n===`memory`?f>=4:n===`money`&&f>=2,Ct=!St&&n===`symbol`?{target:`.keypad button[data-number="${ee.indexOf(C)}"]`,text:f===0?`完成第一次试玩:找到目标图标对应的数字并点击。`:`图标已经换位,再完成一次匹配。`,onTargetClick:()=>tt(ee.indexOf(C))}:!St&&n===`trail`?{target:`.trail-node[data-index="${f}"]`,text:f===0?`先点击数字 1。`:f===1?`接着点击最小的绿色扇区。`:f===2?`然后点击数字 2。`:`再点击第二小的绿色扇区,完成试玩。`,onTargetClick:()=>nt(f)}:!St&&n===`attention`?{target:`.direction-console button[data-direction="${E}"]`,text:`${f===0?`第一次试玩`:`再试一次`}:目标是${ue===`blue`?`青绿色`:`珊瑚色`}飞机,点击机头对应的方向键。`,onTargetClick:()=>rt(E)}:!St&&n===`memory`?f===0?{target:`.memory-demo-stage .shopping-tab`,text:`先点击购物清单,把需要寻找的商品图片展开。`,onTargetClick:()=>{ke(!0),p(1)}}:f===1?{target:`.memory-demo-stage .shopping-tab`,text:`记住清单后先收起,传送带才会继续。`,onTargetClick:()=>{ke(!1),p(2)}}:f<4?{target:`.memory-demo-stage .demo-belt-item[data-index="${be[f-2]}"]`,text:f===2?`点击清单中的第一个商品。`:`再点击清单中的第二个商品。`,onTargetClick:()=>ut(be[f-2])}:null:!St&&n===`money`?{target:`.demo-change-stage .money-pad button[data-value="${f===0?1:2}"]`,text:f===0?`试玩目标是 3 元,先选择 1 元。`:`再选择 2 元,组成 3 元,完成试玩。`,onTargetClick:()=>dt(f===0?1:2)}:null;return(0,H.jsxs)(`div`,{className:`web-app screen-${e}`,children:[e===`home`&&(0,H.jsxs)(`main`,{className:`landing-shell`,children:[(0,H.jsxs)(`nav`,{children:[(0,H.jsx)(zd,{}),(0,H.jsxs)(`span`,{className:`home-duration`,children:[(0,H.jsx)(yd,{weight:`fill`}),` 约 10 分钟`]})]}),(0,H.jsxs)(`section`,{className:`home-start`,children:[(0,H.jsxs)(`header`,{className:`home-copy`,children:[(0,H.jsx)(`img`,{className:`home-visual`,src:`/assets/ui/home-compass.png`,alt:``}),(0,H.jsxs)(`p`,{className:`eyebrow`,children:[(0,H.jsx)(ld,{weight:`fill`}),` DAILY CHECK-IN`]}),(0,H.jsxs)(`h1`,{children:[`开始今天的`,(0,H.jsx)(`br`,{}),(0,H.jsx)(`span`,{children:`状态评估`})]}),(0,H.jsx)(`p`,{children:`填写三项基础信息,然后直接进入第一个小游戏。`})]}),(0,H.jsxs)(`div`,{className:`home-fields`,children:[(0,H.jsxs)(`label`,{children:[(0,H.jsx)(`span`,{children:`年龄`}),(0,H.jsxs)(`select`,{value:i.age,onChange:e=>a({...i,age:e.target.value}),children:[(0,H.jsx)(`option`,{value:``,children:`请选择年龄`}),(0,H.jsx)(`option`,{children:`18-29 岁`}),(0,H.jsx)(`option`,{children:`30-44 岁`}),(0,H.jsx)(`option`,{children:`45-59 岁`}),(0,H.jsx)(`option`,{children:`60-69 岁`}),(0,H.jsx)(`option`,{children:`70 岁以上`})]})]}),(0,H.jsxs)(`label`,{children:[(0,H.jsx)(`span`,{children:`性别`}),(0,H.jsxs)(`select`,{value:i.gender,onChange:e=>a({...i,gender:e.target.value}),children:[(0,H.jsx)(`option`,{value:``,children:`请选择性别`}),(0,H.jsx)(`option`,{children:`女`}),(0,H.jsx)(`option`,{children:`男`}),(0,H.jsx)(`option`,{children:`不便透露`})]})]}),(0,H.jsxs)(`label`,{children:[(0,H.jsx)(`span`,{children:`教育程度`}),(0,H.jsxs)(`select`,{value:i.education,onChange:e=>a({...i,education:e.target.value}),children:[(0,H.jsx)(`option`,{value:``,children:`请选择教育程度`}),(0,H.jsx)(`option`,{children:`初中及以下`}),(0,H.jsx)(`option`,{children:`高中 / 中专`}),(0,H.jsx)(`option`,{children:`大专 / 本科`}),(0,H.jsx)(`option`,{children:`研究生及以上`})]})]})]}),(0,H.jsxs)(`div`,{className:`home-actions`,children:[(0,H.jsxs)(Bd,{disabled:!i.age||!i.gender||!i.education,onClick:()=>{et(),Je(`symbol`)},children:[`开始评估 `,(0,H.jsx)(Wu,{weight:`bold`})]}),(0,H.jsxs)(`small`,{children:[(0,H.jsx)(rd,{weight:`bold`}),` 匿名完成,信息仅用于本次结果`]})]})]}),(0,H.jsx)(`p`,{className:`legal`,children:`结果仅供自我了解,不构成医疗诊断或治疗建议。`})]}),e===`complete`&&(0,H.jsxs)(`main`,{className:`completion-screen completion-${m}`,children:[(0,H.jsx)(`img`,{className:`completion-art`,src:wd[m],alt:``}),(0,H.jsx)(`p`,{children:xt}),(0,H.jsx)(`h1`,{children:`本项游戏已结束`}),(0,H.jsxs)(Bd,{onClick:ft,children:[g===`report`?`查看结果`:`进入下一个游戏`,` `,(0,H.jsx)(Wu,{weight:`bold`})]})]}),e===`profile`&&(0,H.jsx)(`main`,{className:`center-shell`,children:(0,H.jsxs)(`section`,{className:`profile-card`,children:[(0,H.jsxs)(`button`,{className:`back-link`,onClick:()=>t(`home`),children:[(0,H.jsx)(Hu,{}),` 返回首页`]}),(0,H.jsxs)(`div`,{className:`profile-grid`,children:[(0,H.jsxs)(`div`,{children:[(0,H.jsx)(`p`,{className:`eyebrow`,children:`BEFORE WE START`}),(0,H.jsx)(`h1`,{children:`让报告更贴近你`}),(0,H.jsx)(`p`,{children:`这些信息只用于解释本次表现,不需要姓名、手机号或账号。`}),(0,H.jsxs)(`div`,{className:`privacy-panel`,children:[(0,H.jsx)(rd,{size:26}),(0,H.jsxs)(`span`,{children:[(0,H.jsx)(`b`,{children:`匿名完成`}),(0,H.jsx)(`small`,{children:`不会建立公开个人档案`})]})]})]}),(0,H.jsxs)(`div`,{className:`form-panel`,children:[(0,H.jsxs)(`label`,{children:[`年龄范围`,(0,H.jsxs)(`select`,{value:i.age,onChange:e=>a({...i,age:e.target.value}),children:[(0,H.jsx)(`option`,{value:``,children:`请选择`}),(0,H.jsx)(`option`,{children:`18-29 岁`}),(0,H.jsx)(`option`,{children:`30-44 岁`}),(0,H.jsx)(`option`,{children:`45-59 岁`}),(0,H.jsx)(`option`,{children:`60-69 岁`}),(0,H.jsx)(`option`,{children:`70 岁以上`})]})]}),(0,H.jsxs)(`label`,{children:[`性别`,(0,H.jsxs)(`select`,{value:i.gender,onChange:e=>a({...i,gender:e.target.value}),children:[(0,H.jsx)(`option`,{value:``,children:`请选择`}),(0,H.jsx)(`option`,{children:`女`}),(0,H.jsx)(`option`,{children:`男`}),(0,H.jsx)(`option`,{children:`不便透露`})]})]}),(0,H.jsxs)(`label`,{children:[`最高教育程度`,(0,H.jsxs)(`select`,{value:i.education,onChange:e=>a({...i,education:e.target.value}),children:[(0,H.jsx)(`option`,{value:``,children:`请选择`}),(0,H.jsx)(`option`,{children:`初中及以下`}),(0,H.jsx)(`option`,{children:`高中 / 中专`}),(0,H.jsx)(`option`,{children:`大专 / 本科`}),(0,H.jsx)(`option`,{children:`研究生及以上`})]})]}),(0,H.jsxs)(Bd,{disabled:!i.age||!i.gender||!i.education,onClick:()=>t(`overview`),children:[`继续 `,(0,H.jsx)(Wu,{})]})]})]})]})}),e===`overview`&&(0,H.jsxs)(`main`,{className:`overview-shell`,children:[(0,H.jsxs)(`nav`,{children:[(0,H.jsx)(zd,{}),(0,H.jsx)(`span`,{children:`测试准备`})]}),(0,H.jsxs)(`header`,{children:[(0,H.jsx)(`p`,{className:`eyebrow`,children:`YOUR ASSESSMENT`}),(0,H.jsx)(`h1`,{children:`五项任务,逐步完成`}),(0,H.jsx)(`p`,{children:`每项开始前都有练习,不计入最终结果。`})]}),(0,H.jsx)(`section`,{className:`task-grid`,children:[{Icon:dd,no:`01`,title:`符号速配`,domain:`处理速度`,time:`60 秒`,tone:`violet`},{Icon:sd,no:`02`,title:`交替连线`,domain:`执行功能`,time:`180 秒`,tone:`mint`},{Icon:_d,no:`03`,title:`动态追踪`,domain:`注意力`,time:`60 秒`,tone:`blue`},{Icon:pd,no:`04`,title:`购物记忆`,domain:`工作记忆`,time:`180 秒`,tone:`coral`},{Icon:qu,no:`05`,title:`零钱计算`,domain:`计算能力`,time:`约 2 分钟`,tone:`blue`}].map(({Icon:e,no:t,title:n,domain:r,time:i,tone:a})=>(0,H.jsxs)(`article`,{className:`task-card ${a}`,children:[(0,H.jsx)(`span`,{children:t}),(0,H.jsx)(`i`,{children:(0,H.jsx)(e,{size:34,weight:`duotone`})}),(0,H.jsx)(`small`,{children:r}),(0,H.jsx)(`h3`,{children:n}),(0,H.jsxs)(`b`,{children:[(0,H.jsx)($u,{}),` `,i]})]},t))}),(0,H.jsxs)(`div`,{className:`overview-action`,children:[(0,H.jsxs)(`span`,{children:[(0,H.jsx)(td,{weight:`fill`}),` 找一个安静的位置,保持浏览器全屏体验更佳。`]}),(0,H.jsxs)(Bd,{onClick:()=>{et(),Je(`symbol`)},children:[`进入第一项 `,(0,H.jsx)(Wu,{})]})]})]}),e===`symbol`&&(0,H.jsxs)(`main`,{className:`game-shell symbol-shell ${n===`symbol`?`tutorial-active`:``}`,children:[(0,H.jsx)(Vd,{seconds:o,onBack:()=>d(!0)}),(0,H.jsxs)(`section`,{className:`symbol-layout`,children:[(0,H.jsx)(`div`,{className:`target-zone`,children:(0,H.jsx)(`div`,{className:`target-object`,children:(0,H.jsx)(`img`,{src:xd[C],alt:``})},x)}),(0,H.jsxs)(`div`,{className:`symbol-console`,children:[(0,H.jsx)(Oc,{id:`symbol-map`,children:(0,H.jsx)(`div`,{className:`symbol-map`,children:ee.map((e,t)=>(0,H.jsxs)(`div`,{"data-symbol":e,children:[(0,H.jsx)(`b`,{children:t}),(0,H.jsx)(_u.img,{layoutId:`symbol-${e}`,transition:{type:`spring`,stiffness:240,damping:25},src:xd[e],alt:``})]},t))})}),(0,H.jsx)(`div`,{className:`keypad`,children:[1,2,3,4,5,6,7,8,9,0].map(e=>(0,H.jsx)(`button`,{"data-number":e,onClick:()=>tt(e),children:e},e))})]})]})]}),e===`trail`&&(0,H.jsxs)(`main`,{className:`game-shell trail-shell ${n===`trail`?`tutorial-active`:``}`,children:[(0,H.jsx)(Vd,{seconds:o,onBack:()=>d(!0)}),(0,H.jsxs)(`section`,{className:`trail-board`,children:[(0,H.jsx)(`svg`,{className:`trail-lines`,viewBox:`0 0 100 100`,preserveAspectRatio:`none`,children:(0,H.jsx)(`polyline`,{points:ae.slice(0,Math.max(1,n===`trail`?f:re)).map(e=>`${e.x},${e.y}`).join(` `)})}),Q.map((e,t)=>{let r=ae[t],i=n===`trail`?f:re;return(0,H.jsx)(`button`,{"data-index":t,onClick:()=>nt(t),className:`trail-node ${e.kind} ${td(!0)}),(0,H.jsxs)(`section`,{className:`sky-stage`,children:[(0,H.jsxs)(`div`,{className:`attention-title`,children:[(0,H.jsx)(`span`,{children:`寻找目标颜色`}),(0,H.jsx)(`strong`,{className:ue,children:ue===`blue`?`青绿色飞机`:`珊瑚色飞机`}),(0,H.jsx)(`small`,{children:[0,1,2].map(e=>(0,H.jsx)(td,{weight:e(0,H.jsx)(`img`,{className:`moving-plane ${e.color} fly-${e.direction}`,src:Cd[e.color],alt:e.target?`目标飞机`:`干扰飞机`,style:{"--lane":`${e.lane}%`,"--angle":`${Od[e.direction]}deg`,animationDuration:`${e.duration}s`,animationDelay:`${e.delay}s`}},e.id)),(0,H.jsx)(`div`,{className:`direction-console`,children:Td.map(e=>{let t=Ed[e];return(0,H.jsxs)(`button`,{"data-direction":e,className:`direction-${e}`,onClick:()=>rt(e),"aria-label":Dd[e],children:[(0,H.jsx)(t,{weight:`bold`}),(0,H.jsx)(`span`,{children:Dd[e]})]},e)})})]})]}),e===`memory`&&(0,H.jsxs)(`main`,{className:`game-shell memory-shell ${n===`memory`?`tutorial-active`:``}`,children:[(0,H.jsx)(Vd,{seconds:o,onBack:()=>d(!0)}),n===`memory`&&(0,H.jsxs)(`section`,{className:`market-stage memory-demo-stage ${Oe?`list-open`:``}`,children:[(0,H.jsxs)(`button`,{className:`shopping-tab ${Oe?`open`:``}`,children:[(0,H.jsx)(`b`,{children:`购物清单`}),(0,H.jsx)(`span`,{children:Oe?`收起`:`点击查看`}),Oe&&(0,H.jsx)(`div`,{className:`shopping-list-preview`,children:be.slice(0,2).map(e=>(0,H.jsx)(`span`,{children:(0,H.jsx)(`img`,{src:Sd[e].image,alt:``})},e))})]}),Oe&&(0,H.jsx)(`button`,{className:`market-list-shade`,"aria-label":`收起购物清单`,onClick:()=>ke(!1)}),(0,H.jsxs)(`div`,{className:`conveyor memory-demo-belt`,children:[(0,H.jsx)(`div`,{className:`belt-lines`}),[...be.slice(0,2),...Ee.filter(e=>!be.slice(0,2).includes(e)).slice(0,1)].map(e=>{let t=Sd[e];return(0,H.jsx)(`button`,{"data-index":e,className:`demo-belt-item`,onClick:()=>ut(e),children:(0,H.jsx)(`img`,{src:t.image,alt:t.name})},e)})]})]}),n!==`memory`&&ve===`study`&&(0,H.jsxs)(`section`,{className:`study-stage`,children:[(0,H.jsxs)(`div`,{className:`memory-study-copy`,children:[(0,H.jsxs)(`p`,{className:`eyebrow`,children:[`SHOPPING LIST · ROUND `,ge]}),(0,H.jsx)(`h2`,{children:`记住需要购买的物品`}),(0,H.jsx)(`p`,{children:`正式选择时回看清单会记录次数与停留时长,并影响工作记忆评分。`})]}),(0,H.jsxs)(`div`,{className:`memory-study-board`,children:[(0,H.jsxs)(`header`,{children:[(0,H.jsxs)(`b`,{children:[`第 `,ge,` 轮`]}),(0,H.jsxs)(`span`,{children:[be.length,` 件物品`]})]}),(0,H.jsx)(`div`,{children:be.map(e=>(0,H.jsx)(`img`,{src:Sd[e].image,alt:``},e))}),(0,H.jsxs)(Bd,{onClick:()=>{Ce([]),s(jd[ge]),ye(`conveyor`)},children:[`我记好了 `,(0,H.jsx)(Wu,{})]})]})]}),n!==`memory`&&ve===`conveyor`&&(0,H.jsxs)(`section`,{className:`market-stage ${Oe?`list-open`:``}`,children:[(0,H.jsxs)(`button`,{className:`shopping-tab ${Oe?`open`:``}`,onClick:Ke,children:[(0,H.jsx)(`b`,{children:`购物清单`}),(0,H.jsx)(`span`,{children:Oe?`收起`:`回看会影响评分`}),Oe&&(0,H.jsx)(`div`,{className:`shopping-list-preview`,children:be.map(e=>{let t=Se.includes(e);return(0,H.jsxs)(`span`,{className:t?`selected`:``,children:[(0,H.jsx)(`img`,{src:Sd[e].image,alt:``}),t&&(0,H.jsx)(`i`,{children:(0,H.jsx)(Yu,{weight:`bold`})})]},e)})})]}),Oe&&(0,H.jsx)(`button`,{className:`market-list-shade`,"aria-label":`收起购物清单`,onClick:Ge}),(0,H.jsxs)(`div`,{className:`conveyor`,children:[(0,H.jsx)(`div`,{className:`belt-lines`}),Ee.map((e,t)=>{if(we.includes(e))return null;let n=Sd[e],r=Se.includes(e);return(0,H.jsxs)(`button`,{className:`belt-item ${n.tone} ${r?`selected`:``}`,style:{animationDelay:`${t*3.5}s`},onClick:t=>at(e,t.currentTarget),children:[(0,H.jsx)(`img`,{src:n.image,alt:n.name}),r&&(0,H.jsx)(`i`,{children:(0,H.jsx)(Yu,{weight:`bold`})})]},e)})]})]})]}),e===`money`&&(0,H.jsxs)(`main`,{className:`game-shell money-shell ${n===`money`?`tutorial-active`:``}`,children:[(0,H.jsx)(Vd,{seconds:o,onBack:()=>d(!0)}),(0,H.jsxs)(`section`,{className:`change-stage ${n===`money`?`demo-change-stage`:``}`,children:[(0,H.jsxs)(`div`,{className:`change-summary`,children:[(0,H.jsx)(`p`,{className:`eyebrow`,children:n===`money`?`找零试玩`:`EXACT CHANGE · ROUND ${Ae} / ${Md.length}`}),(0,H.jsx)(`h2`,{children:`组合正确的找零金额`}),(0,H.jsxs)(`div`,{children:[(0,H.jsxs)(`span`,{children:[`商品价格 `,(0,H.jsxs)(`b`,{children:[`¥`,n===`money`?7:ot.price]})]}),(0,H.jsxs)(`span`,{children:[`顾客付款 `,(0,H.jsxs)(`b`,{children:[`¥`,n===`money`?10:ot.payment]})]})]}),(0,H.jsx)(`strong`,{children:n===`money`?`应找零 ¥3.00`:`请自行计算应找金额`})]}),(0,H.jsxs)(`div`,{className:`cash-desk`,children:[(0,H.jsxs)(`div`,{className:`cash-display`,children:[(0,H.jsx)(`span`,{children:`当前已选`}),(0,H.jsxs)(`b`,{children:[`¥`,ct.toFixed(2)]}),(0,H.jsx)(`div`,{children:Pe.map((e,t)=>(0,H.jsxs)(`button`,{"data-cash-index":t,onClick:()=>N(t),"aria-label":`移除 ${e} 元`,children:[(0,H.jsx)(`img`,{src:Nd(e),alt:``}),(0,H.jsx)(`i`,{className:`cash-remove`,children:(0,H.jsx)(ad,{weight:`bold`})})]},`${e}-${t}`))})]}),(0,H.jsx)(`div`,{className:`money-pad`,children:Ad.map(e=>(0,H.jsx)(`button`,{"data-value":e.value,onClick:()=>n===`money`?dt(e.value):Fe(t=>[...t,e.value]),"aria-label":`${e.value} 元`,children:(0,H.jsx)(`img`,{src:e.image,alt:``})},e.value))}),n!==`money`&&(0,H.jsx)(Bd,{disabled:!Pe.length,onClick:lt,children:`提交找零`})]})]})]}),e===`report`&&(0,H.jsxs)(`main`,{className:`report-shell`,children:[(0,H.jsxs)(`nav`,{children:[(0,H.jsx)(zd,{}),(0,H.jsxs)(`span`,{className:`report-chip`,children:[(0,H.jsx)(ld,{weight:`fill`}),` AI 表现报告`]})]}),(0,H.jsxs)(`header`,{className:`report-hero`,children:[(0,H.jsxs)(`div`,{children:[(0,H.jsx)(`p`,{className:`eyebrow`,children:`YOUR COGNITIVE SNAPSHOT`}),(0,H.jsx)(`h1`,{children:`本次综合表现`}),(0,H.jsx)(`p`,{children:`以下结果结合准确率、完成度与错误情况生成。`})]}),(0,H.jsx)(`img`,{className:`report-complete-art`,src:`/assets/ui/finish-all.png`,alt:``}),(0,H.jsxs)(`div`,{className:`score-orb`,children:[(0,H.jsx)(`small`,{children:`综合得分`}),(0,H.jsx)(`strong`,{children:pt}),(0,H.jsx)(`span`,{children:`/100`})]})]}),(0,H.jsxs)(`section`,{className:`report-facts`,children:[(0,H.jsxs)(`span`,{children:[(0,H.jsx)(`small`,{children:`完成度`}),(0,H.jsxs)(`b`,{children:[yt,`%`]})]}),(0,H.jsxs)(`span`,{children:[(0,H.jsx)(`small`,{children:`正确操作`}),(0,H.jsx)(`b`,{children:_t})]}),(0,H.jsxs)(`span`,{children:[(0,H.jsx)(`small`,{children:`错误操作`}),(0,H.jsx)(`b`,{children:vt})]})]}),(0,H.jsx)(`section`,{className:`metric-grid`,children:mt.map(([e,t,n])=>{let r=v[e],i=r.score||70;return(0,H.jsxs)(`article`,{children:[(0,H.jsxs)(`div`,{children:[(0,H.jsx)(n,{weight:`duotone`}),(0,H.jsxs)(`span`,{children:[(0,H.jsx)(`small`,{children:t}),(0,H.jsx)(`b`,{children:i})]})]}),(0,H.jsx)(`i`,{children:(0,H.jsx)(`span`,{style:{width:`${i}%`}})}),(0,H.jsxs)(`div`,{className:`metric-data`,children:[(0,H.jsxs)(`span`,{children:[(0,H.jsx)(`small`,{children:`正确`}),(0,H.jsxs)(`b`,{children:[r.correct,`/`,r.total]})]}),(0,H.jsxs)(`span`,{children:[(0,H.jsx)(`small`,{children:`错误`}),(0,H.jsx)(`b`,{children:r.errors})]}),(0,H.jsxs)(`span`,{children:[(0,H.jsx)(`small`,{children:`完成`}),(0,H.jsxs)(`b`,{children:[r.completion,`%`]})]})]}),(0,H.jsx)(`p`,{children:i>=80?`表现稳定,速度和准确度配合较好。`:i>=60?`整体平稳,仍有进一步提升空间。`:`波动较明显,建议休息后再尝试。`})]},e)})}),(0,H.jsxs)(`section`,{className:`insight-panel`,children:[(0,H.jsxs)(`div`,{children:[(0,H.jsx)(`img`,{className:`report-insight-art`,src:`/assets/ui/report-insight.png`,alt:``}),(0,H.jsxs)(`span`,{children:[(0,H.jsx)(`small`,{children:`AI 指标总结`}),(0,H.jsx)(`h2`,{children:pt>=80?`整体状态稳定`:pt>=60?`整体状态平稳`:`本次表现存在波动`})]})]}),(0,H.jsxs)(`p`,{children:[`本次得分最高的维度是`,(0,H.jsx)(`strong`,{children:P}),`,相对需要关注的是`,(0,H.jsx)(`strong`,{children:gt}),`。购物记忆正式阶段回看清单 `,(0,H.jsxs)(`strong`,{children:[A.current,` 次`]}),`、累计 `,(0,H.jsxs)(`strong`,{children:[bt,` 秒`]}),`,已作为工作记忆评分的扣分因素;零钱计算单独统计,不再混入购物记忆。`]}),(0,H.jsxs)(`div`,{children:[(0,H.jsxs)(`span`,{children:[(0,H.jsx)(hd,{weight:`fill`}),` 相对优势:`,P]}),(0,H.jsxs)(`span`,{children:[(0,H.jsx)(qu,{}),` 建议关注:`,gt]})]})]}),(0,H.jsxs)(`div`,{className:`report-actions`,children:[(0,H.jsx)(Bd,{secondary:!0,onClick:()=>window.print(),children:`保存报告`}),(0,H.jsxs)(Bd,{onClick:()=>{et(),Je(`symbol`)},children:[`重新评估 `,(0,H.jsx)(Wu,{})]})]}),(0,H.jsx)(`p`,{className:`legal`,children:`结果仅供自我了解与能力参考,不构成医疗或诊断建议。`})]}),c&&(0,H.jsx)(`div`,{className:`feedback-pop ${c}`,"aria-label":c===`correct`?`正确`:`错误`,children:c===`correct`?(0,H.jsx)(Yu,{weight:`bold`}):(0,H.jsx)(Z,{weight:`bold`})}),Ct&&(0,H.jsx)(Hd,{target:Ct.target,text:Ct.text,onTargetClick:Ct.onTargetClick}),n&&St&&(0,H.jsx)(Ud,{onStart:()=>Xe(n)}),u&&(0,H.jsx)(`div`,{className:`dialog-backdrop`,children:(0,H.jsxs)(`section`,{className:`dialog-card`,children:[(0,H.jsx)(`h2`,{children:`退出当前任务?`}),(0,H.jsx)(`p`,{children:`当前进度不会保留,你可以返回继续完成。`}),(0,H.jsx)(Bd,{onClick:()=>d(!1),children:`继续测试`}),(0,H.jsx)(`button`,{onClick:()=>{d(!1),r(null),t(`home`)},children:`退出任务`})]})})]})}function Gd(){return(0,H.jsx)(Wd,{})}x.createRoot(document.getElementById(`root`)).render((0,H.jsx)(b.StrictMode,{children:(0,H.jsx)(Gd,{})})); \ No newline at end of file diff --git a/brain-h5/dist/client/assets/index-ouTen0sP.css b/brain-h5/dist/client/assets/index-ouTen0sP.css new file mode 100644 index 0000000..8aa6b1a --- /dev/null +++ b/brain-h5/dist/client/assets/index-ouTen0sP.css @@ -0,0 +1 @@ +@font-face{font-family:Roboto;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/roboto-latin-500-normal-7RbcRiD8.woff2)format("woff2"),url(/assets/roboto-latin-500-normal-DQZyH_nt.woff)format("woff")}:root{color:#172033;font-synthesis:none;text-rendering:optimizelegibility;-webkit-font-smoothing:antialiased;background:#f4f8ff;font-family:Inter,PingFang SC,Microsoft YaHei,system-ui,sans-serif}*{box-sizing:border-box}html,body,#root{width:100%;min-width:320px;min-height:100%;margin:0}body{min-height:100vh;overflow-x:hidden}button,input,select{font:inherit}button{cursor:pointer}button:focus-visible,select:focus-visible{outline-offset:3px;outline:3px solid #267cff47}h1,h2,h3,p{margin:0}:root{--ink:#172033;--muted:#69758b;--blue:#3978ff;--cyan:#23c8d5;--violet:#8156ed;--mint:#16ae91;--coral:#f27672;--paper:#ffffffd1;--line:#1a2d4e1a;--shadow:0 30px 80px #1f37621f}html,body{overscroll-behavior-y:none;min-height:100%}body{min-height:100dvh}.web-app{background:radial-gradient(circle at 12% 10%,#37bcae26,#0000 26%),radial-gradient(circle at 88% 4%,#3e80b41f,#0000 25%),linear-gradient(145deg,#f7fbfc 0%,#eef6f4 52%,#f8f7f1 100%);min-height:100vh;position:relative;overflow:hidden}.landing-shell,.overview-shell,.report-shell,.game-shell,.center-shell{z-index:1;width:min(1480px,100% - 64px);min-height:100vh;margin:0 auto;position:relative}nav{height:92px;color:var(--muted);justify-content:space-between;align-items:center;font-size:13px;display:flex}.brand{color:var(--ink);align-items:center;gap:10px;display:flex}.brand>span{color:#fff;background:linear-gradient(135deg, var(--cyan), var(--blue), var(--violet));border-radius:15px;place-items:center;width:44px;height:44px;display:grid;box-shadow:0 12px 24px #3a70e73d}.brand b{letter-spacing:-.04em;font-size:20px}.brand em{border-left:1px solid var(--line);color:#8a95a8;letter-spacing:.18em;padding-left:10px;font-size:9px;font-style:normal}.eyebrow{color:#4b6eb9;letter-spacing:.17em;align-items:center;gap:7px;font-size:11px;font-weight:900;display:flex}.primary-button{color:#fff;background:linear-gradient(105deg,#123d5b,#0f8d82 62%,#246f94);border:0;border-radius:19px;justify-content:center;align-items:center;gap:10px;min-height:58px;padding:0 28px;font-weight:850;transition:transform .2s,box-shadow .2s,opacity .2s;display:inline-flex;box-shadow:0 18px 36px #21737438}.primary-button:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 22px 44px #2a5bb44d}.primary-button:active:not(:disabled){transform:translateY(0)}.primary-button:disabled{opacity:.38;cursor:not-allowed}.primary-button.secondary{color:#385079;border:1px solid var(--line);background:#fff;box-shadow:0 10px 30px #1f376214}.hero{grid-template-columns:minmax(0,.92fr) minmax(560px,1.08fr);align-items:center;gap:clamp(40px,7vw,120px);min-height:calc(100vh - 150px);padding:50px 2vw 100px;display:grid}.hero-copy h1{letter-spacing:-.065em;margin:24px 0;font-size:clamp(48px,5.4vw,86px);line-height:1.03}.hero-copy h1 span{color:#0000;background:linear-gradient(90deg,#177fba,#566fea 48%,#9a54df);-webkit-background-clip:text;background-clip:text}.hero-copy>p:not(.eyebrow){max-width:650px;color:var(--muted);font-size:clamp(16px,1.3vw,20px);line-height:1.85}.hero-actions{align-items:center;gap:22px;margin-top:36px;display:flex}.hero-actions small{color:#748197;align-items:center;gap:7px;display:flex}.feature-strip{gap:36px;margin-top:48px;display:flex}.feature-strip span{color:var(--muted);gap:2px;font-size:11px;display:grid}.feature-strip b{color:var(--ink);letter-spacing:-.04em;font-size:26px}.hero-stage{height:min(680px,70vh);min-height:540px;box-shadow:inset 0 0 0 1px #ffffff73, var(--shadow);-webkit-backdrop-filter:blur(24px);backdrop-filter:blur(24px);background:linear-gradient(145deg,#ffffffa6,#e5f1ff73);border:1px solid #ffffffe6;border-radius:54px;position:relative}.hero-stage:before{content:"";border:1px solid #4069ba1a;border-radius:50%;position:absolute;inset:10% 12%;transform:rotate(-12deg)}.hero-stage:after{content:"";border:1px dashed #704cd121;border-radius:50%;position:absolute;inset:20% 7%;transform:rotate(20deg)}.brain-object{z-index:3;color:#4770dc;background:linear-gradient(145deg,#fff,#e9f1ff 50%,#eee6ff);border-radius:42% 58% 54% 46%/45% 43% 57% 55%;place-items:center;width:260px;height:260px;animation:5s ease-in-out infinite brain-float;display:grid;position:absolute;top:48%;left:50%;transform:translate(-50%,-50%);box-shadow:0 42px 65px #364b8233,inset 8px 8px 16px #fff}.brain-object i{border-radius:inherit;border:1px solid #4477e61f;animation:2.8s ease-out infinite pulse-ring;position:absolute;inset:-24px}.brain-object span{color:#078e88;letter-spacing:.12em;background:#dffffa;border-radius:99px;padding:7px 10px;font-size:9px;font-weight:900;position:absolute;top:18px;right:12px}.glass-orbit{z-index:4;color:#fff;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border:1px solid #fff;border-radius:24px;place-items:center;width:72px;height:72px;animation:4s ease-in-out infinite orbit-float;display:grid;position:absolute;box-shadow:0 20px 36px #2f497d2e}.orbit-a{background:linear-gradient(145deg,#22d0c8,#3196db);top:18%;left:12%}.orbit-b{background:linear-gradient(145deg,#ff9b73,#ed607f);animation-delay:-.8s;top:25%;right:11%}.orbit-c{background:linear-gradient(145deg,#7e65ee,#b35ddb);animation-delay:-1.7s;bottom:18%;right:18%}.hero-meter{z-index:4;-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);background:#ffffffc7;border:1px solid #fff;border-radius:22px;width:230px;padding:18px;position:absolute;bottom:8%;left:8%;box-shadow:0 18px 35px #283c691f}.hero-meter small{color:var(--muted)}.hero-meter strong{margin:4px 0 12px;display:block}.hero-meter>i{background:#e6eaf3;border-radius:99px;height:6px;display:block;overflow:hidden}.hero-meter>i span{border-radius:inherit;background:linear-gradient(90deg, var(--cyan), var(--blue), var(--violet));width:76%;height:100%;display:block}.legal{color:#8994a6;text-align:center;padding:18px 0 28px;font-size:11px}.center-shell{place-items:center;padding:52px 0;display:grid}.profile-card{width:min(1180px,100%);box-shadow:var(--shadow);-webkit-backdrop-filter:blur(24px);backdrop-filter:blur(24px);background:#ffffffb8;border:1px solid #fff;border-radius:42px;padding:34px}.back-link{color:var(--muted);background:0 0;border:0;align-items:center;gap:8px;font-weight:750;display:flex}.profile-grid{grid-template-columns:1fr 1fr;align-items:center;gap:90px;padding:50px 5%;display:grid}.profile-grid h1{letter-spacing:-.055em;margin:14px 0 18px;font-size:clamp(38px,4vw,62px)}.profile-grid>div>p:not(.eyebrow){color:var(--muted);line-height:1.8}.privacy-panel{color:#168b7b;background:#effffc;border:1px solid #18ad9124;border-radius:20px;align-items:center;gap:14px;margin-top:32px;padding:18px;display:flex}.privacy-panel span{gap:2px;display:grid}.privacy-panel small{color:#67928e}.form-panel{background:#fff;border-radius:30px;padding:30px;box-shadow:0 20px 50px #283c6917}.form-panel label{color:#44516a;gap:8px;margin-bottom:18px;font-size:12px;font-weight:850;display:grid}.form-panel select{border:1px solid var(--line);width:100%;height:54px;color:var(--ink);background:#f9fbff;border-radius:15px;padding:0 14px}.form-panel .primary-button{width:100%;margin-top:12px}.overview-shell{padding-bottom:60px}.overview-shell>header{text-align:center;padding:70px 0 36px}.overview-shell>header .eyebrow{justify-content:center}.overview-shell>header h1{letter-spacing:-.06em;margin:14px 0;font-size:clamp(42px,5vw,68px)}.overview-shell>header>p:last-child{color:var(--muted)}.task-grid{grid-template-columns:repeat(4,1fr);gap:18px;display:grid}.task-card{background:#ffffffb8;border:1px solid #fff;border-radius:30px;min-height:290px;padding:24px;transition:transform .25s;position:relative;overflow:hidden;box-shadow:0 20px 50px #283c6914}.task-card:hover{transform:translateY(-6px)}.task-card>span{color:#1f2f4a14;font-size:68px;font-weight:950;position:absolute;top:12px;right:18px}.task-card>i{border-radius:22px;place-items:center;width:64px;height:64px;margin-bottom:58px;display:grid}.task-card.violet>i{color:#7655d8;background:#eee7ff}.task-card.mint>i{color:#128b78;background:#ddfbf5}.task-card.blue>i{color:#2f70de;background:#e1edff}.task-card.coral>i{color:#d85e68;background:#ffe7e7}.task-card small{color:var(--muted);font-weight:750}.task-card h3{margin:6px 0 22px;font-size:27px}.task-card>b{color:#778398;align-items:center;gap:6px;font-size:12px;display:flex}.overview-action{background:#ffffffad;border:1px solid #fff;border-radius:25px;justify-content:space-between;align-items:center;margin-top:26px;padding:18px 20px;display:flex}.overview-action>span{color:var(--muted);align-items:center;gap:8px;font-size:12px;display:flex}.overview-action>span svg{color:#ef6a7d}.game-shell{width:min(1600px,100% - 44px);padding-bottom:30px}.game-header{grid-template-columns:56px 1fr auto;align-items:center;gap:22px;height:86px;display:grid}.round-button{color:#44536d;background:#ffffffc2;border:1px solid #fff;border-radius:16px;place-items:center;width:48px;height:48px;display:grid;box-shadow:0 10px 24px #283c691a}.game-progress{justify-self:center;width:min(600px,100%)}.game-progress>div{color:var(--muted);letter-spacing:.08em;justify-content:space-between;margin-bottom:8px;font-size:10px;font-weight:850;display:flex}.game-progress>i{background:#4554751a;border-radius:99px;height:7px;display:block;overflow:hidden}.game-progress>i span{border-radius:inherit;background:linear-gradient(90deg,#22b8b0,#3387b8,#8abf67);height:100%;transition:width .35s;display:block}.timer{color:#384860;background:#ffffffbd;border:1px solid #fff;border-radius:16px;justify-content:center;align-items:center;gap:8px;min-width:105px;height:46px;padding:0 15px;display:flex}.timer svg{color:#4e75d5}.intro-backdrop,.dialog-backdrop{z-index:50;-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);background:#121c317a;place-items:center;padding:22px;display:grid;position:fixed;inset:0}.intro-card,.dialog-card{background:#fffffff5;border:1px solid #fff;border-radius:32px;width:min(560px,100%);padding:38px;box-shadow:0 40px 100px #121c3147}.intro-number{float:right;color:#284b911a;font-size:80px;font-weight:950;line-height:.8}.intro-card h2{letter-spacing:-.05em;margin:12px 0 10px;font-size:38px}.intro-card>p:not(.eyebrow){color:var(--muted);line-height:1.7}.intro-rules{gap:9px;margin:22px 0;display:grid}.intro-rules span{color:#516078;align-items:center;gap:9px;font-size:13px;display:flex}.intro-rules svg{color:var(--mint)}.practice-panel{background:linear-gradient(145deg,#fff,#eef8f5);border:1px solid #ffffffe6;border-radius:22px;gap:12px;margin:18px 0 12px;padding:16px;display:grid;box-shadow:inset 0 1px #ffffffe6,0 16px 34px #243e5a14}.practice-panel>span{color:#41516a;font-size:12px;font-weight:850}.practice-panel button{color:#16384f;background:#fff;border:1px solid #1a4e5d1a;border-radius:16px;font-weight:900;transition:transform .16s,border-color .16s,background .16s;box-shadow:0 8px 18px #243e5a14}.practice-panel button:hover{border-color:#0f8d824d;transform:translateY(-2px)}.practice-panel button.done,.practice-panel button.picked{color:#087c71;background:#e6faf5;border-color:#0f8d8259}.symbol-practice{justify-items:center}.symbol-practice>img{object-fit:contain;filter:drop-shadow(0 16px 14px #22354e29);width:112px;height:112px}.symbol-practice>div{grid-template-columns:repeat(3,54px);gap:8px;display:grid}.symbol-practice button{height:48px;font-size:18px}.trail-practice{grid-template-columns:repeat(3,1fr);align-items:center}.trail-practice>span{grid-column:1/-1}.trail-practice button{place-items:center;height:58px;font-size:18px;display:grid}.trail-practice i{background:conic-gradient(from -90deg, #119c79 0 42%, #edf3ef 42% 100%);border-radius:50%;width:38px;height:38px}.attention-practice{justify-items:center}.attention-practice>img{object-fit:contain;filter:drop-shadow(0 14px 12px #22354e2e);width:128px;height:90px}.attention-practice>div{grid-template-columns:repeat(4,48px);gap:8px;display:grid}.attention-practice button{place-items:center;height:46px;display:grid}.memory-practice>div{grid-template-columns:repeat(3,1fr);gap:8px;display:grid}.memory-practice button{place-items:center;gap:4px;min-height:84px;display:grid}.memory-practice img{object-fit:contain;filter:drop-shadow(0 10px 8px #47372624);width:48px;height:48px}.memory-practice b{font-size:11px}.practice-trigger{color:#4b6eb9;background:#f2f7ff;border:1px dashed #3b70d740;border-radius:16px;justify-content:center;align-items:center;gap:8px;width:100%;min-height:54px;margin-bottom:14px;font-weight:750;display:flex}.practice-trigger.done{color:#168b7b;background:#eefffb;border-color:#168b7b40}.intro-card .primary-button{width:100%}.dialog-card h2{margin-bottom:8px;font-size:28px}.dialog-card p{color:var(--muted);margin-bottom:24px}.dialog-card .primary-button{width:100%}.dialog-card>button:last-child{color:#d45e6d;background:0 0;border:0;width:100%;margin-top:12px;font-weight:750}.feedback-pop{z-index:80;color:#fff;border-radius:22px;justify-content:center;align-items:center;gap:8px;min-width:110px;height:70px;padding:0 22px;font-weight:850;animation:.62s both feedback-in;display:flex;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);box-shadow:0 25px 60px #18264340}.feedback-pop.correct{background:linear-gradient(135deg,#13bda6,#268ee9)}.feedback-pop.wrong{background:linear-gradient(135deg,#ff8d6d,#e85e7e)}.symbol-layout{grid-template-columns:.82fr 1.18fr;align-items:center;gap:34px;min-height:calc(100vh - 118px);padding:20px 2% 46px;display:grid}.target-zone{min-height:620px;box-shadow:var(--shadow);background:linear-gradient(145deg,#ffffffd6,#e1f7f1ad);border:1px solid #fff;border-radius:42px;flex-direction:column;justify-content:center;align-items:center;padding:54px;display:flex}.target-zone h2{margin:12px 0 30px;font-size:clamp(28px,3vw,48px)}.target-zone>span{color:var(--muted);font-size:12px;font-weight:800}.target-object{color:#0f8479;background:linear-gradient(145deg,#fff,#e9f8f2);border:1px solid #fff;border-radius:52px;place-items:center;width:210px;height:210px;margin-bottom:26px;animation:.5s cubic-bezier(.2,.8,.2,1) both target-enter;display:grid;box-shadow:0 35px 60px #19685d29,inset 6px 6px 15px #fff}.target-object img{object-fit:contain;filter:drop-shadow(0 18px 18px #22354e2e);width:158px;height:158px}.symbol-console{box-shadow:var(--shadow);background:#ffffffb8;border:1px solid #fff;border-radius:42px;padding:34px}.symbol-map{background:#edf7f1;border-radius:28px;grid-template-columns:repeat(5,1fr);gap:10px;padding:22px;display:grid}.symbol-map>div{color:#0f8479;background:#fff;border:1px solid #ffffffe6;border-radius:18px;grid-template-columns:auto 1fr;place-items:center;gap:6px;min-height:92px;display:grid;box-shadow:0 8px 18px #2d37540f}.symbol-map b{color:var(--ink);font-size:17px}.symbol-map img{object-fit:contain;filter:drop-shadow(0 10px 10px #22354e26);width:58px;height:58px}.keypad{grid-template-columns:repeat(5,1fr);gap:10px;width:min(520px,100%);margin:24px auto 0;display:grid}.keypad button{color:#fff;background:linear-gradient(160deg,#0f8d82,#123d5b);border:0;border-radius:20px;height:70px;font-size:24px;font-weight:850;transition:transform .16s;box-shadow:0 12px 22px #0f5c5c33,inset 0 1px #ffffff40}.keypad button:hover{transform:translateY(-3px)}.trail-heading{justify-content:space-between;align-items:center;height:105px;padding:8px 2%;display:flex}.trail-heading h2{margin-top:7px;font-size:clamp(27px,3vw,44px)}.trail-heading>span{color:#127c6b;background:#edfffacc;border:1px solid #fff;border-radius:99px;padding:12px 18px;font-size:12px;font-weight:850}.trail-board{height:calc(100vh - 220px);min-height:620px;box-shadow:var(--shadow), inset 0 0 80px #1cbb9114;background:radial-gradient(circle,#f5fffcf5,#d6f9e6d9);border:1px solid #fff;border-radius:38px;position:relative;overflow:hidden}.trail-board:before{content:"";background-image:radial-gradient(#1d846d17 1px,#0000 1px);background-size:28px 28px;position:absolute;inset:0;-webkit-mask-image:linear-gradient(#0000,#000 20% 80%,#0000);mask-image:linear-gradient(#0000,#000 20% 80%,#0000)}.trail-lines{pointer-events:none;width:100%;height:100%;position:absolute;inset:0}.trail-lines polyline{fill:none;stroke:#138b72;stroke-width:.48px;stroke-linecap:round;stroke-linejoin:round;vector-effect:non-scaling-stroke;filter:drop-shadow(0 2px 3px #138b7233);animation:.35s both line-draw}.trail-node{z-index:2;color:#253246;background:linear-gradient(145deg,#fff,#edf1f0);border:3px solid #1d957b8c;border-radius:50%;place-items:center;width:clamp(44px,4.1vw,66px);height:clamp(44px,4.1vw,66px);font-size:clamp(14px,1.5vw,21px);font-weight:900;transition:opacity .2s,transform .2s;display:grid;position:absolute;transform:translate(-50%,-50%);box-shadow:0 13px 24px #194f4329,inset 3px 3px 7px #fff}.trail-node.shape{background:linear-gradient(145deg,#fff,#e5eae7);border-color:#fff}.trail-node.shape span{background:conic-gradient(from -90deg, #119c79 0 var(--slice), #f5f5f2 var(--slice) 100%);border-radius:50%;width:100%;height:100%;box-shadow:inset -7px -7px 12px #0b4b3b1f,inset 5px 5px 9px #ffffffb3}.trail-node.done{opacity:.46;box-shadow:none}.trail-node:hover{transform:translate(-50%,-50%)scale(1.08)}.attention-shell{background:linear-gradient(#d9e9ff,#edf5ff);width:100%;max-width:none;padding:0 22px 22px}.attention-shell .game-header{max-width:1560px;margin:auto}.sky-stage{background:linear-gradient(#cfe2ff,#eaf3ff);border:1px solid #fffc;border-radius:34px;height:calc(100vh - 108px);min-height:650px;position:relative;overflow:hidden;box-shadow:inset 0 -120px 120px #ffffff52}.attention-title{z-index:10;justify-items:center;gap:4px;display:grid;position:absolute;top:26px;left:50%;transform:translate(-50%)}.attention-title>span{color:#6d7d96;letter-spacing:.12em;font-size:10px;font-weight:850}.attention-title strong{font-size:26px}.attention-title strong.blue{color:#168fa4}.attention-title strong.orange{color:#db6b19}.attention-title small{color:#ed5268;gap:5px;margin-top:5px;display:flex}.cloud{filter:blur(20px);background:#ffffff59;border-radius:50%;width:300px;height:80px;position:absolute}.cloud-a{top:22%;left:8%}.cloud-b{bottom:20%;right:12%}.moving-plane{z-index:5;object-fit:contain;will-change:transform;filter:drop-shadow(0 16px 12px #2b4f8433);width:clamp(72px,7vw,126px);height:clamp(72px,7vw,126px);animation-timing-function:linear;animation-iteration-count:infinite;position:absolute}.fly-right{left:-120px;top:var(--lane);animation-name:fly-right}.fly-left{right:-120px;top:var(--lane);animation-name:fly-left}.fly-up{left:var(--lane);animation-name:fly-up;bottom:-120px}.fly-down{left:var(--lane);animation-name:fly-down;top:-120px}.direction-console{z-index:12;-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);background:#37639338;border:1px solid #ffffffdb;border-radius:28px;grid-template-columns:repeat(4,1fr);gap:10px;padding:12px;display:grid;position:absolute;bottom:28px;left:50%;transform:translate(-50%);box-shadow:0 22px 45px #253d672e}.direction-console button{color:#fff;background:#207a9dbd;border:1px solid #ffffffb3;border-radius:20px;place-items:center;gap:2px;width:clamp(82px,8vw,118px);height:76px;transition:transform .16s,background .16s;display:grid;box-shadow:inset 0 1px #ffffff40}.direction-console button:hover{background:#287fa0;transform:translateY(-4px)}.direction-console svg{width:29px;height:29px}.direction-console span{font-size:10px;font-weight:750}.memory-shell{background:linear-gradient(#fff1e8,#fff8f4);width:100%;max-width:none;padding:0 22px 22px}.memory-shell .game-header{max-width:1560px;margin:auto}.money-shell{background:linear-gradient(145deg,#eef8f3,#fff7e8);width:100%;max-width:none;padding:0 22px 22px}.money-shell .game-header{max-width:1560px;margin:auto}.study-stage,.change-stage{grid-template-columns:.85fr 1.15fr;align-items:center;gap:70px;width:min(1260px,92%);min-height:calc(100vh - 110px);margin:auto;display:grid}.study-stage>div h2,.change-summary h2{letter-spacing:-.06em;margin:13px 0 14px;font-size:clamp(40px,5vw,70px)}.study-stage>div>p:last-child{color:var(--muted)}.receipt{background:linear-gradient(#fff,#f8f8f5);border-radius:12px 12px 28px 28px;padding:34px;position:relative;box-shadow:0 28px 70px #5a3f2b26}.receipt:after{content:"";background:linear-gradient(135deg,#0000 12px,#f8f8f5 0) 0 0/24px 24px repeat-x;height:24px;position:absolute;bottom:-15px;left:0;right:0}.receipt header{border-bottom:1px dashed #c9c6bd;justify-content:space-between;padding-bottom:20px;display:flex}.receipt header span{color:var(--muted);font-size:12px}.receipt>div{grid-template-columns:repeat(2,1fr);gap:12px;padding:22px 0;display:grid}.receipt>div>span{background:#f3f5f7;border-radius:18px;align-items:center;gap:12px;min-height:90px;padding:14px;display:flex}.receipt>div img{object-fit:contain;filter:drop-shadow(0 10px 8px #47372629);width:48px;height:48px}.receipt>div svg{width:34px;height:34px}.receipt>div .amber,.receipt>div .orange{color:#b86b13;background:#fff3de}.receipt>div .coral,.receipt>div .pink{color:#cf5966;background:#ffeaed}.receipt>div .yellow{color:#9f7c13;background:#fff8d8}.receipt>div .violet{color:#356e69;background:#e9f8f2}.receipt>div .blue,.receipt>div .cyan{color:#16809c;background:#e3f8ff}.receipt .primary-button{width:100%}.market-stage{min-height:calc(100vh - 108px);padding-top:80px;position:relative}.shopping-tab{z-index:20;color:#3a3a42;background:linear-gradient(#fff,#f0efec);border:0;border-radius:0 0 24px 24px;grid-template-columns:1fr auto;width:min(450px,80%);min-height:68px;padding:14px 22px;display:grid;position:absolute;top:0;left:50%;transform:translate(-50%);box-shadow:0 12px 32px #3f312a1f}.shopping-tab:after{content:"";background:linear-gradient(135deg,#0000 7px,#f0efec 0) 0 0/14px 14px repeat-x;height:14px;position:absolute;bottom:-9px;left:0;right:0}.shopping-tab b{text-align:left}.shopping-tab span{color:#d87531;font-size:11px}.shopping-tab div{color:var(--muted);grid-column:1/-1;margin-top:10px;font-size:12px}.market-status{grid-template-columns:auto auto 1fr;align-items:center;gap:14px;width:min(1500px,95%);margin:20px auto;display:grid}.market-status>span{color:#e95666}.market-status>i{background:#7b4a2f1a;border-radius:99px;height:7px;overflow:hidden}.market-status>i span{background:linear-gradient(90deg,#ef9251,#d76a25);height:100%;transition:width .3s;display:block}.conveyor{background:#34373a;border-top:38px solid #85808a;border-bottom:38px solid #85808a;height:390px;margin:28px -22px;position:relative;overflow:hidden;box-shadow:inset 0 18px 30px #0003,inset 0 -18px 30px #0003}.belt-lines{opacity:.3;background:repeating-linear-gradient(90deg,#0000 0 42px,#b5b1bb 42px 62px);position:absolute;inset:-38px 0}.belt-item{z-index:3;color:#fff;background:0 0;border:0;border-radius:40px;align-content:center;place-items:center;gap:5px;width:150px;height:150px;animation:12s linear infinite conveyor-move;display:grid;position:absolute;left:-180px}.belt-item img{object-fit:contain;filter:drop-shadow(0 16px 10px #00000047);width:118px;height:118px}.belt-item svg{filter:drop-shadow(0 12px 8px #0000003d);width:76px;height:76px}.belt-item span{opacity:0;background:#00000040;border-radius:99px;padding:3px 8px;font-size:10px;transition:opacity .2s}.belt-item:hover span{opacity:1}.belt-item>i{color:#fff;background:#25b65e;border:4px solid #fff;border-radius:50%;place-items:center;width:36px;height:36px;display:grid;position:absolute;top:5px;right:5px;box-shadow:0 8px 18px #00000040}.belt-item.selected:before{content:"";z-index:-1;background:#1d877b38;border-radius:50%;position:absolute;inset:4px}.belt-item.amber,.belt-item.orange{color:#f6a337}.belt-item.coral,.belt-item.pink{color:#f47b89}.belt-item.yellow{color:#f3cf4d}.belt-item.violet{color:#9e77ee}.belt-item.blue,.belt-item.cyan{color:#49c6e2}.memory-submit{justify-content:space-between;align-items:center;width:min(1100px,94%);margin:auto;display:flex}.memory-submit>span{color:var(--muted);font-size:12px}.change-summary>div{grid-template-columns:1fr 1fr;gap:12px;margin:28px 0 16px;display:grid}.change-summary>div span{color:var(--muted);background:#ffffffa6;border:1px solid #fff;border-radius:18px;gap:5px;padding:16px;display:grid}.change-summary>div b{color:var(--ink);font-size:24px}.change-summary>strong{color:#d76d25;font-size:32px}.cash-desk{box-shadow:var(--shadow);background:#ffffffc2;border:1px solid #fff;border-radius:34px;padding:30px}.cash-display{color:#fff;background:#34383b;border-radius:24px;min-height:140px;padding:22px}.cash-display>span{color:#c8cdd3;font-size:11px}.cash-display>b{margin:5px 0 14px;font-size:38px;display:block}.cash-display>div{flex-wrap:wrap;gap:7px;display:flex}.cash-display button{color:#fff;background:#6aa654;border:0;border-radius:8px;padding:6px 9px;font-size:11px}.money-pad{grid-template-columns:repeat(3,1fr);gap:9px;margin:18px 0;display:grid}.money-pad button{color:#537840;background:linear-gradient(145deg,#f5ffe9,#dcefc5);border:1px solid #4b6c4a29;border-radius:16px;place-items:center;gap:2px;min-height:76px;display:grid;box-shadow:0 8px 16px #41583a14}.money-pad small{font-size:9px}.money-pad b{font-size:17px}.cash-desk .primary-button{width:100%}.memory-study-board{gap:24px;display:grid}.memory-study-board>header{color:#704d38;border-bottom:1px solid #503a2a24;justify-content:space-between;padding-bottom:12px;display:flex}.memory-study-board>header span{color:#8a7468;font-size:12px}.memory-study-board>div{flex-wrap:wrap;justify-content:center;align-items:center;gap:clamp(20px,4vw,54px);min-height:220px;display:flex}.memory-study-board>div img{object-fit:contain;filter:drop-shadow(0 20px 15px #5d402b29);width:clamp(104px,11vw,160px);height:clamp(104px,11vw,160px)}.memory-study-board .primary-button{justify-self:end;min-width:210px}.money-shell .change-summary>div span{background:0 0;border:0;border-bottom:1px solid #2b424224;border-radius:0;padding:8px 0}.money-shell .cash-desk{box-shadow:none;background:0 0;border:0;border-radius:0;padding:0}.money-shell .cash-display{color:#173349;background:0 0;border-bottom:1px solid #2b424224;border-radius:0;min-height:112px;padding:12px 0}.money-shell .cash-display>span{color:#6c7c7f}.money-shell .cash-display>div{min-height:42px}.money-shell .cash-display button{background:0 0;border-radius:0;width:64px;height:44px;padding:0;position:relative;overflow:visible}.money-shell .cash-display button img{object-fit:contain;width:100%;height:100%}.money-shell .cash-remove{color:#fff;pointer-events:none;background:#e95656;border:2px solid #fff;border-radius:50%;place-items:center;width:24px;height:24px;display:grid;position:absolute;top:-8px;right:-7px;box-shadow:0 5px 12px #b4303047}.money-shell .cash-remove svg{width:14px;height:14px}.money-shell .money-pad{gap:8px;margin:12px 0 18px}.money-shell .money-pad button{min-height:126px;box-shadow:none;background:0 0;border:0;border-radius:0;padding:0;transition:transform .16s,filter .16s}.money-shell .money-pad button:hover{filter:brightness(1.04);transform:translateY(-5px)}.money-shell .money-pad button:active{transform:translateY(0)scale(.96)}.money-shell .money-pad img{object-fit:contain;filter:drop-shadow(0 14px 10px #24373d29);width:100%;height:122px}.report-shell{padding-bottom:40px}.report-chip{color:#7354d0;background:#f2edff;border:1px solid #6651d326;border-radius:99px;align-items:center;gap:6px;padding:9px 13px;font-size:11px;font-weight:800;display:flex}.report-hero{min-height:250px;box-shadow:var(--shadow);background:linear-gradient(120deg,#ffffffd1,#ebf6ffbf);border:1px solid #fff;border-radius:34px;justify-content:space-between;align-items:center;padding:45px 5%;display:flex}.report-hero>div>p:last-child{color:var(--muted)}.score-orb{color:#fff;background:conic-gradient(from 20deg,#19c4bc,#3479ee,#8e57df,#19c4bc);border-radius:50%;align-content:center;place-items:center;width:180px;height:180px;display:grid;box-shadow:0 28px 55px #3d59b047}.score-orb small{font-size:10px}.score-orb strong{letter-spacing:-.08em;font-size:72px;line-height:.95}.score-orb span{font-size:10px}.metric-grid{grid-template-columns:repeat(4,1fr);gap:15px;margin-top:22px;display:grid}.metric-grid article{background:#ffffffbf;border:1px solid #fff;border-radius:25px;padding:22px;box-shadow:0 14px 36px #283c6912}.metric-grid article>div{align-items:center;gap:12px;display:flex}.metric-grid article>div>svg{color:#3f76dc;width:40px;height:40px}.metric-grid article>div span{display:grid}.metric-grid small{color:var(--muted)}.metric-grid b{font-size:30px}.metric-grid article>i{background:#e7ebf2;border-radius:99px;height:7px;margin:17px 0;display:block;overflow:hidden}.metric-grid article>i span{background:linear-gradient(90deg,var(--cyan),var(--blue),var(--violet));height:100%;display:block}.metric-grid p{color:var(--muted);font-size:11px;line-height:1.65}.insight-panel{background:#ffffffc7;border:1px solid #456fd524;border-radius:28px;margin-top:20px;padding:30px;box-shadow:0 18px 45px #283c6912}.insight-panel>div:first-child{align-items:flex-start;gap:14px;display:flex}.insight-panel>div:first-child>svg{color:#7658dc;width:36px;height:36px}.insight-panel small{color:#7558cf;font-weight:800}.insight-panel h2{margin-top:5px;font-size:26px}.insight-panel>p{color:var(--muted);margin:20px 0;line-height:1.8}.insight-panel>div:last-child{grid-template-columns:1fr 1fr;gap:12px;display:grid}.insight-panel>div:last-child span{color:#52627b;background:#f5f7fb;border-radius:15px;align-items:center;gap:8px;padding:15px;font-size:12px;display:flex}.insight-panel>div:last-child svg{color:#5a79d4}.report-actions{justify-content:flex-end;gap:12px;margin-top:20px;display:flex}@keyframes brain-float{50%{transform:translate(-50%,-53%)rotate(2deg)}}@keyframes orbit-float{50%{transform:translateY(-12px)rotate(4deg)}}@keyframes pulse-ring{0%{opacity:.7;transform:scale(.9)}to{opacity:0;transform:scale(1.18)}}@keyframes feedback-in{0%{opacity:0;transform:translate(-50%,-44%)scale(.8)}35%{opacity:1;transform:translate(-50%,-50%)scale(1.04)}to{opacity:0;transform:translate(-50%,-55%)scale(1)}}@keyframes target-enter{0%{opacity:0;transform:translateY(-40px)scale(.72)rotate(-7deg)}to{opacity:1;transform:none}}@keyframes line-draw{0%{opacity:.3}to{opacity:1}}@keyframes node-pulse{50%{box-shadow:0 0 0 12px #1ebd9924,0 15px 28px #194f432e}}@keyframes fly-right{0%{transform:translateX(0) rotate(var(--angle))}to{transform:translateX(calc(100vw + 240px)) rotate(var(--angle))}}@keyframes fly-left{0%{transform:translateX(0) rotate(var(--angle))}to{transform:translateX(calc(-100vw - 240px)) rotate(var(--angle))}}@keyframes fly-up{0%{transform:translateY(0) rotate(var(--angle))}to{transform:translateY(calc(-100vh - 240px)) rotate(var(--angle))}}@keyframes fly-down{0%{transform:translateY(0) rotate(var(--angle))}to{transform:translateY(calc(100vh + 240px)) rotate(var(--angle))}}@keyframes conveyor-move{0%{transform:translate(0)}42.8%{transform:translate(calc(100vw + 360px))}42.81%,to{transform:translate(calc(100vw + 360px))}}@media (width<=1050px){.landing-shell,.overview-shell,.report-shell,.center-shell{width:min(94%,820px)}.hero{grid-template-columns:1fr;padding-top:30px}.hero-stage{height:520px;min-height:0}.hero-copy{text-align:center}.hero-copy .eyebrow,.hero-actions{justify-content:center}.hero-copy>p:not(.eyebrow){margin:auto}.feature-strip{justify-content:center}.profile-grid{grid-template-columns:1fr;gap:35px}.task-grid{grid-template-columns:1fr 1fr}.symbol-layout{grid-template-columns:1fr}.target-zone{min-height:380px}.symbol-console{margin-bottom:30px}.study-stage,.change-stage{grid-template-columns:1fr;gap:30px;padding:40px 0}.metric-grid{grid-template-columns:1fr 1fr}}@media (width<=680px){.landing-shell,.overview-shell,.report-shell,.center-shell{width:calc(100% - 28px)}nav{height:74px}.brand em,nav>span{display:none}.hero{flex-direction:column;gap:45px;padding:40px 0 70px;display:flex}.hero-copy h1{font-size:44px}.hero-copy>p:not(.eyebrow){font-size:15px}.hero-actions{flex-direction:column}.feature-strip{gap:18px}.feature-strip b{font-size:22px}.hero-stage{width:100%;height:420px}.brain-object{width:190px;height:190px}.brain-object svg{width:86px}.glass-orbit{border-radius:18px;width:56px;height:56px}.hero-meter{width:190px}.profile-card{padding:20px}.profile-grid{padding:36px 4%}.form-panel{padding:20px}.overview-shell>header{padding-top:40px}.task-grid{grid-template-columns:1fr}.task-card{min-height:220px}.task-card>i{margin-bottom:28px}.overview-action{flex-direction:column;align-items:stretch;gap:16px}.overview-action .primary-button{width:100%}.game-shell{width:100%;padding:0 10px 16px}.game-header{grid-template-columns:45px 1fr auto;gap:8px;height:76px}.round-button{width:42px;height:42px}.timer{min-width:78px;padding:0 9px;font-size:11px}.timer svg{display:none}.symbol-layout{gap:12px;padding:8px 0 25px}.target-zone{border-radius:28px;min-height:310px;padding:28px}.target-zone h2{font-size:25px}.target-object{border-radius:38px;width:145px;height:145px}.target-object svg{width:65px}.target-object img{width:108px;height:108px}.symbol-console{border-radius:28px;padding:14px}.symbol-map{gap:5px;padding:10px}.symbol-map>div{grid-template-columns:1fr;min-height:66px}.symbol-map svg{width:22px}.symbol-map img{width:36px;height:36px}.symbol-map b{font-size:12px}.keypad{gap:6px}.keypad button{border-radius:15px;height:54px;font-size:19px}.trail-heading{flex-direction:column;justify-content:center;align-items:flex-start;gap:10px;height:120px}.trail-heading h2{font-size:25px}.trail-board{border-radius:24px;height:calc(100vh - 215px);min-height:580px}.trail-node{border-width:2px;width:42px;height:42px}.attention-shell,.memory-shell,.money-shell{padding:0 10px 10px}.sky-stage{border-radius:24px;height:calc(100vh - 90px);min-height:620px}.attention-title{top:16px}.direction-console{border-radius:20px;gap:5px;width:calc(100% - 20px);padding:7px;bottom:14px}.direction-console button{border-radius:15px;width:auto;height:64px}.direction-console span{display:none}.study-stage,.change-stage{width:96%;min-height:calc(100vh - 85px)}.study-stage>div h2,.change-summary h2{font-size:39px}.receipt{padding:22px}.receipt>div{grid-template-columns:1fr 1fr;gap:8px}.receipt>div>span{gap:7px;min-height:72px;padding:9px}.receipt>div svg{width:26px}.receipt>div img{width:38px;height:38px}.market-stage{padding-top:70px}.shopping-tab{min-height:58px}.market-status{grid-template-columns:auto auto}.market-status>i{grid-column:1/-1}.conveyor{height:360px;margin-left:-10px;margin-right:-10px}.belt-item{width:118px;height:118px}.belt-item svg{width:62px;height:62px}.belt-item img{width:92px;height:92px}.memory-submit{flex-direction:column;align-items:stretch;gap:10px}.memory-submit .primary-button{width:100%}.change-summary>div{grid-template-columns:1fr}.cash-desk{padding:18px}.report-hero{flex-direction:column;align-items:flex-start;gap:25px;padding:28px}.score-orb{align-self:center;width:145px;height:145px}.score-orb strong{font-size:58px}.metric-grid,.insight-panel>div:last-child{grid-template-columns:1fr}.report-actions{flex-direction:column}.report-actions .primary-button{width:100%}.intro-card,.dialog-card{padding:26px}.intro-card h2{font-size:31px}}@media (prefers-reduced-motion:reduce){*,:before,:after{scroll-behavior:auto!important;animation-duration:.01ms!important;animation-iteration-count:1!important}}@media print{.web-app{background:#fff}.report-shell{width:100%}.report-actions,nav{display:none}.report-hero,.metric-grid article,.insight-panel{box-shadow:none}}.screen-symbol{background:#f5f0e7}.screen-trail{background:#d9f7e8}.screen-attention{background:#dceaff}.screen-memory{background:#ffe5d3}.screen-symbol .game-header{color:#263a58}.screen-trail .game-header{color:#176c5a}.screen-attention .game-header{color:#235c9c}.screen-memory .game-header{color:#9a542d}.screen-symbol .game-progress>i span{background:#d57949}.screen-trail .game-progress>i span{background:#16a879}.screen-attention .game-progress>i span{background:#458de4}.screen-memory .game-progress>i span{background:#e6793b}.screen-symbol .timer svg{color:#d57949}.screen-trail .timer svg{color:#15936e}.screen-attention .timer svg{color:#4b86d3}.screen-memory .timer svg{color:#dd783b}.symbol-shell,.trail-shell,.attention-shell,.memory-shell,.money-shell{min-height:100dvh}.symbol-shell{background:#f5f0e7}.symbol-layout{min-height:calc(100dvh - 118px)}.symbol-layout .target-zone{background:#ffffff4d}.symbol-map>div{background:#ffffffd1}.keypad{grid-template-columns:repeat(3,minmax(0,1fr))}.keypad button{background:#253f64;border-radius:18px}.keypad button:last-child{grid-column:2}.target-object{animation:2.7s ease-in-out infinite target-float,.5s cubic-bezier(.2,.8,.2,1) both target-enter}.target-object img{animation:2.7s ease-in-out infinite target-image-float}.trail-shell{background:#d9f7e8}.trail-board{background:#d8f7e7;box-shadow:inset 0 0 80px #16a8791f}.trail-heading>span{color:#137e66;background:#ffffffa3}.attention-shell{background:#dceaff}.attention-shell .sky-stage{background:#cfe1fb;border-color:#ffffffbf}.direction-console{width:210px;height:210px;box-shadow:none;-webkit-backdrop-filter:none;backdrop-filter:none;background:0 0;border:0;grid-template-rows:repeat(3,1fr);grid-template-columns:repeat(3,1fr);gap:10px;padding:0;display:grid}.direction-console button{background:#559bb6;border-radius:22px;width:auto;height:auto;box-shadow:0 12px 20px #2c5d8529}.direction-console button:hover{background:#3f879f}.memory-shell{background:#ffe5d3}.memory-shell .market-stage{min-height:calc(100dvh - 108px)}.shopping-list-preview{gap:8px;display:flex;overflow:hidden}.shopping-list-preview span{justify-items:center;gap:2px;min-width:46px;display:grid}.shopping-list-preview img{object-fit:contain;width:38px;height:38px}.shopping-list-preview b{text-overflow:ellipsis;white-space:nowrap;max-width:46px;font-size:10px;overflow:hidden}.conveyor{height:330px}.belt-item{margin-top:-75px;top:50%}.belt-item img{width:122px;height:122px}.memory-submit{color:#8d5e48}.memory-submit>b{color:#d26f32;font-size:20px}.timeout-card{text-align:center}.timeout-card>svg{color:#d7793d;margin:0 auto 12px}@keyframes target-float{50%{transform:translateY(-8px)rotate(2deg)}}@keyframes target-image-float{50%{transform:translateY(-7px)rotate(2deg)scale(1.02)}}@media (width<=680px){html,body,#root{min-height:100%}.landing-shell,.center-shell,.overview-shell{height:100dvh;min-height:100dvh;overflow:hidden}.landing-shell nav{height:62px}.landing-shell .hero{grid-template-rows:auto minmax(130px,1fr);gap:14px;min-height:calc(100dvh - 92px);padding:10px 0 18px;display:grid}.hero-copy h1{margin:12px 0;font-size:36px;line-height:1.04}.hero-copy>p:not(.eyebrow){font-size:13px;line-height:1.55}.hero-actions{gap:10px;margin-top:18px}.hero-actions .primary-button{min-height:50px}.hero-actions small{font-size:10px}.feature-strip{gap:24px;margin-top:18px}.feature-strip b{font-size:19px}.hero-stage{border-radius:28px 28px 0 0;height:100%;min-height:130px;overflow:hidden}.brain-object{width:126px;height:126px;top:68%}.brain-object svg{width:66px}.glass-orbit{border-radius:13px;width:42px;height:42px}.hero-meter,.landing-shell>.legal{display:none}.center-shell{padding:8px 0;display:block}.profile-card{border-radius:24px;height:calc(100dvh - 16px);padding:14px;overflow:hidden}.profile-grid{grid-template-rows:auto 1fr;gap:8px;height:calc(100% - 34px);padding:12px 2%}.profile-grid h1{margin:6px 0;font-size:28px}.profile-grid>div>p:not(.eyebrow),.privacy-panel{display:none}.form-panel{border-radius:20px;padding:14px}.form-panel label{gap:4px;margin-bottom:9px}.form-panel select{height:46px}.form-panel .primary-button{min-height:50px;margin-top:4px}.overview-shell{width:calc(100% - 20px);padding-bottom:8px}.overview-shell nav{height:54px}.overview-shell>header{padding:8px 0 10px}.overview-shell>header h1{margin:5px 0;font-size:29px}.overview-shell>header>p:last-child{font-size:11px}.task-grid{grid-template-columns:1fr 1fr;gap:8px}.task-card{border-radius:19px;min-height:148px;padding:12px}.task-card>span{font-size:38px;top:5px;right:9px}.task-card>i{border-radius:13px;width:42px;height:42px;margin-bottom:12px}.task-card small{font-size:9px}.task-card h3{margin:2px 0 8px;font-size:18px}.task-card>b{font-size:10px}.overview-action{border-radius:16px;margin-top:8px;padding:8px}.overview-action>span{display:none}.overview-action .primary-button{min-height:48px}.web-app.screen-symbol,.web-app.screen-trail,.web-app.screen-attention,.web-app.screen-memory{height:100dvh;min-height:100dvh;overflow:hidden}.game-shell{height:100dvh;min-height:0;overflow:hidden}.game-header{flex:none}.symbol-layout{grid-template-rows:39% 61%;align-items:stretch;gap:0;height:calc(100dvh - 76px);min-height:0;padding:0 8px 12px}.symbol-layout .target-zone{min-height:0;box-shadow:none;background:0 0;border:0;border-radius:0;padding:6px 8px 4px}.target-zone .eyebrow{font-size:9px}.target-zone h2{margin:2px 0 4px;font-size:20px}.target-zone>span{font-size:10px}.target-object{border-radius:30px;width:112px;height:112px;margin:4px 0 5px;box-shadow:0 14px 24px #6a4d301f}.target-object img{width:86px;height:86px}.symbol-console{min-height:0;box-shadow:none;background:0 0;border:0;border-radius:0;grid-template-rows:45% 55%;padding:0;display:grid}.symbol-map{background:#ffffff75;border-radius:18px;gap:2px;padding:4px 2px}.symbol-map>div{min-height:0;box-shadow:none;background:#ffffff9e;border:0;border-radius:10px;grid-template-columns:1fr;gap:0}.symbol-map b{font-size:11px;line-height:1}.symbol-map img{width:32px;height:32px}.keypad{align-content:center;gap:6px;width:214px;margin:8px auto 0}.keypad button{border-radius:13px;height:43px;font-size:18px;box-shadow:0 7px 12px #1832532e}.trail-heading{height:74px;padding:0 8px}.trail-heading .eyebrow{font-size:9px}.trail-heading h2{margin-top:2px;font-size:18px}.trail-heading>span{padding:7px 10px;font-size:10px}.trail-board{border:0;border-radius:20px;height:calc(100dvh - 150px);min-height:0}.trail-node{width:37px;height:37px}.attention-shell,.memory-shell,.money-shell{padding:0 8px 8px}.sky-stage{border:0;border-radius:20px;height:calc(100dvh - 84px);min-height:0}.attention-title{top:12px}.attention-title strong{font-size:24px}.direction-console{gap:7px;width:178px;height:178px;bottom:14px}.direction-console button{border-radius:18px}.direction-console span{display:none}.market-stage{height:calc(100dvh - 84px);min-height:0;padding-top:60px}.shopping-tab{border-radius:0 0 18px 18px;width:min(360px,88%);min-height:54px;padding:11px 16px}.market-status{width:94%;margin:8px auto 12px}.conveyor{border-top-width:30px;border-bottom-width:30px;height:245px;margin:12px -8px}.belt-item{width:100px;height:100px;margin-top:-50px}.belt-item img{width:84px;height:84px}.belt-item span{display:none}.belt-item>i{border-width:3px;width:27px;height:27px}.memory-submit{width:94%;min-height:32px;font-size:11px}.memory-submit .primary-button{display:none}.intro-backdrop,.dialog-backdrop{padding:8px}.intro-card,.dialog-card{border-radius:24px;max-height:calc(100dvh - 16px);padding:20px;overflow-y:auto}.intro-card h2{font-size:27px}.intro-rules{gap:5px;margin:12px 0}.intro-rules span{font-size:11px}.practice-panel{border-radius:17px;margin:10px 0;padding:10px}.practice-trigger{min-height:42px;font-size:11px}}.screen-home{background:#f3f7fb}.screen-home .landing-shell{height:100dvh;min-height:720px}.screen-home nav{height:76px}.home-duration{color:#52637b;align-items:center;gap:7px;font-weight:800;display:inline-flex}.brand>span{background:#3778e8;border-radius:13px;box-shadow:0 10px 24px #3778e833}.home-start{grid-template-rows:auto auto auto;grid-template-columns:minmax(0,.9fr) minmax(420px,1.1fr);align-content:center;column-gap:clamp(60px,9vw,150px);min-height:calc(100dvh - 128px);padding:4vh 5vw 6vh;display:grid}.home-start>header{grid-row:1/4;align-self:center}.home-copy{padding-top:clamp(150px,16vw,210px);position:relative}.home-visual{object-fit:contain;pointer-events:none;filter:drop-shadow(0 22px 30px #2c5b9d29);width:clamp(205px,20vw,285px);height:auto;animation:5s ease-in-out infinite visual-float;position:absolute;top:-42px;left:-38px}.home-start h1{color:#16243a;letter-spacing:0;margin:16px 0;font-size:clamp(42px,4.6vw,64px);line-height:1.06}.home-start h1 span{color:#3778e8}.home-start>header>p:last-child{color:#68768b;max-width:480px;font-size:16px;line-height:1.7}.home-fields{border-top:1px solid #1d33521f;gap:8px;display:grid}.home-fields label{border-bottom:1px solid #1d33521f;grid-template-columns:100px 1fr;align-items:center;min-height:72px;display:grid}.home-fields label>span{color:#34455f;font-size:13px;font-weight:850}.home-fields select{color:#17253a;background:0 0;border:0;border-radius:0;outline:0;width:100%;height:52px;padding:0 8px;font-size:16px;font-weight:750}.home-actions{align-items:center;gap:18px;margin-top:24px;display:flex}.home-actions small{color:#7b8798;align-items:center;gap:6px;font-size:11px;display:flex}.screen-home .legal{padding:0;position:absolute;bottom:12px;left:0;right:0}.game-header{grid-template-columns:1fr 1fr;gap:0;height:68px;padding:0 6px}.game-progress{display:none}.round-button{width:44px;height:44px;box-shadow:none;background:#ffffffa8;border:0;border-radius:50%;justify-self:start}.timer{background:0 0;border:0;border-radius:0;justify-self:end;min-width:88px;height:44px;padding:0}.symbol-layout .target-zone,.symbol-console{box-shadow:none;background:0 0;border:0}.symbol-layout .target-zone{min-height:0;padding:0}.target-object{box-shadow:none;background:0 0;border:0}.symbol-map{background:0 0}.symbol-map>div{box-shadow:none;background:0 0;border:0}.symbol-map b{font-size:20px}.symbol-map img{width:70px;height:70px}.keypad{grid-template-columns:repeat(3,64px);justify-content:center;gap:12px;width:246px}.keypad button{color:#1f3048;background:#fff;border:1px solid #20355114;border-radius:50%;width:64px;height:64px;padding:0;font-size:23px;box-shadow:0 10px 18px #23355121}.keypad button:hover{background:#fff;transform:translateY(-2px)}.trail-board,.attention-shell .sky-stage{box-shadow:none;border:0}.trail-board{border-radius:0;height:calc(100dvh - 68px);min-height:0}.trail-node{aspect-ratio:1;border-radius:50%;padding:0;overflow:hidden}.trail-node.current{animation:none}.trail-node.shape span,.trail-practice i{aspect-ratio:1;clip-path:circle(50%);border-radius:50%}.moving-plane{animation-fill-mode:both}.direction-console{grid-template-rows:repeat(2,1fr);grid-template-columns:repeat(3,1fr);gap:9px;width:226px;height:148px}.direction-console button{color:#28526d;background:#fff;border:1px solid #2b5b871a;border-radius:16px;box-shadow:0 8px 16px #2c5d851f}.direction-console button.direction-up{grid-area:1/2}.direction-console button.direction-left{grid-area:2/1}.direction-console button.direction-down{grid-area:2/2}.direction-console button.direction-right{grid-area:2/3}.direction-console button:hover{color:#28526d;background:#fff}.belt-item{animation-duration:28s}.feedback-pop{border:6px solid;border-radius:50%;width:92px;min-width:0;height:92px;padding:0;box-shadow:0 12px 30px #142d412e;background:#fffffff5!important}.feedback-pop svg{filter:none;width:56px;height:56px}.feedback-pop.correct{color:#20a66b}.feedback-pop.wrong{color:#e44d57}.tutorial-card{padding:26px}.tutorial-head{text-align:left}.tutorial-head>span{color:#5b6e8a;letter-spacing:.12em;font-size:10px;font-weight:900}.tutorial-head h2{margin:5px 0 4px}.tutorial-head p{color:#6d798c;font-size:13px;line-height:1.55}.coach-hint{color:#34445d;justify-content:space-between;align-items:center;gap:12px;width:100%;display:flex}.coach-hint span{gap:2px;font-size:12px;display:grid}.coach-hint b{color:#2674d9;font-size:13px}.coach-hint>svg{color:#2674d9;flex:none;width:34px;height:34px;animation:1.15s ease-in-out infinite coach-point}.practice-panel{box-shadow:none;background:#f5f8fc;border:0}.practice-panel button{border-radius:50%}.symbol-practice .practice-key-row{grid-template-columns:repeat(3,54px);gap:10px;display:grid}.practice-directions{grid-template-rows:repeat(2,1fr);gap:6px;width:164px;height:108px;grid-template-columns:repeat(3,1fr)!important;display:grid!important}.practice-directions button{border-radius:12px;width:auto;height:auto}.practice-directions .direction-up{grid-area:1/2}.practice-directions .direction-left{grid-area:2/1}.practice-directions .direction-down{grid-area:2/2}.practice-directions .direction-right{grid-area:2/3}.practice-trigger{background:0 0;border:0}@keyframes coach-point{50%{transform:translateY(7px)}}@media (width<=680px){.screen-home .landing-shell{width:calc(100% - 32px);min-height:100dvh}.screen-home nav{height:62px}.home-duration{font-size:11px;display:flex!important}.home-start{flex-direction:column;justify-content:center;gap:0;min-height:calc(100dvh - 96px);padding:8px 2px 32px;display:flex}.home-copy{padding-top:122px}.home-visual{width:158px;animation:5s ease-in-out infinite visual-float-mobile;top:-20px;left:50%;transform:translate(-50%)}.home-start h1{margin:8px 0;font-size:34px;line-height:1.08}.home-start>header>p:last-child{font-size:13px}.home-fields{margin-top:24px}.home-fields label{grid-template-columns:82px 1fr;min-height:58px}.home-fields select{height:48px;font-size:14px}.home-actions{flex-direction:column;align-items:stretch;gap:10px;margin-top:20px}.home-actions .primary-button{width:100%;min-height:52px}.home-actions small{justify-content:center}.screen-home .legal{font-size:9px;display:block;bottom:8px}.game-header{grid-template-columns:1fr 1fr;height:58px;padding:0 4px}.timer{min-width:72px;font-size:12px}.timer svg{display:block}.symbol-layout{grid-template-rows:31% 69%;height:calc(100dvh - 58px)}.symbol-map{padding:5px}.symbol-map b{font-size:16px}.symbol-map img{width:48px;height:48px}.keypad{grid-template-columns:repeat(3,54px);gap:8px 18px;width:210px}.keypad button{border-radius:50%;width:54px;height:54px;font-size:20px}.trail-board{border-radius:0;height:calc(100dvh - 58px)}.direction-console{width:196px;height:128px;bottom:12px}.direction-console button{border-radius:14px}.sky-stage{height:calc(100dvh - 58px);min-height:0}.market-stage{height:calc(100dvh - 58px)}.tutorial-card{max-height:calc(100dvh - 12px);padding:18px}.tutorial-head h2{font-size:25px}.tutorial-head p,.coach-hint span{font-size:11px}.practice-panel{margin:8px 0}}.coach-layer{z-index:100;pointer-events:none;position:fixed;inset:0}.coach-shade{z-index:100;pointer-events:auto;background:#080f1cb8;position:fixed}.coach-shade-top{top:0;left:0;right:0}.coach-shade-left{left:0}.coach-shade-right{right:0}.coach-shade-bottom{bottom:0;left:0;right:0}.coach-spotlight{z-index:101;pointer-events:none;border:3px solid #fff;border-radius:18px;animation:1.2s ease-in-out infinite coach-spotlight;position:fixed;box-shadow:0 0 0 5px #428dffd9,0 0 28px #428dffb3}.coach-hit-target{z-index:103;cursor:pointer;pointer-events:auto;-webkit-tap-highlight-color:transparent;background:0 0;border:0;border-radius:18px;padding:0;position:fixed}.demo-ready-layer{z-index:120;color:#fff;text-align:center;background:#09111ec7;flex-direction:column;justify-content:center;align-items:center;padding:24px;display:flex;position:fixed;inset:0}.demo-ready-layer>svg{color:#62d79e;width:68px;height:68px;margin-bottom:16px}.demo-ready-layer>p{color:#b9c8dd;font-size:12px;font-weight:800}.demo-ready-layer h2{margin:6px 0 24px;font-size:30px}.demo-ready-layer .primary-button{min-width:230px}.coach-bubble{z-index:102;color:#263750;pointer-events:none;background:#fff;border-radius:16px;gap:5px;min-height:86px;padding:16px 18px;display:grid;position:fixed;box-shadow:0 20px 48px #00000047}.coach-bubble:after{content:"";background:#fff;width:18px;height:18px;position:absolute;left:50%;transform:translate(-50%)rotate(45deg)}.coach-bubble.below:after{top:-8px}.coach-bubble.above:after{bottom:-8px}.coach-bubble b{z-index:1;color:#2877df;font-size:12px;position:relative}.coach-bubble span{z-index:1;font-size:14px;font-weight:750;line-height:1.45;position:relative}.feedback-pop{z-index:110}.coach-plane{z-index:5;width:clamp(104px,10vw,150px);height:clamp(104px,10vw,150px);transform:translate(-50%, -50%) rotate(var(--angle));object-fit:contain;filter:drop-shadow(0 16px 12px #2b4f8433);position:absolute;top:42%;left:50%}.market-stage .conveyor{margin-top:clamp(110px,16vh,160px)}.market-list-shade{z-index:15;cursor:default;background:#12171ea8;border:0;width:100%;height:100%;position:absolute;inset:0}.market-stage.list-open .belt-item{animation-play-state:paused}.market-stage.list-open .conveyor{pointer-events:none}.shopping-list-preview{justify-content:center;overflow:visible}.shopping-list-preview span{min-width:66px;position:relative}.shopping-list-preview img{width:58px;height:58px}.shopping-list-preview b{max-width:66px;font-size:11px}.shopping-list-preview span.selected{opacity:.58}.shopping-list-preview span>i{color:#fff;background:#22a66e;border:2px solid #fff;border-radius:50%;place-items:center;width:23px;height:23px;display:grid;position:absolute;top:0;right:2px;box-shadow:0 5px 12px #19684c3d}.shopping-list-preview span>i svg{width:14px;height:14px}.memory-demo-belt{justify-content:space-around;align-items:center;padding:0 8%;display:flex}.demo-belt-item{z-index:3;background:0 0;border:0;border-radius:24px;width:132px;height:132px;padding:0;position:relative}.demo-belt-item img{object-fit:contain;filter:drop-shadow(0 16px 10px #00000047);width:112px;height:112px}.completion-screen{z-index:2;width:100%;min-height:100dvh;padding:max(28px, env(safe-area-inset-top)) 24px max(28px, env(safe-area-inset-bottom));text-align:center;flex-direction:column;justify-content:center;align-items:center;display:flex;position:relative}.completion-art{object-fit:contain;pointer-events:none;filter:drop-shadow(0 24px 34px #1c304b2e);width:clamp(230px,28vw,330px);height:clamp(230px,28vw,330px);margin:-54px 0 -22px;animation:4.8s ease-in-out infinite visual-float}.completion-screen>p{color:#68768b;font-size:13px;font-weight:800}.completion-screen h1{color:#17243a;letter-spacing:0;margin:8px 0 30px;font-size:clamp(34px,5vw,56px);line-height:1.15}.completion-screen .primary-button{min-width:220px}.screen-complete{background:#f4f6f8}.completion-symbol{background:#f5f0e7}.completion-trail{background:#d9f7e8}.completion-attention{background:#dceaff}.completion-memory{background:#ffe5d3}.completion-money{background:#eef8f3}.report-shell{width:min(1180px,100% - 40px);padding-bottom:24px}.report-hero{border-radius:16px;grid-template-columns:minmax(0,1fr) 150px 116px;align-items:center;gap:24px;min-height:0;padding:24px 28px;display:grid;box-shadow:0 12px 30px #283c6912}.report-complete-art{object-fit:contain;pointer-events:none;filter:drop-shadow(0 16px 24px #23529124);width:150px;height:150px;margin:-28px 0}.report-hero h1{letter-spacing:0;margin:6px 0;font-size:clamp(32px,4vw,48px)}.score-orb{width:116px;height:116px;box-shadow:0 15px 30px #3d59b038}.score-orb strong{letter-spacing:0;font-size:48px}.report-facts{border-bottom:1px solid #22354e1a;grid-template-columns:repeat(3,1fr);min-height:74px;padding:12px 0;display:grid}.report-facts>span{place-items:center;gap:3px;display:grid}.report-facts>span+span{border-left:1px solid #22354e1a}.report-facts small,.metric-data small{color:#748197;font-size:10px}.report-facts b{color:#21334c;font-size:22px}.metric-grid{grid-template-columns:repeat(5,minmax(0,1fr));gap:10px;margin-top:12px}.metric-grid article{border-radius:14px;padding:15px;box-shadow:0 8px 20px #283c690d}.metric-grid article>div>svg{width:32px;height:32px}.metric-grid article>i{margin:11px 0}.metric-data{grid-template-columns:repeat(3,1fr);gap:6px!important;display:grid!important}.metric-data>span{gap:2px;display:grid}.metric-data b{font-size:13px}.metric-grid article>p{margin-top:10px}.insight-panel{border-radius:16px;margin-top:12px;padding:18px 20px;box-shadow:0 8px 24px #283c690d}.report-insight-art{object-fit:contain;filter:drop-shadow(0 10px 14px #2352911f);flex:none;width:54px;height:54px}.insight-panel h2{font-size:21px}.insight-panel>p{margin:12px 0;line-height:1.65}.insight-panel>p strong{color:#405fba;padding:0 3px}.insight-panel>div:last-child span{background:0 0;padding:4px 0}@keyframes coach-spotlight{50%{box-shadow:0 0 0 8px #428dff8c,0 0 34px #428dffd9}}@keyframes visual-float{50%{transform:translateY(-7px)}}@keyframes visual-float-mobile{50%{transform:translate(-50%,-6px)}}@media (width<=680px){.coach-bubble{min-height:80px;padding:14px 16px}.coach-bubble span{font-size:13px}.coach-spotlight{border-radius:15px}.market-stage .conveyor{margin-top:clamp(128px,18vh,158px)}.shopping-tab.open{width:94%;min-height:122px}.shopping-list-preview img{width:54px;height:54px}.memory-demo-belt{padding:0 3%}.demo-belt-item{width:94px;height:94px}.demo-belt-item img{width:82px;height:82px}.coach-plane{width:112px;height:112px;top:38%}.memory-shell .study-stage{grid-template-rows:auto minmax(0,1fr);grid-template-columns:1fr;align-items:stretch;gap:10px;width:100%;height:calc(100dvh - 58px);min-height:0;padding:14px 6px 18px;overflow:hidden}.memory-study-copy .eyebrow{display:none}.memory-study-copy h2{letter-spacing:0!important;margin:0 0 6px!important;font-size:28px!important}.memory-study-copy>p:last-child{font-size:11px;line-height:1.5}.memory-study-board{grid-template-rows:auto minmax(0,1fr) auto;gap:8px;min-height:0}.memory-study-board>header{padding-bottom:6px;font-size:12px}.memory-study-board>div{align-content:center;gap:8px 18px;min-height:0}.memory-study-board>div img{width:clamp(82px,25vw,104px);height:clamp(82px,25vw,104px)}.memory-study-board .primary-button{width:100%;min-height:46px}.money-shell .change-stage{grid-template-rows:auto minmax(0,1fr);grid-template-columns:1fr;align-items:stretch;gap:8px;width:100%;height:calc(100dvh - 58px);min-height:0;padding:6px 4px 10px;overflow:hidden}.money-shell .change-summary .eyebrow{display:none}.money-shell .change-summary h2{letter-spacing:0;margin:0 0 6px;font-size:23px}.money-shell .change-summary>div{grid-template-columns:1fr 1fr;gap:6px;margin:0 0 6px}.money-shell .change-summary>div span{border-radius:9px;padding:7px 9px;font-size:9px}.money-shell .change-summary>div b{font-size:16px}.money-shell .change-summary>strong{font-size:21px}.money-shell .cash-desk{border-radius:14px;grid-template-rows:auto minmax(0,1fr) auto;min-height:0;padding:9px;display:grid}.money-shell .cash-display{border-radius:11px;min-height:68px;padding:9px 12px}.money-shell .cash-display>b{margin:2px 0 4px;font-size:25px}.money-shell .money-pad{gap:5px;margin:7px 0}.money-shell .money-pad button{min-height:72px}.money-shell .money-pad img{height:72px}.money-shell .cash-desk .primary-button{min-height:42px}.report-shell{width:calc(100% - 20px)}.report-shell nav{height:58px}.report-hero{grid-template-columns:minmax(0,1fr) 68px 88px;align-items:center;gap:7px;padding:16px;display:grid}.report-complete-art{width:78px;height:78px;margin:-10px -5px}.report-hero h1{font-size:27px}.report-hero>div>p:last-child{font-size:10px;line-height:1.45}.score-orb{width:88px;height:88px}.score-orb strong{font-size:36px}.report-facts{min-height:62px}.report-facts b{font-size:18px}.metric-grid{grid-template-columns:1fr 1fr}.metric-grid article{min-width:0;padding:12px}.metric-grid b{font-size:23px}.metric-data b{font-size:11px}.metric-grid article>p{font-size:9px}.insight-panel{padding:15px}.insight-panel h2{font-size:18px}.insight-panel>p{font-size:11px}.insight-panel>div:last-child{grid-template-columns:1fr 1fr}.insight-panel>div:last-child span{font-size:10px}.report-insight-art{width:42px;height:42px}.completion-art{width:240px;height:240px;margin:-42px 0 -26px}}@media (prefers-reduced-motion:reduce){.home-visual,.completion-art{animation:none}} diff --git a/brain-h5/dist/client/assets/iphone/Bezel.png b/brain-h5/dist/client/assets/iphone/Bezel.png new file mode 100644 index 0000000..759e8aa Binary files /dev/null and b/brain-h5/dist/client/assets/iphone/Bezel.png differ diff --git a/brain-h5/dist/client/assets/iphone/Keyboard.png b/brain-h5/dist/client/assets/iphone/Keyboard.png new file mode 100644 index 0000000..80207c3 Binary files /dev/null and b/brain-h5/dist/client/assets/iphone/Keyboard.png differ diff --git a/brain-h5/dist/client/assets/money/money-05.png b/brain-h5/dist/client/assets/money/money-05.png new file mode 100644 index 0000000..ffcba5b Binary files /dev/null and b/brain-h5/dist/client/assets/money/money-05.png differ diff --git a/brain-h5/dist/client/assets/money/money-1.png b/brain-h5/dist/client/assets/money/money-1.png new file mode 100644 index 0000000..a8c0775 Binary files /dev/null and b/brain-h5/dist/client/assets/money/money-1.png differ diff --git a/brain-h5/dist/client/assets/money/money-10.png b/brain-h5/dist/client/assets/money/money-10.png new file mode 100644 index 0000000..d82177e Binary files /dev/null and b/brain-h5/dist/client/assets/money/money-10.png differ diff --git a/brain-h5/dist/client/assets/money/money-2.png b/brain-h5/dist/client/assets/money/money-2.png new file mode 100644 index 0000000..b40e75a Binary files /dev/null and b/brain-h5/dist/client/assets/money/money-2.png differ diff --git a/brain-h5/dist/client/assets/money/money-20.png b/brain-h5/dist/client/assets/money/money-20.png new file mode 100644 index 0000000..0c214d8 Binary files /dev/null and b/brain-h5/dist/client/assets/money/money-20.png differ diff --git a/brain-h5/dist/client/assets/money/money-5.png b/brain-h5/dist/client/assets/money/money-5.png new file mode 100644 index 0000000..00acf0d Binary files /dev/null and b/brain-h5/dist/client/assets/money/money-5.png differ diff --git a/brain-h5/dist/client/assets/roboto-latin-500-normal-7RbcRiD8.woff2 b/brain-h5/dist/client/assets/roboto-latin-500-normal-7RbcRiD8.woff2 new file mode 100644 index 0000000..171a2f6 Binary files /dev/null and b/brain-h5/dist/client/assets/roboto-latin-500-normal-7RbcRiD8.woff2 differ diff --git a/brain-h5/dist/client/assets/roboto-latin-500-normal-DQZyH_nt.woff b/brain-h5/dist/client/assets/roboto-latin-500-normal-DQZyH_nt.woff new file mode 100644 index 0000000..7864e64 Binary files /dev/null and b/brain-h5/dist/client/assets/roboto-latin-500-normal-DQZyH_nt.woff differ diff --git a/brain-h5/dist/client/assets/status/ios-status-icons.svg b/brain-h5/dist/client/assets/status/ios-status-icons.svg new file mode 100644 index 0000000..b75235a --- /dev/null +++ b/brain-h5/dist/client/assets/status/ios-status-icons.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/brain-h5/dist/client/assets/status/status-icons.svg b/brain-h5/dist/client/assets/status/status-icons.svg new file mode 100644 index 0000000..8a97e81 --- /dev/null +++ b/brain-h5/dist/client/assets/status/status-icons.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/brain-h5/dist/client/assets/ui/finish-all.png b/brain-h5/dist/client/assets/ui/finish-all.png new file mode 100644 index 0000000..03e0c12 Binary files /dev/null and b/brain-h5/dist/client/assets/ui/finish-all.png differ diff --git a/brain-h5/dist/client/assets/ui/finish-attention.png b/brain-h5/dist/client/assets/ui/finish-attention.png new file mode 100644 index 0000000..7b3e9df Binary files /dev/null and b/brain-h5/dist/client/assets/ui/finish-attention.png differ diff --git a/brain-h5/dist/client/assets/ui/finish-memory.png b/brain-h5/dist/client/assets/ui/finish-memory.png new file mode 100644 index 0000000..f9f5833 Binary files /dev/null and b/brain-h5/dist/client/assets/ui/finish-memory.png differ diff --git a/brain-h5/dist/client/assets/ui/finish-symbol.png b/brain-h5/dist/client/assets/ui/finish-symbol.png new file mode 100644 index 0000000..0596675 Binary files /dev/null and b/brain-h5/dist/client/assets/ui/finish-symbol.png differ diff --git a/brain-h5/dist/client/assets/ui/finish-trail.png b/brain-h5/dist/client/assets/ui/finish-trail.png new file mode 100644 index 0000000..0b5dff8 Binary files /dev/null and b/brain-h5/dist/client/assets/ui/finish-trail.png differ diff --git a/brain-h5/dist/client/assets/ui/home-compass.png b/brain-h5/dist/client/assets/ui/home-compass.png new file mode 100644 index 0000000..8918734 Binary files /dev/null and b/brain-h5/dist/client/assets/ui/home-compass.png differ diff --git a/brain-h5/dist/client/assets/ui/report-insight.png b/brain-h5/dist/client/assets/ui/report-insight.png new file mode 100644 index 0000000..7367b3b Binary files /dev/null and b/brain-h5/dist/client/assets/ui/report-insight.png differ diff --git a/brain-h5/dist/client/index.html b/brain-h5/dist/client/index.html new file mode 100644 index 0000000..7ed4ca4 --- /dev/null +++ b/brain-h5/dist/client/index.html @@ -0,0 +1,14 @@ + + + + + + + 脑晴测 + + + + +
+ + diff --git a/brain-h5/dist/server/index.js b/brain-h5/dist/server/index.js new file mode 100644 index 0000000..ff5978a --- /dev/null +++ b/brain-h5/dist/server/index.js @@ -0,0 +1,52 @@ +const SYSTEM_PROMPT = `你是一名数字脑健康表现报告助手。根据用户完成游戏时产生的结构化数据,生成通俗、克制、非医疗化的中文报告。不得诊断疾病,不得推荐药物或医疗处置,不得使用“异常、受损、提示存在问题或挑战”等暗示医学结论的说法。只描述本次表现,优先使用“反应相对偏慢、注意表现有波动、容易遗漏、仍有提升空间”。只输出合法 JSON:{"summary":"80字内总结","strength":"60字内相对优势","opportunity":"60字内提升空间","recommendations":["建议1","建议2","建议3"]}`; + +async function analyze(request, env) { + if (!env.DEEPSEEK_API_KEY) return Response.json({ error: "AI service is not configured" }, { status: 503 }); + try { + const assessment = await request.json(); + const upstream = await fetch("https://api.deepseek.com/chat/completions", { + method: "POST", + headers: { "content-type": "application/json", authorization: `Bearer ${env.DEEPSEEK_API_KEY}` }, + body: JSON.stringify({ + model: "deepseek-chat", + temperature: 0.35, + response_format: { type: "json_object" }, + messages: [ + { role: "system", content: SYSTEM_PROMPT }, + { role: "user", content: JSON.stringify({ profile: assessment.profile, metrics: assessment.metrics, eventCount: assessment.events?.length ?? 0 }) }, + ], + }), + signal: AbortSignal.timeout(15000), + }); + if (!upstream.ok) return Response.json({ error: "AI service request failed" }, { status: 502 }); + const payload = await upstream.json(); + const content = payload?.choices?.[0]?.message?.content; + const rawReport = JSON.parse(String(content || "{}").replace(/^```json\s*|\s*```$/g, "")); + const parsed = { + summary: String(rawReport.summary || "本次四项任务已经完成。"), + strength: String(rawReport.strength || "部分任务表现相对稳定。"), + opportunity: String(rawReport.opportunity || "仍有可以通过规律练习提升的空间。"), + recommendations: Array.isArray(rawReport.recommendations) ? rawReport.recommendations.slice(0, 3).map(String) : [], + }; + return Response.json(parsed, { headers: { "cache-control": "no-store" } }); + } catch { + return Response.json({ error: "AI report could not be generated" }, { status: 502 }); + } +} + +export default { + async fetch(request, env) { + const url = new URL(request.url); + if (url.pathname === "/api/analyze") { + if (request.method !== "POST") return new Response("Method not allowed", { status: 405 }); + return analyze(request, env); + } + const response = await env.ASSETS.fetch(request); + const acceptsHtml = request.headers.get("accept")?.includes("text/html"); + if (response.status !== 404 || !acceptsHtml || !["GET", "HEAD"].includes(request.method)) return response; + const indexUrl = new URL(request.url); + indexUrl.pathname = "/index.html"; + indexUrl.search = ""; + return env.ASSETS.fetch(new Request(indexUrl, request)); + }, +}; diff --git a/brain-h5/index.html b/brain-h5/index.html new file mode 100644 index 0000000..0422ff8 --- /dev/null +++ b/brain-h5/index.html @@ -0,0 +1,13 @@ + + + + + + + 脑晴测 + + +
+ + + diff --git a/brain-h5/mobile-runtime.lock.json b/brain-h5/mobile-runtime.lock.json new file mode 100644 index 0000000..3a5639f --- /dev/null +++ b/brain-h5/mobile-runtime.lock.json @@ -0,0 +1,30 @@ +{ + "scripts/check-mobile-runtime.mjs": "ee85738cc2ef889c0b457d8ccac61e017b8c5d16f393e766ec9fb7d11c9aff7f", + "scripts/prepare-sites-build.mjs": "b6a6adaa4fab3234676116dd1c9cb6611275ab9d92dd26f5bf402393e3744bf6", + "scripts/update-mobile-runtime-lock.mjs": "b4e1aa41133f19ba8bb32685b3ec05798b1ceabaf72c328419d545aa60fe1f0b", + "vite.config.ts": "0e87e403d04a2345ce91b27c0694060bf7c362505bfdf4cae3ffac2a9fc2113b", + "src/App.tsx": "d24c44012ce15f46a8e821b0876a35b9198301e9fd229adabff9673ca0e0c884", + "src/main.tsx": "01b7049715148ab645637905ccbbc91fc3f87659198a309541c2d1f03bb537d0", + "src/styles.css": "a75c99f677a94a5f6f28f4240bdca42de8e323ae6d61920d7d4979d906a0ad74", + "src/mobile/BottomSheet.tsx": "f9c376dc78b8b5feb1c8752aa23414993ab66013d11e81b2ebb8342c570032ac", + "src/mobile/Carousel.tsx": "242f4a7488e18c35e9b43651c9d5877288655a6f9f1734e03e56108f17526bf7", + "src/mobile/Device.tsx": "867de9c65220f2ac7202f895d2b10a64c747f211a4b22cd8f81a1a1d66e52fc2", + "src/mobile/FlowStack.tsx": "1e85744c5f1c1138dd5e8b7b27fbb6c05139d5aac93d94c45084a018eddd4ebc", + "src/mobile/Keyboard.tsx": "862587264375499846385ce817ea1b813db8f118140cdb6da163f989a6946cac", + "src/mobile/MobileCursor.tsx": "be2353205e05d823bc23ecae88179d712781ee9ede8fa317057c194c7c23ee7d", + "src/mobile/MobileRuntime.tsx": "1ffe80a9582460005d66f10fc73deaff08b81431785a506887cc0d8320be747f", + "src/mobile/MobileScroll.tsx": "ea3e3691f587ea13753162b9e64c1981263e5b9beddebea21a6a1551dce76430", + "src/mobile/PhoneFrame.tsx": "73015590b468acbb4b58e3f6fe5eef99c5f68f67722caffd8f00d271ba00a91d", + "src/mobile/assets.ts": "d40cb8e5390fd2b54618266e7694e40349006dfe480f65d60559316ca8c9c234", + "src/mobile/components.tsx": "20b02f6c6de4cfd08aa6a49bf9bc261c0ea000864b37e1001afdcd892afe4bc8", + "src/mobile/geometry.ts": "f1382e5d6cc9adfd7ac142304f2f9a5a2330db1d74b3f0848adbaf311676bf16", + "src/mobile/index.ts": "ee69d9341571db5dee84dd2d7452a62eef09085a84a85f198a3edc48047e0412", + "public/assets/iphone/Bezel.png": "ee2514d74d2f75f3541405fa2f20811f159879a66586778cfd8c9c84c44959df", + "public/assets/iphone/Keyboard.png": "292e2d83d69adaeb663d6a840ce8db8d0a5257710b472c20713e03f56b08ea88", + "public/assets/android/Pixel10.png": "a87c1250ba20756f5d020b5351a7ae71d663dcfc64aca3a1cd56452e8a05233e", + "public/assets/android/Keyboard.png": "6085e50be17ca2705b4351283187be2c5b01b58262c70b90d74b3376efb4adfe", + "public/assets/android/navigation-bar.svg": "077a782a3b6c2915fc518dfb4bba825c8c5861b2572f9522a7024902b9cb2850", + "public/assets/status/status-icons.svg": "1a8bd4207cf34532ae514bdcdca693acc9a2b8ebc9d3182dc163c3e9ddcc4823", + "public/assets/status/ios-status-icons.svg": "40e218b274d0973d519b50f42884e6e05ef0f2b6a0e46e102fda54218784466d", + "worker/index.js": "60a1b9c1f779ba779e1fb7a617c97a3457b843d3c6b7d20906360e8524bf622f" +} diff --git a/brain-h5/package.json b/brain-h5/package.json new file mode 100644 index 0000000..080539c --- /dev/null +++ b/brain-h5/package.json @@ -0,0 +1,35 @@ +{ + "name": "brain-h5", + "private": true, + "version": "0.1.0", + "type": "module", + "scripts": { + "check:runtime": "node scripts/check-mobile-runtime.mjs", + "update:runtime-lock": "node scripts/update-mobile-runtime-lock.mjs", + "test:runtime": "playwright test", + "test:sites": "node --test tests/sites-worker.test.mjs", + "predev": "node scripts/check-mobile-runtime.mjs", + "dev": "vite", + "prebuild": "node scripts/check-mobile-runtime.mjs", + "build": "tsc && vite build && node scripts/prepare-sites-build.mjs" + }, + "dependencies": { + "@fontsource/roboto": "5.2.10", + "@phosphor-icons/react": "^2.1.10", + "@radix-ui/react-dialog": "1.1.19", + "@radix-ui/react-dropdown-menu": "2.1.20", + "@radix-ui/react-icons": "1.3.2", + "@use-gesture/react": "10.3.1", + "motion": "12.42.2", + "react": "19.2.7", + "react-dom": "19.2.7" + }, + "devDependencies": { + "@playwright/test": "1.61.1", + "@types/react": "19.2.17", + "@types/react-dom": "19.2.3", + "@vitejs/plugin-react": "6.0.3", + "typescript": "7.0.2", + "vite": "8.1.3" + } +} diff --git a/brain-h5/playwright.config.ts b/brain-h5/playwright.config.ts new file mode 100644 index 0000000..04d4c8b --- /dev/null +++ b/brain-h5/playwright.config.ts @@ -0,0 +1,18 @@ +import { defineConfig } from "@playwright/test"; + +const testPort = Number(process.env.MOBILE_RUNTIME_TEST_PORT ?? 4174); + +export default defineConfig({ + testDir: "./tests", + testMatch: "**/*.spec.ts", + timeout: 20_000, + use: { + baseURL: `http://127.0.0.1:${testPort}`, + viewport: { width: 1100, height: 1100 }, + }, + webServer: { + command: `npm run dev -- --port ${testPort}`, + url: `http://127.0.0.1:${testPort}/tests/runtime-fixture.html`, + reuseExistingServer: process.env.MOBILE_RUNTIME_TEST_PORT == null, + }, +}); diff --git a/brain-h5/pnpm-lock.yaml b/brain-h5/pnpm-lock.yaml new file mode 100644 index 0000000..a3813a9 --- /dev/null +++ b/brain-h5/pnpm-lock.yaml @@ -0,0 +1,1622 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@fontsource/roboto': + specifier: 5.2.10 + version: 5.2.10 + '@phosphor-icons/react': + specifier: ^2.1.10 + version: 2.1.10(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-dialog': + specifier: 1.1.19 + version: 1.1.19(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-dropdown-menu': + specifier: 2.1.20 + version: 2.1.20(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-icons': + specifier: 1.3.2 + version: 1.3.2(react@19.2.7) + '@use-gesture/react': + specifier: 10.3.1 + version: 10.3.1(react@19.2.7) + motion: + specifier: 12.42.2 + version: 12.42.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: + specifier: 19.2.7 + version: 19.2.7 + react-dom: + specifier: 19.2.7 + version: 19.2.7(react@19.2.7) + devDependencies: + '@playwright/test': + specifier: 1.61.1 + version: 1.61.1 + '@types/react': + specifier: 19.2.17 + version: 19.2.17 + '@types/react-dom': + specifier: 19.2.3 + version: 19.2.3(@types/react@19.2.17) + '@vitejs/plugin-react': + specifier: 6.0.3 + version: 6.0.3(vite@8.1.3) + typescript: + specifier: 7.0.2 + version: 7.0.2 + vite: + specifier: 8.1.3 + version: 8.1.3 + +packages: + + '@emnapi/core@1.11.1': + resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==} + + '@emnapi/runtime@1.11.1': + resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} + + '@emnapi/wasi-threads@1.2.2': + resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} + + '@floating-ui/core@1.8.0': + resolution: {integrity: sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==} + + '@floating-ui/dom@1.8.0': + resolution: {integrity: sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==} + + '@floating-ui/react-dom@2.1.9': + resolution: {integrity: sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/utils@0.2.12': + resolution: {integrity: sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==} + + '@fontsource/roboto@5.2.10': + resolution: {integrity: sha512-8HlA5FtSfz//oFSr2eL7GFXAiE7eIkcGOtx7tjsLKq+as702x9+GU7K95iDeWFapHC4M2hv9RrpXKRTGGBI8Zg==} + + '@napi-rs/wasm-runtime@1.1.6': + resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 + + '@oxc-project/types@0.139.0': + resolution: {integrity: sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==} + + '@phosphor-icons/react@2.1.10': + resolution: {integrity: sha512-vt8Tvq8GLjheAZZYa+YG/pW7HDbov8El/MANW8pOAz4eGxrwhnbfrQZq0Cp4q8zBEu8NIhHdnr+r8thnfRSNYA==} + engines: {node: '>=10'} + peerDependencies: + react: '>= 16.8' + react-dom: '>= 16.8' + + '@playwright/test@1.61.1': + resolution: {integrity: sha512-8nKv6+0RJSL9FE4jYOEGXnPeM/Hg12qZpmqzZjRh3qM0Y7c3z1mrOTfFLids72RDQYVh9WpLEfR5WdpNX4fkig==} + engines: {node: '>=18'} + hasBin: true + + '@radix-ui/primitive@1.1.5': + resolution: {integrity: sha512-d86WIWFYNtGA0H/d8exstrTRTp7eWJYlYJbtNofxr/3ljupZYn6EFDG/Qgu/0Kc8v7yMUxySagqJsL1+PdYjWg==} + + '@radix-ui/react-arrow@1.1.11': + resolution: {integrity: sha512-Kdil9BB1rIFC/khmf4hC35bn8701AJcizTU7G7cUbEbk5XqqbjDuHW60uUfKqO5WojjZcbAW51Q7P0hRmMLw8A==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-collection@1.1.12': + resolution: {integrity: sha512-nb67INpE0IahJKN7EYPp9m9YGwYeKlnzxT3MwXVkgCskaSJia97kG4T0ywpjNUSSnoJk/uvk12V8vbrEHEj+/Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-compose-refs@1.1.3': + resolution: {integrity: sha512-rYOP8OMnuuPMQF1uhPVlGNcCDlkokKqGFE3JcxFViIkAXP7EvFWUliJAstrapypaBLJNHbZL6jGhbVDGTwmVhA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-context@1.2.0': + resolution: {integrity: sha512-fOE+JtN9rygNZkCnHRBEP0TAvLldlhyOxMsbwFvTP4nAs+nBmfnna+o/Zski2wkmY1YMrFC0aSzsHoLY47iLrg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dialog@1.1.19': + resolution: {integrity: sha512-+HhbN2+YtkRgVirjZ2afMeutQRuGOrdkWR5+EFC58SJojGmtyNQwYzgi6tHBpOxvFHefMtPeHdgtjz0BOGxFQg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-direction@1.1.2': + resolution: {integrity: sha512-C3vFhbyi4SW3PmbAi6Awpu4OzJtd0MxGurvSsYtr7p7nM8RNB3VAF3CUmnp2j50knpkrRcB7+ycVXzgLgF6yNA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dismissable-layer@1.1.15': + resolution: {integrity: sha512-b0XaRlzn2QKuo10XyNgi2DAJDf5XC9d1nD3FJcuvCjbR7+4Ad28zmZsLsqx+hvDEzMnRuZaZxZm9gYObV6RmRA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-dropdown-menu@2.1.20': + resolution: {integrity: sha512-slfm+rRaZRuQBvHq60lXvSVUPhid0IPtjSZzIuUlWZMUs01iYZNlGS3mJgRD3ChLQVBAYlKiL/tFyWGX+dz8Xw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-focus-guards@1.1.4': + resolution: {integrity: sha512-cot/aB/mOm0IYVYTTmQcEEK1M48lZWi8FlYe5nDPQQ8NYZUlXEFgncJ9p2Kzer3RKSrY7cTTpEMLZKNo9QoP5Q==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-focus-scope@1.1.12': + resolution: {integrity: sha512-jjk/lqTeNL0azUx5ZYzVrl4NgaDIrdzTNE4mABV9yBFI7FQqN7pIgzV1bTleUezP2QiTGA1BFTqY8MegDgWX9A==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-icons@1.3.2': + resolution: {integrity: sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g==} + peerDependencies: + react: ^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc + + '@radix-ui/react-id@1.1.2': + resolution: {integrity: sha512-orBC88futVpqCmhX1p4cvquNHsELQ+w+vBJnuj3ftETI5bJb0bZn3Tqu3SWN2IOcPycTnMGnhwoermvISt72sA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-menu@2.1.20': + resolution: {integrity: sha512-VsUrXxFe9d2ScbZF0fR/oPR1+qjyeLs5p0jzG8h90puMoA9bq4SirYlXbE+USRg9Q2qTeJSFNqjw2nts8jJe4w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-popper@1.3.3': + resolution: {integrity: sha512-mS7dGpyjv6b+gsDjLF7e0ia1W4Im1B1hSCy2yuXlHuvnZxHKagfDaobt/KAKt27EpZMit2pss8eJBVyVjEWM+g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-portal@1.1.13': + resolution: {integrity: sha512-z3oXfmaHLJTF1wktbjgD6cn9jiEbq3WSondB10LIuIt2m2Ym4iJlrW04/euMwENDdWDdE7z+OuY7Qyp1YpRSwA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-presence@1.1.7': + resolution: {integrity: sha512-zBZ4QM5XG3JRanDmqXYf3MD6th4AFXFmgU6KNMFzUaV6F3uw9I5/zjMUvFriSEn5ewo1nxuibvyxJdmLlDcslA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-primitive@2.1.7': + resolution: {integrity: sha512-bC3NiwsprbxKjuon9l7X6BUTw7FPVzEYaL92MPEY5SCd/9hUTPXVFtVwRix7778wtRsVao+zE062gL79FZleeQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-roving-focus@1.1.15': + resolution: {integrity: sha512-40svmmugfM3mUN7VUDGVE1tQGOhyi8enlGD0CNJEcMM36C1f71PKM21DFgNHUfem0XnA+d8H8oN3Z9ZpJjSslg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slot@1.3.0': + resolution: {integrity: sha512-MojKku4U/miO8Av4Dkb+ctMAQx7JmY96LmtDQlAarCRtd7rN52QCSzBF+XAvr5S6coSVj9HEPBgHAHKEJVk/WA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-callback-ref@1.1.2': + resolution: {integrity: sha512-xCso9j1/u8sEgP1RNHjFrXJLApL8LiqOkI1R4ywuN00rxWdYg4oQXuwKLS3i0j5NWLromUD27/4nlxj2UFVvIw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-controllable-state@1.2.3': + resolution: {integrity: sha512-PLzC90MS+ReootmjC597dvopoelpZ8Q61HJkDXZSExitIq7PL55vHNnesAHwguHK0aPfBnpdNzQtv1uliaqQrA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-effect-event@0.0.3': + resolution: {integrity: sha512-6c8ZqvPTWILEKnyVkP53EGRCcpnJiKTC21sS/6R1GF5xKyHJJWQEPfkqlcgUkdRQivd6tb23abUwe4ngWmY0JA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-is-hydrated@0.1.1': + resolution: {integrity: sha512-qwOiz4Tjo8CNnrOLAYUMXeZwDzXgXpvK4TKQPmWLECM9XoWvA6+0Z2/7Ag3A4ivjS4ovbLJPbskkxioFyBhr8A==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-layout-effect@1.1.2': + resolution: {integrity: sha512-jrBWOxZITuGcnjRCM2t2U5ZPkCLxD+Ym6DjfssS5haTj2iiak/DOb64JeN6OdLfLgptb6/e2kKR+ZuTrGoZTPA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-rect@1.1.2': + resolution: {integrity: sha512-d8a+bBY/FxikNPlgJJoaBHZX+zKVbWHYJGTLnLvveQgFSTntkGdEKv3JDtHrMS0DNYpllz2nRsTLGLKYttbpmw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-size@1.1.2': + resolution: {integrity: sha512-giWQp+4mxjBPt4KZ0MmyuykFNWfbDxKt4x+fPkRYmgRFJSbCZFzUglvMb/Kjn38tm10YP4ufiQZDx3zna4LU6w==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/rect@1.1.2': + resolution: {integrity: sha512-xnXE7wG13PI+cxieVssYXlQJuYVRhH9NBoxt3KNwzghDIA69GMm7d4wXRouHIYjE+KvS6U/MsMO73NdS2MH9ZA==} + + '@rolldown/binding-android-arm64@1.1.5': + resolution: {integrity: sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.1.5': + resolution: {integrity: sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.1.5': + resolution: {integrity: sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.1.5': + resolution: {integrity: sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.1.5': + resolution: {integrity: sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.1.5': + resolution: {integrity: sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.1.5': + resolution: {integrity: sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.1.5': + resolution: {integrity: sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.1.5': + resolution: {integrity: sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.1.5': + resolution: {integrity: sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.1.5': + resolution: {integrity: sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.1.5': + resolution: {integrity: sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.1.5': + resolution: {integrity: sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.1.5': + resolution: {integrity: sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.1.5': + resolution: {integrity: sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} + + '@tybys/wasm-util@0.10.3': + resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} + + '@types/react-dom@19.2.3': + resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} + peerDependencies: + '@types/react': ^19.2.0 + + '@types/react@19.2.17': + resolution: {integrity: sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==} + + '@typescript/typescript-aix-ppc64@7.0.2': + resolution: {integrity: sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [aix] + + '@typescript/typescript-darwin-arm64@7.0.2': + resolution: {integrity: sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [darwin] + + '@typescript/typescript-darwin-x64@7.0.2': + resolution: {integrity: sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [darwin] + + '@typescript/typescript-freebsd-arm64@7.0.2': + resolution: {integrity: sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [freebsd] + + '@typescript/typescript-freebsd-x64@7.0.2': + resolution: {integrity: sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [freebsd] + + '@typescript/typescript-linux-arm64@7.0.2': + resolution: {integrity: sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [linux] + + '@typescript/typescript-linux-arm@7.0.2': + resolution: {integrity: sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==} + engines: {node: '>=16.20.0'} + cpu: [arm] + os: [linux] + + '@typescript/typescript-linux-loong64@7.0.2': + resolution: {integrity: sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==} + engines: {node: '>=16.20.0'} + cpu: [loong64] + os: [linux] + + '@typescript/typescript-linux-mips64el@7.0.2': + resolution: {integrity: sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==} + engines: {node: '>=16.20.0'} + cpu: [mips64el] + os: [linux] + + '@typescript/typescript-linux-ppc64@7.0.2': + resolution: {integrity: sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [linux] + + '@typescript/typescript-linux-riscv64@7.0.2': + resolution: {integrity: sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==} + engines: {node: '>=16.20.0'} + cpu: [riscv64] + os: [linux] + + '@typescript/typescript-linux-s390x@7.0.2': + resolution: {integrity: sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==} + engines: {node: '>=16.20.0'} + cpu: [s390x] + os: [linux] + + '@typescript/typescript-linux-x64@7.0.2': + resolution: {integrity: sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [linux] + + '@typescript/typescript-netbsd-arm64@7.0.2': + resolution: {integrity: sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [netbsd] + + '@typescript/typescript-netbsd-x64@7.0.2': + resolution: {integrity: sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [netbsd] + + '@typescript/typescript-openbsd-arm64@7.0.2': + resolution: {integrity: sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [openbsd] + + '@typescript/typescript-openbsd-x64@7.0.2': + resolution: {integrity: sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [openbsd] + + '@typescript/typescript-sunos-x64@7.0.2': + resolution: {integrity: sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [sunos] + + '@typescript/typescript-win32-arm64@7.0.2': + resolution: {integrity: sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [win32] + + '@typescript/typescript-win32-x64@7.0.2': + resolution: {integrity: sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [win32] + + '@use-gesture/core@10.3.1': + resolution: {integrity: sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw==} + + '@use-gesture/react@10.3.1': + resolution: {integrity: sha512-Yy19y6O2GJq8f7CHf7L0nxL8bf4PZCPaVOCgJrusOeFHY1LvHgYXnmnXg6N5iwAnbgbZCDjo60SiM6IPJi9C5g==} + peerDependencies: + react: '>= 16.8.0' + + '@vitejs/plugin-react@6.0.3': + resolution: {integrity: sha512-vmFvco5/QuC2f9Oj+wTk0+9XeDFkHxSamwZKYc7MxYwKICfvUvlMhqKI0VuICPltGqh1neqBKDvO4kes1ya8vg==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + '@rolldown/plugin-babel': ^0.1.7 || ^0.2.0 + babel-plugin-react-compiler: ^1.0.0 + vite: ^8.0.0 + peerDependenciesMeta: + '@rolldown/plugin-babel': + optional: true + babel-plugin-react-compiler: + optional: true + + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} + engines: {node: '>=10'} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + framer-motion@12.42.2: + resolution: {integrity: sha512-5XY9luDiu0oHfHBjpDthFMh0ES+122w6p/papSJBweMkO8Sn+PW2QaEgRblQBpWFnuvZS5qvarpt/hO2pjGmnw==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + + lightningcss-android-arm64@1.33.0: + resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.33.0: + resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.33.0: + resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.33.0: + resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.33.0: + resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.33.0: + resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.33.0: + resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.33.0: + resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.33.0: + resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.33.0: + resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.33.0: + resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.33.0: + resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==} + engines: {node: '>= 12.0.0'} + + motion-dom@12.42.2: + resolution: {integrity: sha512-5gIMWLp/PycBtJRJWRgjxke5n8dlvkSn2DrYW+tr3XcqAZY1xZh6BJyooJXCM8wdfM7wfMjkBJNLge1CKPUIRA==} + + motion-utils@12.39.0: + resolution: {integrity: sha512-8nadJAJjTtqRkmRF36FoJTrywK9nnFmnPwnSMyxaOCU7GDjN9RTMJIxx9De8ErM+vpPhMccr/6fo5WciyQLnMQ==} + + motion@12.42.2: + resolution: {integrity: sha512-Atvv11yUKIid41cVrRBDVX5m8tF8kNpExRSlbpt6APClhDjtwQssgFHhQzejxw7/7YYbjHSPKBVbHo05BuJT5Q==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + + nanoid@3.3.16: + resolution: {integrity: sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.5: + resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} + engines: {node: '>=12'} + + playwright-core@1.61.1: + resolution: {integrity: sha512-h7Qlt6m4REp25qvIdvbDtVmD4LqVXfpRxhORv9L0jzETM05p4fuPJ3dKyuSXQxDSbXnmS79HAgi9589lGSpLkg==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.61.1: + resolution: {integrity: sha512-DWnY5o3YbLWK4GovuAVwpqL+1VwGNdUGrRr++8j8PtQQzvAVZUIMjKQ90fY689sEJZJBbZVw1rXaOKSTitkzPQ==} + engines: {node: '>=18'} + hasBin: true + + postcss@8.5.21: + resolution: {integrity: sha512-v4sDNP3fdNiWMfabO7OwOQdOX8TiQSztKyT1Wj0w+j7LDallJThJRBBBmzVGyYj0crMh7jlV4zepPkiNu9UwDQ==} + engines: {node: ^10 || ^12 || >=14} + + react-dom@19.2.7: + resolution: {integrity: sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==} + peerDependencies: + react: ^19.2.7 + + react-remove-scroll-bar@2.3.8: + resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.7.2: + resolution: {integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react-style-singleton@2.2.3: + resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react@19.2.7: + resolution: {integrity: sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==} + engines: {node: '>=0.10.0'} + + rolldown@1.1.5: + resolution: {integrity: sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + typescript@7.0.2: + resolution: {integrity: sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==} + engines: {node: '>=16.20.0'} + hasBin: true + + use-callback-ref@1.3.3: + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + use-sidecar@1.1.3: + resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + vite@8.1.3: + resolution: {integrity: sha512-Ds+gBRbj0lwRO2Y5hwnUBdxSwlAve9LeRyU4sNnAr0ewW0gWF0n5bgXgUzbgZ49MV9BVUAQUFYVcDUcilUExMA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.3.0 + esbuild: ^0.27.0 || ^0.28.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + +snapshots: + + '@emnapi/core@1.11.1': + dependencies: + '@emnapi/wasi-threads': 1.2.2 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.11.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.2': + dependencies: + tslib: 2.8.1 + optional: true + + '@floating-ui/core@1.8.0': + dependencies: + '@floating-ui/utils': 0.2.12 + + '@floating-ui/dom@1.8.0': + dependencies: + '@floating-ui/core': 1.8.0 + '@floating-ui/utils': 0.2.12 + + '@floating-ui/react-dom@2.1.9(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + dependencies: + '@floating-ui/dom': 1.8.0 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + '@floating-ui/utils@0.2.12': {} + + '@fontsource/roboto@5.2.10': {} + + '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': + dependencies: + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@tybys/wasm-util': 0.10.3 + optional: true + + '@oxc-project/types@0.139.0': {} + + '@phosphor-icons/react@2.1.10(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + dependencies: + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + '@playwright/test@1.61.1': + dependencies: + playwright: 1.61.1 + + '@radix-ui/primitive@1.1.5': {} + + '@radix-ui/react-arrow@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + dependencies: + '@radix-ui/react-primitive': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + optionalDependencies: + '@types/react': 19.2.17 + '@types/react-dom': 19.2.3(@types/react@19.2.17) + + '@radix-ui/react-collection@1.1.12(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-context': 1.2.0(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-primitive': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-slot': 1.3.0(@types/react@19.2.17)(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + optionalDependencies: + '@types/react': 19.2.17 + '@types/react-dom': 19.2.3(@types/react@19.2.17) + + '@radix-ui/react-compose-refs@1.1.3(@types/react@19.2.17)(react@19.2.7)': + dependencies: + react: 19.2.7 + optionalDependencies: + '@types/react': 19.2.17 + + '@radix-ui/react-context@1.2.0(@types/react@19.2.17)(react@19.2.7)': + dependencies: + react: 19.2.7 + optionalDependencies: + '@types/react': 19.2.17 + + '@radix-ui/react-dialog@1.1.19(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + dependencies: + '@radix-ui/primitive': 1.1.5 + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-context': 1.2.0(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-dismissable-layer': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-focus-guards': 1.1.4(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-focus-scope': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-id': 1.1.2(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-portal': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-presence': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-primitive': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-slot': 1.3.0(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.17)(react@19.2.7) + aria-hidden: 1.2.6 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + react-remove-scroll: 2.7.2(@types/react@19.2.17)(react@19.2.7) + optionalDependencies: + '@types/react': 19.2.17 + '@types/react-dom': 19.2.3(@types/react@19.2.17) + + '@radix-ui/react-direction@1.1.2(@types/react@19.2.17)(react@19.2.7)': + dependencies: + react: 19.2.7 + optionalDependencies: + '@types/react': 19.2.17 + + '@radix-ui/react-dismissable-layer@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + dependencies: + '@radix-ui/primitive': 1.1.5 + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-primitive': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-use-effect-event': 0.0.3(@types/react@19.2.17)(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + optionalDependencies: + '@types/react': 19.2.17 + '@types/react-dom': 19.2.3(@types/react@19.2.17) + + '@radix-ui/react-dropdown-menu@2.1.20(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + dependencies: + '@radix-ui/primitive': 1.1.5 + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-context': 1.2.0(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-id': 1.1.2(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-menu': 2.1.20(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-primitive': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.17)(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + optionalDependencies: + '@types/react': 19.2.17 + '@types/react-dom': 19.2.3(@types/react@19.2.17) + + '@radix-ui/react-focus-guards@1.1.4(@types/react@19.2.17)(react@19.2.7)': + dependencies: + react: 19.2.7 + optionalDependencies: + '@types/react': 19.2.17 + + '@radix-ui/react-focus-scope@1.1.12(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-primitive': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.17)(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + optionalDependencies: + '@types/react': 19.2.17 + '@types/react-dom': 19.2.3(@types/react@19.2.17) + + '@radix-ui/react-icons@1.3.2(react@19.2.7)': + dependencies: + react: 19.2.7 + + '@radix-ui/react-id@1.1.2(@types/react@19.2.17)(react@19.2.7)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.17)(react@19.2.7) + react: 19.2.7 + optionalDependencies: + '@types/react': 19.2.17 + + '@radix-ui/react-menu@2.1.20(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + dependencies: + '@radix-ui/primitive': 1.1.5 + '@radix-ui/react-collection': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-context': 1.2.0(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-direction': 1.1.2(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-dismissable-layer': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-focus-guards': 1.1.4(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-focus-scope': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-id': 1.1.2(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-popper': 1.3.3(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-portal': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-presence': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-primitive': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-roving-focus': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-slot': 1.3.0(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.17)(react@19.2.7) + aria-hidden: 1.2.6 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + react-remove-scroll: 2.7.2(@types/react@19.2.17)(react@19.2.7) + optionalDependencies: + '@types/react': 19.2.17 + '@types/react-dom': 19.2.3(@types/react@19.2.17) + + '@radix-ui/react-popper@1.3.3(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + dependencies: + '@floating-ui/react-dom': 2.1.9(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-arrow': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-context': 1.2.0(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-primitive': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-use-rect': 1.1.2(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-use-size': 1.1.2(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/rect': 1.1.2 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + optionalDependencies: + '@types/react': 19.2.17 + '@types/react-dom': 19.2.3(@types/react@19.2.17) + + '@radix-ui/react-portal@1.1.13(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + dependencies: + '@radix-ui/react-primitive': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.17)(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + optionalDependencies: + '@types/react': 19.2.17 + '@types/react-dom': 19.2.3(@types/react@19.2.17) + + '@radix-ui/react-presence@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.17)(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + optionalDependencies: + '@types/react': 19.2.17 + '@types/react-dom': 19.2.3(@types/react@19.2.17) + + '@radix-ui/react-primitive@2.1.7(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + dependencies: + '@radix-ui/react-slot': 1.3.0(@types/react@19.2.17)(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + optionalDependencies: + '@types/react': 19.2.17 + '@types/react-dom': 19.2.3(@types/react@19.2.17) + + '@radix-ui/react-roving-focus@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + dependencies: + '@radix-ui/primitive': 1.1.5 + '@radix-ui/react-collection': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-context': 1.2.0(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-direction': 1.1.2(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-id': 1.1.2(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-primitive': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-use-callback-ref': 1.1.2(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-use-is-hydrated': 0.1.1(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.17)(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + optionalDependencies: + '@types/react': 19.2.17 + '@types/react-dom': 19.2.3(@types/react@19.2.17) + + '@radix-ui/react-slot@1.3.0(@types/react@19.2.17)(react@19.2.7)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.17)(react@19.2.7) + react: 19.2.7 + optionalDependencies: + '@types/react': 19.2.17 + + '@radix-ui/react-use-callback-ref@1.1.2(@types/react@19.2.17)(react@19.2.7)': + dependencies: + react: 19.2.7 + optionalDependencies: + '@types/react': 19.2.17 + + '@radix-ui/react-use-controllable-state@1.2.3(@types/react@19.2.17)(react@19.2.7)': + dependencies: + '@radix-ui/react-use-effect-event': 0.0.3(@types/react@19.2.17)(react@19.2.7) + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.17)(react@19.2.7) + react: 19.2.7 + optionalDependencies: + '@types/react': 19.2.17 + + '@radix-ui/react-use-effect-event@0.0.3(@types/react@19.2.17)(react@19.2.7)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.17)(react@19.2.7) + react: 19.2.7 + optionalDependencies: + '@types/react': 19.2.17 + + '@radix-ui/react-use-is-hydrated@0.1.1(@types/react@19.2.17)(react@19.2.7)': + dependencies: + react: 19.2.7 + optionalDependencies: + '@types/react': 19.2.17 + + '@radix-ui/react-use-layout-effect@1.1.2(@types/react@19.2.17)(react@19.2.7)': + dependencies: + react: 19.2.7 + optionalDependencies: + '@types/react': 19.2.17 + + '@radix-ui/react-use-rect@1.1.2(@types/react@19.2.17)(react@19.2.7)': + dependencies: + '@radix-ui/rect': 1.1.2 + react: 19.2.7 + optionalDependencies: + '@types/react': 19.2.17 + + '@radix-ui/react-use-size@1.1.2(@types/react@19.2.17)(react@19.2.7)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.2(@types/react@19.2.17)(react@19.2.7) + react: 19.2.7 + optionalDependencies: + '@types/react': 19.2.17 + + '@radix-ui/rect@1.1.2': {} + + '@rolldown/binding-android-arm64@1.1.5': + optional: true + + '@rolldown/binding-darwin-arm64@1.1.5': + optional: true + + '@rolldown/binding-darwin-x64@1.1.5': + optional: true + + '@rolldown/binding-freebsd-x64@1.1.5': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.1.5': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.1.5': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.1.5': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.1.5': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.1.5': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.1.5': + optional: true + + '@rolldown/binding-linux-x64-musl@1.1.5': + optional: true + + '@rolldown/binding-openharmony-arm64@1.1.5': + optional: true + + '@rolldown/binding-wasm32-wasi@1.1.5': + dependencies: + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.1.5': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.1.5': + optional: true + + '@rolldown/pluginutils@1.0.1': {} + + '@tybys/wasm-util@0.10.3': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/react-dom@19.2.3(@types/react@19.2.17)': + dependencies: + '@types/react': 19.2.17 + + '@types/react@19.2.17': + dependencies: + csstype: 3.2.3 + + '@typescript/typescript-aix-ppc64@7.0.2': + optional: true + + '@typescript/typescript-darwin-arm64@7.0.2': + optional: true + + '@typescript/typescript-darwin-x64@7.0.2': + optional: true + + '@typescript/typescript-freebsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-freebsd-x64@7.0.2': + optional: true + + '@typescript/typescript-linux-arm64@7.0.2': + optional: true + + '@typescript/typescript-linux-arm@7.0.2': + optional: true + + '@typescript/typescript-linux-loong64@7.0.2': + optional: true + + '@typescript/typescript-linux-mips64el@7.0.2': + optional: true + + '@typescript/typescript-linux-ppc64@7.0.2': + optional: true + + '@typescript/typescript-linux-riscv64@7.0.2': + optional: true + + '@typescript/typescript-linux-s390x@7.0.2': + optional: true + + '@typescript/typescript-linux-x64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-sunos-x64@7.0.2': + optional: true + + '@typescript/typescript-win32-arm64@7.0.2': + optional: true + + '@typescript/typescript-win32-x64@7.0.2': + optional: true + + '@use-gesture/core@10.3.1': {} + + '@use-gesture/react@10.3.1(react@19.2.7)': + dependencies: + '@use-gesture/core': 10.3.1 + react: 19.2.7 + + '@vitejs/plugin-react@6.0.3(vite@8.1.3)': + dependencies: + '@rolldown/pluginutils': 1.0.1 + vite: 8.1.3 + + aria-hidden@1.2.6: + dependencies: + tslib: 2.8.1 + + csstype@3.2.3: {} + + detect-libc@2.1.2: {} + + detect-node-es@1.1.0: {} + + fdir@6.5.0(picomatch@4.0.5): + optionalDependencies: + picomatch: 4.0.5 + + framer-motion@12.42.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + motion-dom: 12.42.2 + motion-utils: 12.39.0 + tslib: 2.8.1 + optionalDependencies: + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + fsevents@2.3.2: + optional: true + + fsevents@2.3.3: + optional: true + + get-nonce@1.0.1: {} + + lightningcss-android-arm64@1.33.0: + optional: true + + lightningcss-darwin-arm64@1.33.0: + optional: true + + lightningcss-darwin-x64@1.33.0: + optional: true + + lightningcss-freebsd-x64@1.33.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.33.0: + optional: true + + lightningcss-linux-arm64-gnu@1.33.0: + optional: true + + lightningcss-linux-arm64-musl@1.33.0: + optional: true + + lightningcss-linux-x64-gnu@1.33.0: + optional: true + + lightningcss-linux-x64-musl@1.33.0: + optional: true + + lightningcss-win32-arm64-msvc@1.33.0: + optional: true + + lightningcss-win32-x64-msvc@1.33.0: + optional: true + + lightningcss@1.33.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.33.0 + lightningcss-darwin-arm64: 1.33.0 + lightningcss-darwin-x64: 1.33.0 + lightningcss-freebsd-x64: 1.33.0 + lightningcss-linux-arm-gnueabihf: 1.33.0 + lightningcss-linux-arm64-gnu: 1.33.0 + lightningcss-linux-arm64-musl: 1.33.0 + lightningcss-linux-x64-gnu: 1.33.0 + lightningcss-linux-x64-musl: 1.33.0 + lightningcss-win32-arm64-msvc: 1.33.0 + lightningcss-win32-x64-msvc: 1.33.0 + + motion-dom@12.42.2: + dependencies: + motion-utils: 12.39.0 + + motion-utils@12.39.0: {} + + motion@12.42.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + framer-motion: 12.42.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + tslib: 2.8.1 + optionalDependencies: + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + + nanoid@3.3.16: {} + + picocolors@1.1.1: {} + + picomatch@4.0.5: {} + + playwright-core@1.61.1: {} + + playwright@1.61.1: + dependencies: + playwright-core: 1.61.1 + optionalDependencies: + fsevents: 2.3.2 + + postcss@8.5.21: + dependencies: + nanoid: 3.3.16 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + react-dom@19.2.7(react@19.2.7): + dependencies: + react: 19.2.7 + scheduler: 0.27.0 + + react-remove-scroll-bar@2.3.8(@types/react@19.2.17)(react@19.2.7): + dependencies: + react: 19.2.7 + react-style-singleton: 2.2.3(@types/react@19.2.17)(react@19.2.7) + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.17 + + react-remove-scroll@2.7.2(@types/react@19.2.17)(react@19.2.7): + dependencies: + react: 19.2.7 + react-remove-scroll-bar: 2.3.8(@types/react@19.2.17)(react@19.2.7) + react-style-singleton: 2.2.3(@types/react@19.2.17)(react@19.2.7) + tslib: 2.8.1 + use-callback-ref: 1.3.3(@types/react@19.2.17)(react@19.2.7) + use-sidecar: 1.1.3(@types/react@19.2.17)(react@19.2.7) + optionalDependencies: + '@types/react': 19.2.17 + + react-style-singleton@2.2.3(@types/react@19.2.17)(react@19.2.7): + dependencies: + get-nonce: 1.0.1 + react: 19.2.7 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.17 + + react@19.2.7: {} + + rolldown@1.1.5: + dependencies: + '@oxc-project/types': 0.139.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.1.5 + '@rolldown/binding-darwin-arm64': 1.1.5 + '@rolldown/binding-darwin-x64': 1.1.5 + '@rolldown/binding-freebsd-x64': 1.1.5 + '@rolldown/binding-linux-arm-gnueabihf': 1.1.5 + '@rolldown/binding-linux-arm64-gnu': 1.1.5 + '@rolldown/binding-linux-arm64-musl': 1.1.5 + '@rolldown/binding-linux-ppc64-gnu': 1.1.5 + '@rolldown/binding-linux-s390x-gnu': 1.1.5 + '@rolldown/binding-linux-x64-gnu': 1.1.5 + '@rolldown/binding-linux-x64-musl': 1.1.5 + '@rolldown/binding-openharmony-arm64': 1.1.5 + '@rolldown/binding-wasm32-wasi': 1.1.5 + '@rolldown/binding-win32-arm64-msvc': 1.1.5 + '@rolldown/binding-win32-x64-msvc': 1.1.5 + + scheduler@0.27.0: {} + + source-map-js@1.2.1: {} + + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.5) + picomatch: 4.0.5 + + tslib@2.8.1: {} + + typescript@7.0.2: + optionalDependencies: + '@typescript/typescript-aix-ppc64': 7.0.2 + '@typescript/typescript-darwin-arm64': 7.0.2 + '@typescript/typescript-darwin-x64': 7.0.2 + '@typescript/typescript-freebsd-arm64': 7.0.2 + '@typescript/typescript-freebsd-x64': 7.0.2 + '@typescript/typescript-linux-arm': 7.0.2 + '@typescript/typescript-linux-arm64': 7.0.2 + '@typescript/typescript-linux-loong64': 7.0.2 + '@typescript/typescript-linux-mips64el': 7.0.2 + '@typescript/typescript-linux-ppc64': 7.0.2 + '@typescript/typescript-linux-riscv64': 7.0.2 + '@typescript/typescript-linux-s390x': 7.0.2 + '@typescript/typescript-linux-x64': 7.0.2 + '@typescript/typescript-netbsd-arm64': 7.0.2 + '@typescript/typescript-netbsd-x64': 7.0.2 + '@typescript/typescript-openbsd-arm64': 7.0.2 + '@typescript/typescript-openbsd-x64': 7.0.2 + '@typescript/typescript-sunos-x64': 7.0.2 + '@typescript/typescript-win32-arm64': 7.0.2 + '@typescript/typescript-win32-x64': 7.0.2 + + use-callback-ref@1.3.3(@types/react@19.2.17)(react@19.2.7): + dependencies: + react: 19.2.7 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.17 + + use-sidecar@1.1.3(@types/react@19.2.17)(react@19.2.7): + dependencies: + detect-node-es: 1.1.0 + react: 19.2.7 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.17 + + vite@8.1.3: + dependencies: + lightningcss: 1.33.0 + picomatch: 4.0.5 + postcss: 8.5.21 + rolldown: 1.1.5 + tinyglobby: 0.2.17 + optionalDependencies: + fsevents: 2.3.3 diff --git a/brain-h5/public/assets/android/Keyboard.png b/brain-h5/public/assets/android/Keyboard.png new file mode 100644 index 0000000..bf959fa Binary files /dev/null and b/brain-h5/public/assets/android/Keyboard.png differ diff --git a/brain-h5/public/assets/android/Pixel10.png b/brain-h5/public/assets/android/Pixel10.png new file mode 100644 index 0000000..2ba4a10 Binary files /dev/null and b/brain-h5/public/assets/android/Pixel10.png differ diff --git a/brain-h5/public/assets/android/navigation-bar.svg b/brain-h5/public/assets/android/navigation-bar.svg new file mode 100644 index 0000000..9e79543 --- /dev/null +++ b/brain-h5/public/assets/android/navigation-bar.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/brain-h5/public/assets/brain/airplane-source.png b/brain-h5/public/assets/brain/airplane-source.png new file mode 100644 index 0000000..35728f8 Binary files /dev/null and b/brain-h5/public/assets/brain/airplane-source.png differ diff --git a/brain-h5/public/assets/brain/airplane.png b/brain-h5/public/assets/brain/airplane.png new file mode 100644 index 0000000..87f3d22 Binary files /dev/null and b/brain-h5/public/assets/brain/airplane.png differ diff --git a/brain-h5/public/assets/brain/design-reference.png b/brain-h5/public/assets/brain/design-reference.png new file mode 100644 index 0000000..644ffc2 Binary files /dev/null and b/brain-h5/public/assets/brain/design-reference.png differ diff --git a/brain-h5/public/assets/brain/direction-object.png b/brain-h5/public/assets/brain/direction-object.png new file mode 100644 index 0000000..c6d95a9 Binary files /dev/null and b/brain-h5/public/assets/brain/direction-object.png differ diff --git a/brain-h5/public/assets/brain/direction-source.png b/brain-h5/public/assets/brain/direction-source.png new file mode 100644 index 0000000..a73fc16 Binary files /dev/null and b/brain-h5/public/assets/brain/direction-source.png differ diff --git a/brain-h5/public/assets/brain/memory/bread.png b/brain-h5/public/assets/brain/memory/bread.png new file mode 100644 index 0000000..3c2469b Binary files /dev/null and b/brain-h5/public/assets/brain/memory/bread.png differ diff --git a/brain-h5/public/assets/brain/memory/carrot.png b/brain-h5/public/assets/brain/memory/carrot.png new file mode 100644 index 0000000..71b4f8b Binary files /dev/null and b/brain-h5/public/assets/brain/memory/carrot.png differ diff --git a/brain-h5/public/assets/brain/memory/cheese.png b/brain-h5/public/assets/brain/memory/cheese.png new file mode 100644 index 0000000..65ed926 Binary files /dev/null and b/brain-h5/public/assets/brain/memory/cheese.png differ diff --git a/brain-h5/public/assets/brain/memory/coffee.png b/brain-h5/public/assets/brain/memory/coffee.png new file mode 100644 index 0000000..bbacaec Binary files /dev/null and b/brain-h5/public/assets/brain/memory/coffee.png differ diff --git a/brain-h5/public/assets/brain/memory/cookie.png b/brain-h5/public/assets/brain/memory/cookie.png new file mode 100644 index 0000000..b3f8b4a Binary files /dev/null and b/brain-h5/public/assets/brain/memory/cookie.png differ diff --git a/brain-h5/public/assets/brain/memory/egg.png b/brain-h5/public/assets/brain/memory/egg.png new file mode 100644 index 0000000..6068e68 Binary files /dev/null and b/brain-h5/public/assets/brain/memory/egg.png differ diff --git a/brain-h5/public/assets/brain/memory/fish.png b/brain-h5/public/assets/brain/memory/fish.png new file mode 100644 index 0000000..3242c63 Binary files /dev/null and b/brain-h5/public/assets/brain/memory/fish.png differ diff --git a/brain-h5/public/assets/brain/memory/orange.png b/brain-h5/public/assets/brain/memory/orange.png new file mode 100644 index 0000000..142c786 Binary files /dev/null and b/brain-h5/public/assets/brain/memory/orange.png differ diff --git a/brain-h5/public/assets/brain/planes/coral.png b/brain-h5/public/assets/brain/planes/coral.png new file mode 100644 index 0000000..490f12e Binary files /dev/null and b/brain-h5/public/assets/brain/planes/coral.png differ diff --git a/brain-h5/public/assets/brain/planes/teal.png b/brain-h5/public/assets/brain/planes/teal.png new file mode 100644 index 0000000..5f937d8 Binary files /dev/null and b/brain-h5/public/assets/brain/planes/teal.png differ diff --git a/brain-h5/public/assets/brain/symbols/camera.png b/brain-h5/public/assets/brain/symbols/camera.png new file mode 100644 index 0000000..fade936 Binary files /dev/null and b/brain-h5/public/assets/brain/symbols/camera.png differ diff --git a/brain-h5/public/assets/brain/symbols/coffee.png b/brain-h5/public/assets/brain/symbols/coffee.png new file mode 100644 index 0000000..1436ca0 Binary files /dev/null and b/brain-h5/public/assets/brain/symbols/coffee.png differ diff --git a/brain-h5/public/assets/brain/symbols/gear.png b/brain-h5/public/assets/brain/symbols/gear.png new file mode 100644 index 0000000..8404654 Binary files /dev/null and b/brain-h5/public/assets/brain/symbols/gear.png differ diff --git a/brain-h5/public/assets/brain/symbols/lightning.png b/brain-h5/public/assets/brain/symbols/lightning.png new file mode 100644 index 0000000..364e3ec Binary files /dev/null and b/brain-h5/public/assets/brain/symbols/lightning.png differ diff --git a/brain-h5/public/assets/brain/symbols/lock.png b/brain-h5/public/assets/brain/symbols/lock.png new file mode 100644 index 0000000..e818a36 Binary files /dev/null and b/brain-h5/public/assets/brain/symbols/lock.png differ diff --git a/brain-h5/public/assets/brain/symbols/moon.png b/brain-h5/public/assets/brain/symbols/moon.png new file mode 100644 index 0000000..7d5635e Binary files /dev/null and b/brain-h5/public/assets/brain/symbols/moon.png differ diff --git a/brain-h5/public/assets/brain/symbols/puzzle.png b/brain-h5/public/assets/brain/symbols/puzzle.png new file mode 100644 index 0000000..55c3bf0 Binary files /dev/null and b/brain-h5/public/assets/brain/symbols/puzzle.png differ diff --git a/brain-h5/public/assets/brain/symbols/squares.png b/brain-h5/public/assets/brain/symbols/squares.png new file mode 100644 index 0000000..3aeaebb Binary files /dev/null and b/brain-h5/public/assets/brain/symbols/squares.png differ diff --git a/brain-h5/public/assets/brain/symbols/star.png b/brain-h5/public/assets/brain/symbols/star.png new file mode 100644 index 0000000..d406cb6 Binary files /dev/null and b/brain-h5/public/assets/brain/symbols/star.png differ diff --git a/brain-h5/public/assets/brain/symbols/sun.png b/brain-h5/public/assets/brain/symbols/sun.png new file mode 100644 index 0000000..1b2bca0 Binary files /dev/null and b/brain-h5/public/assets/brain/symbols/sun.png differ diff --git a/brain-h5/public/assets/iphone/Bezel.png b/brain-h5/public/assets/iphone/Bezel.png new file mode 100644 index 0000000..759e8aa Binary files /dev/null and b/brain-h5/public/assets/iphone/Bezel.png differ diff --git a/brain-h5/public/assets/iphone/Keyboard.png b/brain-h5/public/assets/iphone/Keyboard.png new file mode 100644 index 0000000..80207c3 Binary files /dev/null and b/brain-h5/public/assets/iphone/Keyboard.png differ diff --git a/brain-h5/public/assets/money/money-05.png b/brain-h5/public/assets/money/money-05.png new file mode 100644 index 0000000..ffcba5b Binary files /dev/null and b/brain-h5/public/assets/money/money-05.png differ diff --git a/brain-h5/public/assets/money/money-1.png b/brain-h5/public/assets/money/money-1.png new file mode 100644 index 0000000..a8c0775 Binary files /dev/null and b/brain-h5/public/assets/money/money-1.png differ diff --git a/brain-h5/public/assets/money/money-10.png b/brain-h5/public/assets/money/money-10.png new file mode 100644 index 0000000..d82177e Binary files /dev/null and b/brain-h5/public/assets/money/money-10.png differ diff --git a/brain-h5/public/assets/money/money-2.png b/brain-h5/public/assets/money/money-2.png new file mode 100644 index 0000000..b40e75a Binary files /dev/null and b/brain-h5/public/assets/money/money-2.png differ diff --git a/brain-h5/public/assets/money/money-20.png b/brain-h5/public/assets/money/money-20.png new file mode 100644 index 0000000..0c214d8 Binary files /dev/null and b/brain-h5/public/assets/money/money-20.png differ diff --git a/brain-h5/public/assets/money/money-5.png b/brain-h5/public/assets/money/money-5.png new file mode 100644 index 0000000..00acf0d Binary files /dev/null and b/brain-h5/public/assets/money/money-5.png differ diff --git a/brain-h5/public/assets/status/ios-status-icons.svg b/brain-h5/public/assets/status/ios-status-icons.svg new file mode 100644 index 0000000..b75235a --- /dev/null +++ b/brain-h5/public/assets/status/ios-status-icons.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/brain-h5/public/assets/status/status-icons.svg b/brain-h5/public/assets/status/status-icons.svg new file mode 100644 index 0000000..8a97e81 --- /dev/null +++ b/brain-h5/public/assets/status/status-icons.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/brain-h5/public/assets/ui/finish-all.png b/brain-h5/public/assets/ui/finish-all.png new file mode 100644 index 0000000..03e0c12 Binary files /dev/null and b/brain-h5/public/assets/ui/finish-all.png differ diff --git a/brain-h5/public/assets/ui/finish-attention.png b/brain-h5/public/assets/ui/finish-attention.png new file mode 100644 index 0000000..7b3e9df Binary files /dev/null and b/brain-h5/public/assets/ui/finish-attention.png differ diff --git a/brain-h5/public/assets/ui/finish-memory.png b/brain-h5/public/assets/ui/finish-memory.png new file mode 100644 index 0000000..f9f5833 Binary files /dev/null and b/brain-h5/public/assets/ui/finish-memory.png differ diff --git a/brain-h5/public/assets/ui/finish-symbol.png b/brain-h5/public/assets/ui/finish-symbol.png new file mode 100644 index 0000000..0596675 Binary files /dev/null and b/brain-h5/public/assets/ui/finish-symbol.png differ diff --git a/brain-h5/public/assets/ui/finish-trail.png b/brain-h5/public/assets/ui/finish-trail.png new file mode 100644 index 0000000..0b5dff8 Binary files /dev/null and b/brain-h5/public/assets/ui/finish-trail.png differ diff --git a/brain-h5/public/assets/ui/home-compass.png b/brain-h5/public/assets/ui/home-compass.png new file mode 100644 index 0000000..8918734 Binary files /dev/null and b/brain-h5/public/assets/ui/home-compass.png differ diff --git a/brain-h5/public/assets/ui/report-insight.png b/brain-h5/public/assets/ui/report-insight.png new file mode 100644 index 0000000..7367b3b Binary files /dev/null and b/brain-h5/public/assets/ui/report-insight.png differ diff --git a/brain-h5/scripts/check-mobile-runtime.mjs b/brain-h5/scripts/check-mobile-runtime.mjs new file mode 100644 index 0000000..72bf53d --- /dev/null +++ b/brain-h5/scripts/check-mobile-runtime.mjs @@ -0,0 +1,33 @@ +#!/usr/bin/env node +import { createHash } from "node:crypto"; +import { existsSync, readFileSync } from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); +const lockPath = path.join(root, "mobile-runtime.lock.json"); +const lockedFiles = JSON.parse(readFileSync(lockPath, "utf8")); +const failures = []; + +for (const [relativePath, expectedHash] of Object.entries(lockedFiles)) { + const filePath = path.join(root, relativePath); + + if (!existsSync(filePath)) { + failures.push(`${relativePath} is missing`); + continue; + } + + const actualHash = createHash("sha256").update(readFileSync(filePath)).digest("hex"); + if (actualHash !== expectedHash) { + failures.push(`${relativePath} was modified`); + } +} + +if (failures.length > 0) { + console.error("Mobile runtime integrity check failed:\n"); + for (const failure of failures) console.error(`- ${failure}`); + console.error("\nRestore the protected runtime. Put app UI in src/Prototype.tsx and src/prototype.css."); + process.exit(1); +} + +console.log(`Mobile runtime integrity check passed (${Object.keys(lockedFiles).length} protected files).`); diff --git a/brain-h5/scripts/extract-video-frames.ps1 b/brain-h5/scripts/extract-video-frames.ps1 new file mode 100644 index 0000000..863f0b2 --- /dev/null +++ b/brain-h5/scripts/extract-video-frames.ps1 @@ -0,0 +1,122 @@ +param( + [Parameter(Mandatory = $true)] + [string]$VideoPath, + + [Parameter(Mandatory = $true)] + [string]$OutputDirectory, + + [int]$FrameCount = 12, + + [double]$StartSeconds = 0, + + [double]$EndSeconds = -1 +) + +$ErrorActionPreference = "Stop" +Add-Type -AssemblyName PresentationCore +Add-Type -AssemblyName WindowsBase + +function Invoke-DispatcherWait { + param([int]$Milliseconds) + + $frame = [System.Windows.Threading.DispatcherFrame]::new() + $timer = [System.Windows.Threading.DispatcherTimer]::new( + [System.Windows.Threading.DispatcherPriority]::Background + ) + $timer.Interval = [TimeSpan]::FromMilliseconds($Milliseconds) + $timer.Add_Tick({ + $timer.Stop() + $frame.Continue = $false + }) + $timer.Start() + [System.Windows.Threading.Dispatcher]::PushFrame($frame) +} + +$resolvedVideo = (Resolve-Path -LiteralPath $VideoPath).Path +$resolvedOutput = [System.IO.Path]::GetFullPath($OutputDirectory) +[System.IO.Directory]::CreateDirectory($resolvedOutput) | Out-Null + +$player = [System.Windows.Media.MediaPlayer]::new() +$player.ScrubbingEnabled = $true +$player.Open([Uri]::new($resolvedVideo)) +$player.Play() + +for ($attempt = 0; $attempt -lt 100 -and $player.NaturalVideoWidth -eq 0; $attempt++) { + Invoke-DispatcherWait -Milliseconds 100 +} + +if ($player.NaturalVideoWidth -eq 0 -or -not $player.NaturalDuration.HasTimeSpan) { + $player.Close() + throw "Unable to decode video: $resolvedVideo" +} + +$width = $player.NaturalVideoWidth +$height = $player.NaturalVideoHeight +$duration = $player.NaturalDuration.TimeSpan.TotalSeconds +$rangeStart = [Math]::Min([Math]::Max($StartSeconds, 0), $duration) +$rangeEnd = if ($EndSeconds -lt 0) { + $duration +} else { + [Math]::Min([Math]::Max($EndSeconds, $rangeStart), $duration) +} +$metadata = [ordered]@{ + path = $resolvedVideo + width = $width + height = $height + durationSeconds = [Math]::Round($duration, 3) + frames = @() +} + +$player.Stop() +$player.Position = [TimeSpan]::Zero +$player.SpeedRatio = 16 +$player.Play() + +for ($index = 0; $index -lt $FrameCount; $index++) { + $ratio = if ($FrameCount -eq 1) { 0.5 } else { $index / ($FrameCount - 1) } + $seconds = $rangeStart + (($rangeEnd - $rangeStart) * $ratio) + $seconds = [Math]::Min([Math]::Max($seconds, 0), [Math]::Max($duration - 0.08, 0)) + $deadline = [DateTime]::UtcNow.AddSeconds(45) + while ($player.Position.TotalSeconds -lt $seconds -and [DateTime]::UtcNow -lt $deadline) { + Invoke-DispatcherWait -Milliseconds 40 + } + Invoke-DispatcherWait -Milliseconds 80 + + $visual = [System.Windows.Media.DrawingVisual]::new() + $context = $visual.RenderOpen() + $context.DrawVideo( + $player, + [Windows.Rect]::new(0, 0, $width, $height) + ) + $context.Close() + + $bitmap = [System.Windows.Media.Imaging.RenderTargetBitmap]::new( + $width, + $height, + 96, + 96, + [System.Windows.Media.PixelFormats]::Pbgra32 + ) + $bitmap.Render($visual) + + $milliseconds = [long][Math]::Round($seconds * 1000) + $fileName = "frame-{0:D2}-{1:D6}ms.png" -f ([int]($index + 1)), $milliseconds + $filePath = Join-Path $resolvedOutput $fileName + $encoder = [System.Windows.Media.Imaging.PngBitmapEncoder]::new() + $encoder.Frames.Add([System.Windows.Media.Imaging.BitmapFrame]::Create($bitmap)) + $stream = [System.IO.File]::Open($filePath, [System.IO.FileMode]::Create) + try { + $encoder.Save($stream) + } finally { + $stream.Dispose() + } + + $metadata.frames += [ordered]@{ + file = $fileName + seconds = [Math]::Round($seconds, 3) + actualSeconds = [Math]::Round($player.Position.TotalSeconds, 3) + } +} + +$player.Close() +$metadata | ConvertTo-Json -Depth 4 diff --git a/brain-h5/scripts/prepare-brain-assets.py b/brain-h5/scripts/prepare-brain-assets.py new file mode 100644 index 0000000..3409b4f --- /dev/null +++ b/brain-h5/scripts/prepare-brain-assets.py @@ -0,0 +1,125 @@ +from __future__ import annotations + +from collections import deque +from pathlib import Path + +from PIL import Image + + +ROOT = Path(__file__).resolve().parents[1] +SOURCE_ROOT = Path("D:/") +OUT_ROOT = ROOT / "public" / "assets" / "brain" +LANCZOS = getattr(getattr(Image, "Resampling", Image), "LANCZOS") + + +ASSETS = { + "memory/bread.png": "ChatGPT Image 2026年7月23日 21_31_30 (1).png", + "memory/carrot.png": "ChatGPT Image 2026年7月23日 21_31_32 (2).png", + "memory/coffee.png": "ChatGPT Image 2026年7月23日 21_31_34 (4).png", + "memory/cookie.png": "ChatGPT Image 2026年7月23日 21_31_35 (5).png", + "memory/egg.png": "ChatGPT Image 2026年7月23日 21_31_36 (6).png", + "memory/fish.png": "ChatGPT Image 2026年7月23日 21_31_38 (7).png", + "memory/orange.png": "ChatGPT Image 2026年7月23日 21_31_39 (8).png", + "memory/cheese.png": "ChatGPT Image 2026年7月23日 21_31_40.png", + "planes/teal.png": "ChatGPT Image 2026年7月23日 21_31_44 (9).png", + "planes/coral.png": "ChatGPT Image 2026年7月23日 21_31_45 (10).png", + "symbols/camera.png": "ChatGPT Image 2026年7月23日 21_40_52 (1).png", + "symbols/sun.png": "ChatGPT Image 2026年7月23日 21_40_52 (2).png", + "symbols/squares.png": "ChatGPT Image 2026年7月23日 21_40_53 (3).png", + "symbols/lock.png": "ChatGPT Image 2026年7月23日 21_40_53 (4).png", + "symbols/lightning.png": "ChatGPT Image 2026年7月23日 21_40_53 (5).png", + "symbols/moon.png": "ChatGPT Image 2026年7月23日 21_40_53 (6).png", + "symbols/gear.png": "ChatGPT Image 2026年7月23日 21_40_53 (7).png", + "symbols/star.png": "ChatGPT Image 2026年7月23日 21_40_53 (8).png", + "symbols/puzzle.png": "ChatGPT Image 2026年7月23日 21_40_53 (9).png", + "symbols/coffee.png": "ChatGPT Image 2026年7月23日 21_40_53 (10).png", +} + + +def has_real_alpha(image: Image.Image) -> bool: + if "A" not in image.getbands(): + return False + alpha = image.getchannel("A") + lo, hi = alpha.getextrema() + return lo < 255 and hi == 255 + + +def remove_generated_checkerboard(image: Image.Image) -> Image.Image: + rgba = image.convert("RGBA") + rgba.thumbnail((720, 720), LANCZOS) + pixels = rgba.load() + width, height = rgba.size + + def is_background(x: int, y: int) -> bool: + red, green, blue, _ = pixels[x, y] + high = max(red, green, blue) + low = min(red, green, blue) + return low >= 218 and high - low <= 18 + + # Flood only from the canvas edge. This removes the connected checkerboard + # without punching holes into pale objects such as the teal plane or egg. + queue: deque[tuple[int, int]] = deque() + visited = bytearray(width * height) + for x in range(width): + queue.append((x, 0)) + queue.append((x, height - 1)) + for y in range(height): + queue.append((0, y)) + queue.append((width - 1, y)) + + while queue: + x, y = queue.popleft() + offset = y * width + x + if visited[offset] or not is_background(x, y): + continue + visited[offset] = 1 + if x: + queue.append((x - 1, y)) + if x + 1 < width: + queue.append((x + 1, y)) + if y: + queue.append((x, y - 1)) + if y + 1 < height: + queue.append((x, y + 1)) + + for y in range(height): + for x in range(width): + red, green, blue, _ = pixels[x, y] + alpha = 0 if visited[y * width + x] else 255 + pixels[x, y] = (red, green, blue, alpha) + + bounds = rgba.getbbox() + if bounds: + rgba = rgba.crop(bounds) + return rgba + + +def copy_or_convert(source: Path, destination: Path) -> None: + destination.parent.mkdir(parents=True, exist_ok=True) + with Image.open(source) as image: + if has_real_alpha(image): + prepared = image.convert("RGBA") + bounds = prepared.getbbox() + if bounds: + prepared = prepared.crop(bounds) + prepared.thumbnail((720, 720), LANCZOS) + else: + prepared = remove_generated_checkerboard(image) + prepared.save(destination, optimize=True) + + +def main() -> None: + missing: list[str] = [] + for output, source_name in ASSETS.items(): + source = SOURCE_ROOT / source_name + destination = OUT_ROOT / output + if not source.exists(): + missing.append(source_name) + continue + copy_or_convert(source, destination) + if missing: + raise SystemExit("Missing assets:\n" + "\n".join(missing)) + + +if __name__ == "__main__": + main() diff --git a/brain-h5/scripts/prepare-sites-build.mjs b/brain-h5/scripts/prepare-sites-build.mjs new file mode 100644 index 0000000..86a9e8c --- /dev/null +++ b/brain-h5/scripts/prepare-sites-build.mjs @@ -0,0 +1,21 @@ +#!/usr/bin/env node +import { copyFileSync, existsSync, mkdirSync } from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); +const dist = path.join(root, "dist"); +const index = path.join(dist, "client", "index.html"); +const worker = path.join(root, "worker", "index.js"); +const hosting = path.join(root, ".openai", "hosting.json"); + +for (const file of [index, worker, hosting]) { + if (!existsSync(file)) throw new Error("Missing Sites build input: " + file); +} + +mkdirSync(path.join(dist, "server"), { recursive: true }); +mkdirSync(path.join(dist, ".openai"), { recursive: true }); +copyFileSync(worker, path.join(dist, "server", "index.js")); +copyFileSync(hosting, path.join(dist, ".openai", "hosting.json")); + +console.log("Prepared Sites build: dist/server/index.js and dist/.openai/hosting.json"); diff --git a/brain-h5/scripts/start-local.cmd b/brain-h5/scripts/start-local.cmd new file mode 100644 index 0000000..a908437 --- /dev/null +++ b/brain-h5/scripts/start-local.cmd @@ -0,0 +1,58 @@ +@echo off +setlocal +cd /d "%~dp0.." + +set "BUNDLED_NODE=%USERPROFILE%\.cache\codex-runtimes\codex-primary-runtime\dependencies\node\bin" +set "BUNDLED_PNPM=%USERPROFILE%\.cache\codex-runtimes\codex-primary-runtime\dependencies\bin\fallback\pnpm.cmd" + +if exist "%BUNDLED_PNPM%" goto bundled_check +where npm.cmd >nul 2>nul +if errorlevel 1 goto missing + +if not exist "node_modules" goto npm_install +node -e "import('vite')" >nul 2>nul +if errorlevel 1 goto npm_repair +goto npm_run + +:npm_repair +echo Existing dependencies are damaged. Reinstalling... +rmdir /s /q "%CD%\node_modules" + +:npm_install +call npm.cmd install +if errorlevel 1 goto install_failed + +:npm_run +call npm.cmd run dev -- --host 0.0.0.0 --port 4173 +exit /b %errorlevel% + +:bundled_check +set "PATH=%BUNDLED_NODE%;%PATH%" +if not exist "node_modules" goto bundled_install +"%BUNDLED_NODE%\node.exe" -e "import('vite')" >nul 2>nul +if errorlevel 1 goto bundled_repair +goto bundled_run + +:bundled_repair +echo Existing dependencies are damaged. Reinstalling... +rmdir /s /q "%CD%\node_modules" + +:bundled_install +call "%BUNDLED_PNPM%" install --frozen-lockfile +if errorlevel 1 goto install_failed + +:bundled_run +call "%BUNDLED_PNPM%" dev --host 0.0.0.0 --port 4173 +exit /b %errorlevel% + +:install_failed +echo. +echo Dependency installation failed. Check the network, then run this launcher again. +pause +exit /b 1 + +:missing +echo No local web runtime was found. +echo Install Node.js or reopen this project in Codex, then retry. +pause +exit /b 1 diff --git a/brain-h5/scripts/update-mobile-runtime-lock.mjs b/brain-h5/scripts/update-mobile-runtime-lock.mjs new file mode 100644 index 0000000..7d91275 --- /dev/null +++ b/brain-h5/scripts/update-mobile-runtime-lock.mjs @@ -0,0 +1,48 @@ +#!/usr/bin/env node +import { createHash } from "node:crypto"; +import { existsSync, readFileSync, writeFileSync } from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); +const lockPath = path.join(root, "mobile-runtime.lock.json"); +const protectedFiles = [ + "scripts/check-mobile-runtime.mjs", + "scripts/prepare-sites-build.mjs", + "scripts/update-mobile-runtime-lock.mjs", + "vite.config.ts", + "src/App.tsx", + "src/main.tsx", + "src/styles.css", + "src/mobile/BottomSheet.tsx", + "src/mobile/Carousel.tsx", + "src/mobile/Device.tsx", + "src/mobile/FlowStack.tsx", + "src/mobile/Keyboard.tsx", + "src/mobile/MobileCursor.tsx", + "src/mobile/MobileRuntime.tsx", + "src/mobile/MobileScroll.tsx", + "src/mobile/PhoneFrame.tsx", + "src/mobile/assets.ts", + "src/mobile/components.tsx", + "src/mobile/geometry.ts", + "src/mobile/index.ts", + "public/assets/iphone/Bezel.png", + "public/assets/iphone/Keyboard.png", + "public/assets/android/Pixel10.png", + "public/assets/android/Keyboard.png", + "public/assets/android/navigation-bar.svg", + "public/assets/status/status-icons.svg", + "public/assets/status/ios-status-icons.svg", + "worker/index.js", +]; + +const hashes = {}; +for (const relativePath of protectedFiles) { + const filePath = path.join(root, relativePath); + if (!existsSync(filePath)) throw new Error(`Protected runtime file is missing: ${relativePath}`); + hashes[relativePath] = createHash("sha256").update(readFileSync(filePath)).digest("hex"); +} + +writeFileSync(lockPath, `${JSON.stringify(hashes, null, 2)}\n`); +console.log(`Updated mobile-runtime.lock.json (${protectedFiles.length} protected files).`); diff --git a/brain-h5/server.mjs b/brain-h5/server.mjs new file mode 100644 index 0000000..295fee5 --- /dev/null +++ b/brain-h5/server.mjs @@ -0,0 +1,148 @@ +import { createServer } from "node:http"; +import { readFile, stat } from "node:fs/promises"; +import { extname, join, normalize } from "node:path"; +import { fileURLToPath } from "node:url"; +import { dirname } from "node:path"; + +const PORT = Number(process.env.PORT) || 4173; +const HOST = process.env.HOST || "0.0.0.0"; +const DEEPSEEK_API_KEY = process.env.DEEPSEEK_API_KEY || ""; +const CLIENT_DIR = join(dirname(fileURLToPath(import.meta.url)), "dist", "client"); + +const SYSTEM_PROMPT = `你是一名数字脑健康表现报告助手。根据用户完成游戏时产生的结构化数据,生成通俗、克制、非医疗化的中文报告。不得诊断疾病,不得推荐药物或医疗处置,不得使用"异常、受损、提示存在问题或挑战"等暗示医学结论的说法。只描述本次表现,优先使用"反应相对偏慢、注意表现有波动、容易遗漏、仍有提升空间"。只输出合法 JSON:{"summary":"80字内总结","strength":"60字内相对优势","opportunity":"60字内提升空间","recommendations":["建议1","建议2","建议3"]}`; + +const MIME = { + ".html": "text/html; charset=utf-8", + ".js": "application/javascript; charset=utf-8", + ".css": "text/css; charset=utf-8", + ".json": "application/json; charset=utf-8", + ".svg": "image/svg+xml", + ".png": "image/png", + ".jpg": "image/jpeg", + ".jpeg": "image/jpeg", + ".gif": "image/gif", + ".webp": "image/webp", + ".ico": "image/x-icon", + ".woff": "font/woff", + ".woff2": "font/woff2", + ".ttf": "font/ttf", + ".otf": "font/otf", + ".eot": "application/vnd.ms-fontobject", + ".map": "application/json; charset=utf-8", +}; + +function send(response, status, body, headers = {}) { + response.writeHead(status, headers); + response.end(body); +} + +function sendJson(response, status, payload) { + send(response, status, JSON.stringify(payload), { + "content-type": "application/json; charset=utf-8", + "cache-control": "no-store", + }); +} + +async function serveStatic(request, response, pathname) { + const safe = normalize(pathname).replace(/^(\.\.[/\\])+/, ""); + let filePath = join(CLIENT_DIR, safe); + let info; + try { + info = await stat(filePath); + } catch { + if (request.headers.get?.("accept")?.includes("text/html") || (request.headers.accept || "").includes("text/html")) { + try { + const index = await readFile(join(CLIENT_DIR, "index.html")); + send(response, 200, index, { "content-type": "text/html; charset=utf-8" }); + return; + } catch { + send(response, 404, "Not Found", { "content-type": "text/plain; charset=utf-8" }); + return; + } + } + send(response, 404, "Not Found", { "content-type": "text/plain; charset=utf-8" }); + return; + } + if (info.isDirectory()) { + filePath = join(filePath, "index.html"); + try { info = await stat(filePath); } catch { send(response, 404, "Not Found"); return; } + } + const data = await readFile(filePath); + const mime = MIME[extname(filePath).toLowerCase()] || "application/octet-stream"; + const headers = { "content-type": mime }; + if (extname(filePath).match(/\.(js|css|woff|woff2|png|jpg|jpeg|gif|webp|svg|ico)$/)) { + headers["cache-control"] = "public, max-age=31536000, immutable"; + } + send(response, 200, data, headers); +} + +async function readBody(request) { + const chunks = []; + for await (const chunk of request) chunks.push(chunk); + return Buffer.concat(chunks).toString("utf-8"); +} + +async function analyze(request, response) { + if (!DEEPSEEK_API_KEY) { + sendJson(response, 503, { error: "AI service is not configured. Set DEEPSEEK_API_KEY env var." }); + return; + } + try { + const raw = await readBody(request); + const assessment = JSON.parse(raw || "{}"); + const upstream = await fetch("https://api.deepseek.com/chat/completions", { + method: "POST", + headers: { "content-type": "application/json", authorization: `Bearer ${DEEPSEEK_API_KEY}` }, + body: JSON.stringify({ + model: "deepseek-chat", + temperature: 0.35, + response_format: { type: "json_object" }, + messages: [ + { role: "system", content: SYSTEM_PROMPT }, + { role: "user", content: JSON.stringify({ profile: assessment.profile, metrics: assessment.metrics, eventCount: assessment.events?.length ?? 0 }) }, + ], + }), + signal: AbortSignal.timeout(15000), + }); + if (!upstream.ok) { + sendJson(response, 502, { error: "AI service request failed" }); + return; + } + const payload = await upstream.json(); + const content = payload?.choices?.[0]?.message?.content; + const rawReport = JSON.parse(String(content || "{}").replace(/^```json\s*|\s*```$/g, "")); + const parsed = { + summary: String(rawReport.summary || "本次四项任务已经完成。"), + strength: String(rawReport.strength || "部分任务表现相对稳定。"), + opportunity: String(rawReport.opportunity || "仍有可以通过规律练习提升的空间。"), + recommendations: Array.isArray(rawReport.recommendations) ? rawReport.recommendations.slice(0, 3).map(String) : [], + }; + sendJson(response, 200, parsed); + } catch (error) { + sendJson(response, 502, { error: error?.message || "AI report could not be generated" }); + } +} + +const server = createServer(async (request, response) => { + const url = new URL(request.url, `http://${request.headers.host || "localhost"}`); + try { + if (url.pathname === "/api/analyze") { + if (request.method !== "POST") { send(response, 405, "Method not allowed"); return; } + await analyze(request, response); + return; + } + if (!["GET", "HEAD"].includes(request.method)) { + send(response, 405, "Method not allowed"); + return; + } + await serveStatic(request, response, url.pathname); + } catch (error) { + if (!response.headersSent) sendJson(response, 500, { error: error?.message || "Internal error" }); + } +}); + +server.listen(PORT, HOST, () => { + console.log(`brain-h5 server listening on http://${HOST}:${PORT}`); + console.log(`static dir: ${CLIENT_DIR}`); + console.log(`DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY ? "configured" : "MISSING (set DEEPSEEK_API_KEY env var)"}`); +}); diff --git a/brain-h5/src/App.tsx b/brain-h5/src/App.tsx new file mode 100644 index 0000000..bd7f114 --- /dev/null +++ b/brain-h5/src/App.tsx @@ -0,0 +1,5 @@ +import Prototype from "./Prototype"; + +export default function App() { + return ; +} diff --git a/brain-h5/src/Prototype.tsx b/brain-h5/src/Prototype.tsx new file mode 100644 index 0000000..4fa8f70 --- /dev/null +++ b/brain-h5/src/Prototype.tsx @@ -0,0 +1,988 @@ +import { useEffect, useLayoutEffect, useRef, useState } from "react"; +import { LayoutGroup, motion } from "motion/react"; +import { + ArrowDown, + ArrowLeft, + ArrowRight, + ArrowUp, + ChartLineUp, + Check, + CheckCircle, + ClockCountdown, + Heart, + LockKey, + Minus, + Path, + Sparkle, + Speedometer, + SquaresFour, + Star, + Target, + Timer, + X, +} from "@phosphor-icons/react"; + +type Screen = "home" | "profile" | "overview" | "symbol" | "trail" | "attention" | "memory" | "money" | "complete" | "report"; +type Game = "symbol" | "trail" | "attention" | "memory" | "money"; +type Direction = "up" | "right" | "down" | "left"; +type MetricKey = "speed" | "executive" | "attention" | "memory" | "calculation"; +type Metric = { score: number; correct: number; total: number; errors: number; completion: number }; +type Plane = { id: number; color: "blue" | "orange"; direction: Direction; lane: number; duration: number; delay: number; target: boolean }; + +const SYMBOL_IMAGES = [ + "/assets/brain/symbols/camera.png", + "/assets/brain/symbols/sun.png", + "/assets/brain/symbols/squares.png", + "/assets/brain/symbols/lock.png", + "/assets/brain/symbols/lightning.png", + "/assets/brain/symbols/moon.png", + "/assets/brain/symbols/gear.png", + "/assets/brain/symbols/star.png", + "/assets/brain/symbols/puzzle.png", + "/assets/brain/symbols/coffee.png", +] as const; + +const FOODS = [ + { name: "全麦面包", image: "/assets/brain/memory/bread.png", tone: "amber" }, + { name: "胡萝卜", image: "/assets/brain/memory/carrot.png", tone: "coral" }, + { name: "奶酪", image: "/assets/brain/memory/cheese.png", tone: "yellow" }, + { name: "咖啡", image: "/assets/brain/memory/coffee.png", tone: "violet" }, + { name: "曲奇", image: "/assets/brain/memory/cookie.png", tone: "pink" }, + { name: "鸡蛋", image: "/assets/brain/memory/egg.png", tone: "blue" }, + { name: "鲜鱼", image: "/assets/brain/memory/fish.png", tone: "cyan" }, + { name: "橙子", image: "/assets/brain/memory/orange.png", tone: "orange" }, +] as const; + +const PLANE_IMAGE = { + blue: "/assets/brain/planes/teal.png", + orange: "/assets/brain/planes/coral.png", +} as const; + +const COMPLETION_IMAGES: Record = { + symbol: "/assets/ui/finish-symbol.png", + trail: "/assets/ui/finish-trail.png", + attention: "/assets/ui/finish-attention.png", + memory: "/assets/ui/finish-memory.png", + money: "/assets/ui/finish-all.png", +}; + +const DIRECTIONS: Direction[] = ["up", "right", "down", "left"]; +const DIRECTION_ICONS = { up: ArrowUp, right: ArrowRight, down: ArrowDown, left: ArrowLeft }; +const DIRECTION_LABELS = { up: "向上", right: "向右", down: "向下", left: "向左" }; +const DIRECTION_ANGLE = { up: -90, right: 0, down: 90, left: 180 }; +const EMPTY_METRIC: Metric = { score: 0, correct: 0, total: 0, errors: 0, completion: 0 }; +const MONEY_OPTIONS = [ + { value: 0.5, image: "/assets/money/money-05.png" }, + { value: 1, image: "/assets/money/money-1.png" }, + { value: 2, image: "/assets/money/money-2.png" }, + { value: 5, image: "/assets/money/money-5.png" }, + { value: 10, image: "/assets/money/money-10.png" }, + { value: 20, image: "/assets/money/money-20.png" }, +] as const; +const MEMORY_ROUND_SECONDS = [0, 35, 40, 45]; +const MONEY_ROUNDS = [ + { price: 13, payment: 20, target: 7, seconds: 40 }, + { price: 26.5, payment: 40, target: 13.5, seconds: 45 }, + { price: 41.5, payment: 60, target: 18.5, seconds: 50 }, +] as const; + +function moneyImage(value: number) { + return MONEY_OPTIONS.find((option) => option.value === value)?.image ?? MONEY_OPTIONS[0].image; +} + +const TRAIL_NODES = Array.from({ length: 20 }, (_, index) => ({ + kind: index % 2 === 0 ? ("number" as const) : ("shape" as const), + rank: Math.floor(index / 2) + 1, +})); + +const TRAIL_PATH = [ + { x: 42, y: 58 }, { x: 57, y: 43 }, { x: 74, y: 54 }, { x: 66, y: 69 }, + { x: 50, y: 75 }, { x: 34, y: 65 }, { x: 18, y: 78 }, { x: 11, y: 58 }, + { x: 24, y: 43 }, { x: 14, y: 25 }, { x: 31, y: 16 }, { x: 45, y: 29 }, + { x: 57, y: 15 }, { x: 69, y: 31 }, { x: 80, y: 17 }, { x: 91, y: 31 }, + { x: 84, y: 48 }, { x: 92, y: 68 }, { x: 78, y: 82 }, { x: 58, y: 85 }, +]; + +function shuffle(items: readonly T[]) { + const copy = [...items]; + for (let i = copy.length - 1; i > 0; i -= 1) { + const j = Math.floor(Math.random() * (i + 1)); + [copy[i], copy[j]] = [copy[j], copy[i]]; + } + return copy; +} + +function randomDirection(): Direction { + return DIRECTIONS[Math.floor(Math.random() * DIRECTIONS.length)]; +} + +function scoreMetric(correct: number, total: number, errors: number, expected: number): Metric { + const completion = Math.min(1, total / expected); + const attempts = Math.max(total, correct + errors); + const accuracy = attempts ? correct / attempts : 0; + const score = Math.max(20, Math.min(98, Math.round(accuracy * 72 + completion * 28))); + return { score, correct, total, errors, completion: Math.round(completion * 100) }; +} + +function createTrailLayout() { + const flipX = Math.random() > 0.5; + const flipY = Math.random() > 0.5; + return TRAIL_PATH.map((point, index) => ({ + x: (flipX ? 100 - point.x : point.x) + (index % 3 - 1) * 0.7, + y: (flipY ? 100 - point.y : point.y) + ((index + 1) % 3 - 1) * 0.6, + })); +} + +function createPlanes(trial: number, targetColor: "blue" | "orange", targetDirection: Direction): Plane[] { + const count = trial < 3 ? 1 : trial < 10 ? 3 : trial < 20 ? 5 : 7; + const targetIndex = Math.floor(Math.random() * count); + return Array.from({ length: count }, (_, index) => { + const target = index === targetIndex; + // Keep the requested color unique. Distractors are always the opposite color. + const color = target ? targetColor : targetColor === "blue" ? "orange" : "blue"; + return { + id: Date.now() + index, + target, + direction: target ? targetDirection : randomDirection(), + color, + lane: 12 + ((index * 17 + Math.floor(Math.random() * 10)) % 72), + duration: 6.7 + Math.random() * 1.5, + delay: index * 0.38, + }; + }); +} + +function Brand() { + return ( +
+ + 脑晴测 + COGNITIVE STUDIO +
+ ); +} + +function PrimaryButton({ children, onClick, disabled, secondary = false }: { + children: React.ReactNode; + onClick: () => void; + disabled?: boolean; + secondary?: boolean; +}) { + return ; +} + +function GameHeader({ seconds, onBack }: { seconds: number; onBack: () => void }) { + return ( +
+ +
{String(Math.floor(seconds / 60)).padStart(2, "0")}:{String(seconds % 60).padStart(2, "0")}
+
+ ); +} + +function GameIntro({ game, onStart }: { game: Game; onStart: () => void }) { + const info = { + symbol: { no: "01", title: "符号速配", text: "记住固定符号表,看到目标后选择对应数字。", rules: ["映射表全程固定", "准确优先,再提高速度", "完成练习后开始"] }, + trail: { no: "02", title: "交替连线", text: "按照数字与绿色扇区交替、从小到大的顺序连接。", rules: ["1 到最小扇区再到 2", "扇区面积逐级增加", "错误不会推进进度"] }, + attention: { no: "03", title: "动态方向追踪", text: "根据顶部目标颜色,在飞行中的机群里判断目标飞机头朝向。", rules: ["飞机持续移动", "目标颜色每题变化", "三次错误后结束"] }, + memory: { no: "04", title: "购物记忆", text: "先记住清单,再从移动的传送带上选中对应商品。", rules: ["商品依次移动出现", "每轮难度逐渐增加", "中途回看会影响评分"] }, + money: { no: "05", title: "零钱计算", text: "根据应找金额,组合出完全一致的钱币数值。", rules: ["直接点击钱币", "点击已选钱币可撤回", "完成两轮精确找零"] }, + }[game]; + const [practised, setPractised] = useState(false); + const [practiceStep, setPracticeStep] = useState(0); + const [practicePick, setPracticePick] = useState(null); + + const finishPractice = () => { + setPractised(true); + }; + + const practiceContent = { + symbol: ( +
+
先看这里 找到图标对应的数字
+ +
{[1, 2, 3].map((number) => )}
+
+ ), + trail: ( +
+
按箭头顺序 先点 1,再点最小扇区,最后点 2
+ {[0, 1, 2].map((index) => )} +
+ ), + attention: ( +
+
观察机头 这架飞机朝右,点击右方向键
+ +
{DIRECTIONS.map((direction) => { const Icon = DIRECTION_ICONS[direction]; return ; })}
+
+ ), + memory: ( +
+
{practiceStep === 0 ? "先记住清单" : "现在动手选择"} {practiceStep === 0 ? "点击任意商品进入选择练习" : "点击清单里的曲奇"}
+
{[1, 4, 7].map((index) => )}
+
+ ), + money: ( +
+
组合 7 元 依次点击 5 元和 2 元
+
{MONEY_OPTIONS.filter((option) => option.value === 5 || option.value === 2).map((option) => )}
+
+ ), + }[game]; + + return ( +
+
+
练习 {info.no}

{info.title}

{info.text}

+ {practiceContent} +
+ {practised ? <> 已掌握操作 : <> 按提示点击高亮位置} +
+ 开始正式测试 +
+
+ ); +} + +function CoachOverlay({ target, text, onTargetClick }: { target: string; text: string; onTargetClick: () => void }) { + const [rect, setRect] = useState<{ left: number; top: number; width: number; height: number } | null>(null); + + useLayoutEffect(() => { + const update = () => { + const element = document.querySelector(target); + if (!element) return; + const bounds = element.getBoundingClientRect(); + const padding = 9; + setRect({ + left: Math.max(4, bounds.left - padding), + top: Math.max(4, bounds.top - padding), + width: Math.min(window.innerWidth - 8, bounds.width + padding * 2), + height: Math.min(window.innerHeight - 8, bounds.height + padding * 2), + }); + }; + update(); + const observer = new ResizeObserver(update); + const element = document.querySelector(target); + if (element) observer.observe(element); + window.addEventListener("resize", update); + return () => { + observer.disconnect(); + window.removeEventListener("resize", update); + }; + }, [target]); + + if (!rect) return null; + const bubbleWidth = Math.min(292, window.innerWidth - 24); + const below = rect.top < window.innerHeight * 0.42; + const bubbleLeft = Math.max(12, Math.min(window.innerWidth - bubbleWidth - 12, rect.left + rect.width / 2 - bubbleWidth / 2)); + const bubbleTop = below ? Math.min(window.innerHeight - 132, rect.top + rect.height + 22) : Math.max(12, rect.top - 118); + + return ( +
+
+
+
+
+
+
+ ); +} + +function DemoReadyOverlay({ onStart }: { onStart: () => void }) { + return ( +
+ +

试玩完成

+

已经掌握操作

+ 开始正式游戏 +
+ ); +} + +export default function Prototype() { + const [screen, setScreen] = useState("home"); + const [intro, setIntro] = useState(null); + const [profile, setProfile] = useState({ age: "", gender: "", education: "" }); + const [seconds, setSeconds] = useState(60); + const [feedback, setFeedback] = useState<"correct" | "wrong" | null>(null); + const [exitConfirm, setExitConfirm] = useState(false); + const [coachStep, setCoachStep] = useState(0); + const [completedGame, setCompletedGame] = useState("symbol"); + const [completionNext, setCompletionNext] = useState("trail"); + const [metrics, setMetrics] = useState>({ + speed: EMPTY_METRIC, + executive: EMPTY_METRIC, + attention: EMPTY_METRIC, + memory: EMPTY_METRIC, + calculation: EMPTY_METRIC, + }); + + const [symbolTrial, setSymbolTrial] = useState(0); + const [symbolTarget, setSymbolTarget] = useState(0); + const [symbolMap, setSymbolMap] = useState(() => shuffle(Array.from({ length: 10 }, (_, index) => index))); + const symbolCorrect = useRef(0); + const symbolErrors = useRef(0); + + const [trailIndex, setTrailIndex] = useState(0); + const [trailPositions, setTrailPositions] = useState(createTrailLayout); + const trailErrors = useRef(0); + + const [attentionTrial, setAttentionTrial] = useState(0); + const [attentionDirection, setAttentionDirection] = useState("right"); + const [targetColor, setTargetColor] = useState<"blue" | "orange">("blue"); + const [attentionLives, setAttentionLives] = useState(3); + const [planes, setPlanes] = useState(() => createPlanes(0, "blue", "right")); + const attentionCorrect = useRef(0); + const attentionErrors = useRef(0); + + const [memoryRound, setMemoryRound] = useState(1); + const [memoryPhase, setMemoryPhase] = useState<"study" | "conveyor">("study"); + const [memoryTargets, setMemoryTargets] = useState(() => shuffle([0, 1, 2, 3, 4, 5, 6, 7]).slice(0, 2)); + const [memorySelected, setMemorySelected] = useState([]); + const [memoryRetired, setMemoryRetired] = useState([]); + const [beltOrder, setBeltOrder] = useState(() => shuffle([0, 1, 2, 3, 4, 5, 6, 7])); + const [listOpen, setListOpen] = useState(false); + const [moneyRound, setMoneyRound] = useState(1); + const [moneyAttempts, setMoneyAttempts] = useState(0); + const [cash, setCash] = useState([]); + const memoryCorrect = useRef(0); + const memoryTotal = useRef(0); + const memoryErrors = useRef(0); + const memoryListViews = useRef(0); + const memoryListViewMs = useRef(0); + const listOpenedAt = useRef(null); + const beltRetireTimers = useRef([]); + const calculationCorrect = useRef(0); + const calculationTotal = useRef(0); + const calculationErrors = useRef(0); + + const activeGame = ["symbol", "trail", "attention", "memory", "money"].includes(screen) && !intro && !exitConfirm; + const timerActive = activeGame && !(screen === "memory" && (memoryPhase === "study" || listOpen)); + + useEffect(() => { + if (!timerActive || seconds <= 0) return; + const timer = window.setInterval(() => setSeconds((value) => value - 1), 1000); + return () => window.clearInterval(timer); + }, [timerActive, seconds]); + + useEffect(() => { + window.scrollTo({ top: 0, behavior: "smooth" }); + }, [screen]); + + const flash = (value: "correct" | "wrong") => { + setFeedback(value); + window.setTimeout(() => setFeedback(null), 620); + }; + + const closeMemoryList = () => { + if (intro !== "memory" && listOpenedAt.current !== null) { + memoryListViewMs.current += Date.now() - listOpenedAt.current; + listOpenedAt.current = null; + } + setListOpen(false); + }; + + const toggleMemoryList = () => { + if (listOpen) { + closeMemoryList(); + return; + } + if (intro !== "memory") { + memoryListViews.current += 1; + listOpenedAt.current = Date.now(); + } + setListOpen(true); + }; + + const memoryMetric = () => { + const base = scoreMetric(memoryCorrect.current, memoryTotal.current, memoryErrors.current, 9); + const viewSeconds = Math.round(memoryListViewMs.current / 1000); + const reviewPenalty = Math.min(20, memoryListViews.current * 4 + Math.floor(viewSeconds / 5)); + return { ...base, score: Math.max(20, base.score - reviewPenalty) }; + }; + + const openGame = (game: Game) => { + setScreen(game); + setIntro(game); + setCoachStep(0); + setListOpen(false); + }; + + const clearBeltRetireTimers = () => { + beltRetireTimers.current.forEach((timer) => window.clearTimeout(timer)); + beltRetireTimers.current = []; + }; + + const startGame = (game: Game) => { + setIntro(null); + setSeconds(game === "trail" ? 90 : game === "memory" ? MEMORY_ROUND_SECONDS[1] : 60); + if (game === "symbol") { + let nextTarget = Math.floor(Math.random() * 10); + while (nextTarget === symbolTarget) nextTarget = Math.floor(Math.random() * 10); + setSymbolTrial(0); + setSymbolTarget(nextTarget); + setSymbolMap(shuffle(Array.from({ length: 10 }, (_, index) => index))); + symbolCorrect.current = 0; + symbolErrors.current = 0; + } + if (game === "trail") { + let nextLayout = createTrailLayout(); + let attempts = 0; + while (nextLayout.every((point, index) => point.x === trailPositions[index].x && point.y === trailPositions[index].y) && attempts < 6) { + nextLayout = createTrailLayout(); + attempts += 1; + } + setTrailIndex(0); + setTrailPositions(nextLayout); + trailErrors.current = 0; + } + if (game === "attention") { + const direction = DIRECTIONS[(DIRECTIONS.indexOf(attentionDirection) + 1 + Math.floor(Math.random() * 3)) % DIRECTIONS.length]; + const color = Math.random() > 0.5 ? "blue" : "orange"; + setAttentionTrial(0); + setAttentionLives(3); + setAttentionDirection(direction); + setTargetColor(color); + setPlanes(createPlanes(0, color, direction)); + attentionCorrect.current = 0; + attentionErrors.current = 0; + } + if (game === "memory") { + let nextTargets = shuffle([0, 1, 2, 3, 4, 5, 6, 7]).slice(0, 2); + const demoKey = [...memoryTargets.slice(0, 2)].sort().join("-"); + while ([...nextTargets].sort().join("-") === demoKey) { + nextTargets = shuffle([0, 1, 2, 3, 4, 5, 6, 7]).slice(0, 2); + } + setMemoryRound(1); + setMemoryPhase("study"); + setMemoryTargets(nextTargets); + setMemorySelected([]); + setMemoryRetired([]); + setBeltOrder(shuffle([0, 1, 2, 3, 4, 5, 6, 7])); + setListOpen(false); + setCash([]); + memoryCorrect.current = 0; + memoryTotal.current = 0; + memoryErrors.current = 0; + memoryListViews.current = 0; + memoryListViewMs.current = 0; + listOpenedAt.current = null; + } + if (game === "money") { + setMoneyRound(1); + setMoneyAttempts(0); + setCash([]); + setSeconds(MONEY_ROUNDS[0].seconds); + calculationCorrect.current = 0; + calculationTotal.current = 0; + calculationErrors.current = 0; + } + }; + + const finishGame = (key: MetricKey, metric: Metric, next: Screen) => { + setMetrics((current) => ({ ...current, [key]: metric })); + setCompletedGame(screen as Game); + setCompletionNext(next); + setScreen("complete"); + setIntro(null); + }; + + const finishMoneyRound = (correct: boolean) => { + calculationTotal.current += 1; + if (correct) calculationCorrect.current += 1; + setCash([]); + setMoneyAttempts(0); + if (moneyRound < MONEY_ROUNDS.length) { + const nextRound = moneyRound + 1; + setMoneyRound(nextRound); + setSeconds(MONEY_ROUNDS[nextRound - 1].seconds); + return; + } + finishGame("calculation", scoreMetric(calculationCorrect.current, calculationTotal.current, calculationErrors.current, MONEY_ROUNDS.length), "report"); + }; + + const continueAfterTime = () => { + if (screen === "symbol") finishGame("speed", scoreMetric(symbolCorrect.current, symbolTrial, symbolErrors.current, 30), "trail"); + if (screen === "trail") finishGame("executive", scoreMetric(trailIndex, trailIndex, trailErrors.current, 20), "attention"); + if (screen === "attention") finishGame("attention", scoreMetric(attentionCorrect.current, attentionTrial, attentionErrors.current, 20), "memory"); + if (screen === "memory" && memoryPhase === "conveyor") finishMemoryRound(memorySelected); + if (screen === "money") { + calculationErrors.current += 1; + finishMoneyRound(false); + } + }; + + useEffect(() => { + if (!timerActive || seconds !== 0) return; + continueAfterTime(); + }, [timerActive, seconds]); + + const resetAll = () => { + setMetrics({ speed: EMPTY_METRIC, executive: EMPTY_METRIC, attention: EMPTY_METRIC, memory: EMPTY_METRIC, calculation: EMPTY_METRIC }); + setSymbolTrial(0); + setSymbolMap(shuffle(Array.from({ length: 10 }, (_, index) => index))); + setSymbolTarget(Math.floor(Math.random() * 10)); + symbolCorrect.current = 0; + symbolErrors.current = 0; + setTrailIndex(0); + setTrailPositions(createTrailLayout()); + trailErrors.current = 0; + setAttentionTrial(0); + setAttentionLives(3); + setAttentionDirection("right"); + setTargetColor("blue"); + setPlanes(createPlanes(0, "blue", "right")); + attentionCorrect.current = 0; + attentionErrors.current = 0; + setMemoryRound(1); + setMemoryPhase("study"); + setMemoryTargets(shuffle([0, 1, 2, 3, 4, 5, 6, 7]).slice(0, 2)); + setMemorySelected([]); + setMemoryRetired([]); + setBeltOrder(shuffle([0, 1, 2, 3, 4, 5, 6, 7])); + setCash([]); + memoryCorrect.current = 0; + memoryTotal.current = 0; + memoryErrors.current = 0; + memoryListViews.current = 0; + memoryListViewMs.current = 0; + listOpenedAt.current = null; + setMoneyRound(1); + setMoneyAttempts(0); + setCash([]); + calculationCorrect.current = 0; + calculationTotal.current = 0; + calculationErrors.current = 0; + }; + + const answerSymbol = (answer: number) => { + if (intro === "symbol") { + if (answer !== symbolMap.indexOf(symbolTarget)) return; + flash("correct"); + if (coachStep >= 1) { + setCoachStep(2); + return; + } + let next = Math.floor(Math.random() * 10); + while (next === symbolTarget) next = Math.floor(Math.random() * 10); + setSymbolTarget(next); + setSymbolMap((current) => shuffle(current)); + setCoachStep(1); + return; + } + const correct = symbolMap.indexOf(symbolTarget) === answer; + if (correct) symbolCorrect.current += 1; + else symbolErrors.current += 1; + flash(correct ? "correct" : "wrong"); + if (symbolTrial >= 29) { + finishGame("speed", scoreMetric(symbolCorrect.current, 30, symbolErrors.current, 30), "trail"); + return; + } + let next = Math.floor(Math.random() * 10); + while (next === symbolTarget) next = Math.floor(Math.random() * 10); + setSymbolTarget(next); + setSymbolMap((current) => shuffle(current)); + setSymbolTrial((value) => value + 1); + }; + + const tapTrail = (index: number) => { + if (intro === "trail") { + if (index !== coachStep) return; + flash("correct"); + setCoachStep((value) => value >= 3 ? 4 : value + 1); + return; + } + if (index !== trailIndex) { + trailErrors.current += 1; + flash("wrong"); + return; + } + flash("correct"); + if (index === 19) { + finishGame("executive", scoreMetric(20, 20, trailErrors.current, 20), "attention"); + return; + } + setTrailIndex(index + 1); + }; + + const answerAttention = (direction: Direction) => { + if (intro === "attention") { + if (direction !== attentionDirection) return; + flash("correct"); + if (coachStep >= 1) { + setCoachStep(2); + return; + } + const nextDirection = DIRECTIONS[(DIRECTIONS.indexOf(attentionDirection) + 1 + Math.floor(Math.random() * 3)) % DIRECTIONS.length]; + setAttentionDirection(nextDirection); + setTargetColor((color) => color === "blue" ? "orange" : "blue"); + setCoachStep(1); + return; + } + const correct = direction === attentionDirection; + if (correct) attentionCorrect.current += 1; + else { + attentionErrors.current += 1; + setAttentionLives((value) => Math.max(0, value - 1)); + } + flash(correct ? "correct" : "wrong"); + const nextLives = correct ? attentionLives : attentionLives - 1; + if (attentionTrial >= 19 || nextLives <= 0) { + finishGame("attention", scoreMetric(attentionCorrect.current, attentionTrial + 1, attentionErrors.current, 20), "memory"); + return; + } + const nextTrial = attentionTrial + 1; + const nextDirection = randomDirection(); + const nextColor = Math.random() > 0.5 ? "blue" : "orange"; + setAttentionTrial(nextTrial); + setAttentionDirection(nextDirection); + setTargetColor(nextColor); + setPlanes(createPlanes(nextTrial, nextColor, nextDirection)); + }; + + const finishMemoryRound = (selected: number[]) => { + clearBeltRetireTimers(); + const hits = memoryTargets.filter((item) => selected.includes(item)).length; + const wrong = selected.filter((item) => !memoryTargets.includes(item)).length; + memoryCorrect.current += hits; + memoryTotal.current += memoryTargets.length; + memoryErrors.current += wrong + memoryTargets.length - hits; + flash(wrong === 0 && hits === memoryTargets.length ? "correct" : "wrong"); + if (memoryRound < 3) { + const nextRound = memoryRound + 1; + setMemoryRound(nextRound); + setMemoryTargets(shuffle([0, 1, 2, 3, 4, 5, 6, 7]).slice(0, nextRound + 1)); + setMemorySelected([]); + setMemoryRetired([]); + setBeltOrder(shuffle([0, 1, 2, 3, 4, 5, 6, 7])); + setMemoryPhase("study"); + setSeconds(MEMORY_ROUND_SECONDS[nextRound]); + } else { + closeMemoryList(); + finishGame("memory", memoryMetric(), "money"); + } + }; + + const selectMemoryItem = (index: number, element?: HTMLButtonElement) => { + if (memoryTargets.every((target) => memorySelected.includes(target))) return; + if (memorySelected.includes(index)) return; + if (!memoryTargets.includes(index)) { + memoryErrors.current += 1; + flash("wrong"); + return; + } + const next = [...memorySelected, index]; + setMemorySelected(next); + flash("correct"); + if (memoryTargets.every((target) => next.includes(target))) { + window.setTimeout(() => finishMemoryRound(next), 180); + return; + } + if (!element) return; + const timer = window.setInterval(() => { + if (!document.body.contains(element)) { + window.clearInterval(timer); + return; + } + if (element.getBoundingClientRect().left <= window.innerWidth) return; + window.clearInterval(timer); + setMemoryRetired((current) => current.includes(index) ? current : [...current, index]); + }, 120); + beltRetireTimers.current.push(timer); + }; + + const moneyQuestion = MONEY_ROUNDS[moneyRound - 1]; + const changeTarget = moneyQuestion.target; + const cashTotal = cash.reduce((sum, item) => sum + item, 0); + const submitChange = () => { + const correct = Math.abs(cashTotal - changeTarget) < 0.01; + flash(correct ? "correct" : "wrong"); + if (correct) { + finishMoneyRound(true); + return; + } + calculationErrors.current += 1; + if (moneyAttempts === 0) { + setMoneyAttempts(1); + setCash([]); + return; + } + finishMoneyRound(false); + }; + + const completeMemoryDemo = (index: number) => { + const demoTarget = memoryTargets[coachStep - 2]; + if (intro !== "memory" || coachStep < 2 || coachStep > 3 || index !== demoTarget) return; + flash("correct"); + setCoachStep((value) => value + 1); + }; + + const completeMoneyDemo = (value: number) => { + if (intro !== "money") return; + if (coachStep === 0 && value === 1) { + setCash([1]); + setCoachStep(1); + } else if (coachStep === 1 && value === 2) { + setCash([1, 2]); + setCoachStep(2); + } + }; + + const removeCash = (index: number) => { + setCash((items) => items.filter((_, itemIndex) => itemIndex !== index)); + }; + + const continueFromCompletion = () => { + if (completionNext === "report") { + setScreen("report"); + return; + } + openGame(completionNext as Game); + }; + + const overall = Math.round(Object.values(metrics).reduce((sum, metric) => sum + (metric.score || 70), 0) / 5); + const reportRows: Array<[MetricKey, string, typeof Speedometer]> = [ + ["speed", "处理速度", Speedometer], + ["executive", "执行功能", Path], + ["attention", "注意力", Target], + ["memory", "工作记忆", SquaresFour], + ["calculation", "计算能力", ChartLineUp], + ]; + const rankedMetrics = [...reportRows].sort((a, b) => metrics[b[0]].score - metrics[a[0]].score); + const strongestMetric = rankedMetrics[0][1]; + const improvementMetric = rankedMetrics[rankedMetrics.length - 1][1]; + const totalCorrect = Object.values(metrics).reduce((sum, metric) => sum + metric.correct, 0); + const totalErrors = Object.values(metrics).reduce((sum, metric) => sum + metric.errors, 0); + const averageCompletion = Math.round(Object.values(metrics).reduce((sum, metric) => sum + metric.completion, 0) / 5); + const memoryReviewSeconds = Math.round(memoryListViewMs.current / 1000); + const completedGameName = { + symbol: "符号速配", + trail: "交替连线", + attention: "方向追踪", + memory: "购物记忆", + money: "零钱计算", + }[completedGame]; + const demoReady = intro === "symbol" ? coachStep >= 2 + : intro === "trail" ? coachStep >= 4 + : intro === "attention" ? coachStep >= 2 + : intro === "memory" ? coachStep >= 4 + : intro === "money" ? coachStep >= 2 + : false; + const coach = !demoReady && intro === "symbol" + ? { + target: `.keypad button[data-number="${symbolMap.indexOf(symbolTarget)}"]`, + text: coachStep === 0 ? "完成第一次试玩:找到目标图标对应的数字并点击。" : "图标已经换位,再完成一次匹配。", + onTargetClick: () => answerSymbol(symbolMap.indexOf(symbolTarget)), + } + : !demoReady && intro === "trail" + ? { + target: `.trail-node[data-index="${coachStep}"]`, + text: coachStep === 0 ? "先点击数字 1。" : coachStep === 1 ? "接着点击最小的绿色扇区。" : coachStep === 2 ? "然后点击数字 2。" : "再点击第二小的绿色扇区,完成试玩。", + onTargetClick: () => tapTrail(coachStep), + } + : !demoReady && intro === "attention" + ? { + target: `.direction-console button[data-direction="${attentionDirection}"]`, + text: `${coachStep === 0 ? "第一次试玩" : "再试一次"}:目标是${targetColor === "blue" ? "青绿色" : "珊瑚色"}飞机,点击机头对应的方向键。`, + onTargetClick: () => answerAttention(attentionDirection), + } + : !demoReady && intro === "memory" + ? coachStep === 0 + ? { + target: ".memory-demo-stage .shopping-tab", + text: "先点击购物清单,把需要寻找的商品图片展开。", + onTargetClick: () => { + setListOpen(true); + setCoachStep(1); + }, + } + : coachStep === 1 + ? { + target: ".memory-demo-stage .shopping-tab", + text: "记住清单后先收起,传送带才会继续。", + onTargetClick: () => { + setListOpen(false); + setCoachStep(2); + }, + } + : coachStep < 4 + ? { + target: `.memory-demo-stage .demo-belt-item[data-index="${memoryTargets[coachStep - 2]}"]`, + text: coachStep === 2 ? "点击清单中的第一个商品。" : "再点击清单中的第二个商品。", + onTargetClick: () => completeMemoryDemo(memoryTargets[coachStep - 2]), + } + : null + : !demoReady && intro === "money" + ? { + target: `.demo-change-stage .money-pad button[data-value="${coachStep === 0 ? 1 : 2}"]`, + text: coachStep === 0 ? "试玩目标是 3 元,先选择 1 元。" : "再选择 2 元,组成 3 元,完成试玩。", + onTargetClick: () => completeMoneyDemo(coachStep === 0 ? 1 : 2), + } + : null; + + return ( +
+ {screen === "home" && ( +
+ +
+
+ +

DAILY CHECK-IN

+

开始今天的
状态评估

+

填写三项基础信息,然后直接进入第一个小游戏。

+
+
+ + + +
+
+ { resetAll(); openGame("symbol"); }}>开始评估 + 匿名完成,信息仅用于本次结果 +
+
+

结果仅供自我了解,不构成医疗诊断或治疗建议。

+
+ )} + + {screen === "complete" && ( +
+ +

{completedGameName}

+

本项游戏已结束

+ + {completionNext === "report" ? "查看结果" : "进入下一个游戏"} + +
+ )} + + {screen === "profile" && ( +
+
+ +
+

BEFORE WE START

让报告更贴近你

这些信息只用于解释本次表现,不需要姓名、手机号或账号。

匿名完成不会建立公开个人档案
+
+ + + + setScreen("overview")}>继续 +
+
+
+
+ )} + + {screen === "overview" && ( +
+ +

YOUR ASSESSMENT

五项任务,逐步完成

每项开始前都有练习,不计入最终结果。

+
+ {[ + { Icon: Speedometer, no: "01", title: "符号速配", domain: "处理速度", time: "60 秒", tone: "violet" }, + { Icon: Path, no: "02", title: "交替连线", domain: "执行功能", time: "180 秒", tone: "mint" }, + { Icon: Target, no: "03", title: "动态追踪", domain: "注意力", time: "60 秒", tone: "blue" }, + { Icon: SquaresFour, no: "04", title: "购物记忆", domain: "工作记忆", time: "180 秒", tone: "coral" }, + { Icon: ChartLineUp, no: "05", title: "零钱计算", domain: "计算能力", time: "约 2 分钟", tone: "blue" }, + ].map(({ Icon, no, title, domain, time, tone }) => ( +
{no}{domain}

{title}

{time}
+ ))} +
+
找一个安静的位置,保持浏览器全屏体验更佳。 { resetAll(); openGame("symbol"); }}>进入第一项
+
+ )} + + {screen === "symbol" && ( +
+ setExitConfirm(true)} /> +
+
+
+
{symbolMap.map((symbol, number) =>
{number}
)}
+
{[1, 2, 3, 4, 5, 6, 7, 8, 9, 0].map((number) => )}
+
+
+
+ )} + + {screen === "trail" && ( +
+ setExitConfirm(true)} /> +
+ `${point.x},${point.y}`).join(" ")} /> + {TRAIL_NODES.map((node, index) => { + const position = trailPositions[index]; + const visibleIndex = intro === "trail" ? coachStep : trailIndex; + return ; + })} +
+
+ )} + + {screen === "attention" && ( +
+ setExitConfirm(true)} /> +
+
寻找目标颜色{targetColor === "blue" ? "青绿色飞机" : "珊瑚色飞机"}{[0, 1, 2].map((life) => )}
+
+ {intro === "attention" + ? 教学目标飞机 + : planes.map((plane) => {plane.target)} +
{DIRECTIONS.map((direction) => { const Icon = DIRECTION_ICONS[direction]; return ; })}
+
+
+ )} + + {screen === "memory" && ( +
+ setExitConfirm(true)} /> + {intro === "memory" &&
+ + {listOpen && ; })}
+ } + {intro !== "memory" && memoryPhase === "study" &&

SHOPPING LIST · ROUND {memoryRound}

记住需要购买的物品

正式选择时回看清单会记录次数与停留时长,并影响工作记忆评分。

第 {memoryRound} 轮{memoryTargets.length} 件物品
{memoryTargets.map((index) => )}
{ setMemorySelected([]); setSeconds(MEMORY_ROUND_SECONDS[memoryRound]); setMemoryPhase("conveyor"); }}>我记好了
} + {intro !== "memory" && memoryPhase === "conveyor" &&
+ + {listOpen && ; })}
+ } + + )} + + {screen === "money" && ( +
+ setExitConfirm(true)} /> +
+

{intro === "money" ? "找零试玩" : `EXACT CHANGE · ROUND ${moneyRound} / ${MONEY_ROUNDS.length}`}

组合正确的找零金额

商品价格 ¥{intro === "money" ? 7 : moneyQuestion.price}顾客付款 ¥{intro === "money" ? 10 : moneyQuestion.payment}
{intro === "money" ? "应找零 ¥3.00" : "请自行计算应找金额"}
+
当前已选¥{cashTotal.toFixed(2)}
{cash.map((value, index) => )}
{MONEY_OPTIONS.map((option) => )}
{intro !== "money" && 提交找零}
+
+
+ )} + + {screen === "report" && ( +
+ +

YOUR COGNITIVE SNAPSHOT

本次综合表现

以下结果结合准确率、完成度与错误情况生成。

综合得分{overall}/100
+
完成度{averageCompletion}%正确操作{totalCorrect}错误操作{totalErrors}
+
{reportRows.map(([key, label, Icon]) => { const metric = metrics[key]; const value = metric.score || 70; return
{label}{value}
正确{metric.correct}/{metric.total}错误{metric.errors}完成{metric.completion}%

{value >= 80 ? "表现稳定,速度和准确度配合较好。" : value >= 60 ? "整体平稳,仍有进一步提升空间。" : "波动较明显,建议休息后再尝试。"}

; })}
+
AI 指标总结

{overall >= 80 ? "整体状态稳定" : overall >= 60 ? "整体状态平稳" : "本次表现存在波动"}

本次得分最高的维度是{strongestMetric},相对需要关注的是{improvementMetric}。购物记忆正式阶段回看清单 {memoryListViews.current} 次、累计 {memoryReviewSeconds} 秒,已作为工作记忆评分的扣分因素;零钱计算单独统计,不再混入购物记忆。

相对优势:{strongestMetric} 建议关注:{improvementMetric}
+
window.print()}>保存报告 { resetAll(); openGame("symbol"); }}>重新评估
+

结果仅供自我了解与能力参考,不构成医疗或诊断建议。

+
+ )} + + {feedback &&
{feedback === "correct" ? : }
} + {coach && } + {intro && demoReady && startGame(intro)} />} + {exitConfirm &&

退出当前任务?

当前进度不会保留,你可以返回继续完成。

setExitConfirm(false)}>继续测试
} +
+ ); +} diff --git a/brain-h5/src/main.tsx b/brain-h5/src/main.tsx new file mode 100644 index 0000000..9ff4f46 --- /dev/null +++ b/brain-h5/src/main.tsx @@ -0,0 +1,12 @@ +import React from "react"; +import ReactDOM from "react-dom/client"; +import "@fontsource/roboto/latin-500.css"; +import App from "./App"; +import "./styles.css"; +import "./prototype.css"; + +ReactDOM.createRoot(document.getElementById("root")!).render( + + + , +); diff --git a/brain-h5/src/mobile/BottomSheet.tsx b/brain-h5/src/mobile/BottomSheet.tsx new file mode 100644 index 0000000..bd9252e --- /dev/null +++ b/brain-h5/src/mobile/BottomSheet.tsx @@ -0,0 +1,136 @@ +import { type PropsWithChildren, useEffect, useState } from "react"; +import * as Dialog from "@radix-ui/react-dialog"; +import { useDrag } from "@use-gesture/react"; +import { AnimatePresence, motion } from "motion/react"; +import { useKeyboard, useKeyboardInsets } from "./Keyboard"; +import { useScreenPortal } from "./PhoneFrame"; +import { useMobileDevice } from "./Device"; + +type BottomSheetProps = PropsWithChildren<{ + open: boolean; + onOpenChange: (open: boolean) => void; + title: string; + description?: string; + snap?: number; +}>; + +export function BottomSheet({ + open, + onOpenChange, + title, + description, + snap = 0.72, + children, +}: BottomSheetProps) { + const { device } = useMobileDevice(); + const { screenRef } = useScreenPortal(); + const keyboard = useKeyboard(); + const { keyboardHeight } = useKeyboardInsets(); + const [dragY, setDragY] = useState(0); + + useEffect(() => { + if (open) keyboard.hide(); + }, [open]); + + const handleOpenChange = (nextOpen: boolean) => { + if (nextOpen) { + keyboard.hide(); + } + + onOpenChange(nextOpen); + }; + + const bindDrag = useDrag( + (state) => { + const [, movementY] = state.movement; + const [, velocityY] = state.velocity; + const [, directionY] = state.direction; + const nextY = Math.max(0, movementY); + + if (!state.last) { + setDragY(nextY); + return; + } + + const shouldClose = nextY > 96 || (velocityY > 0.55 && directionY > 0); + setDragY(0); + + if (shouldClose) { + onOpenChange(false); + } + }, + { + axis: "y", + filterTaps: true, + }, + ); + + const sheetHeight = Math.round(device.geometry.screen.height * snap); + const effectiveHeight = Math.max(260, sheetHeight - Math.min(keyboardHeight, 180)); + const sheetBottom = + device.platform === "android" + ? Math.max(device.geometry.safeArea.bottom, keyboardHeight) + : keyboardHeight; + const portalContainer = screenRef.current ?? undefined; + + return ( + + {/* Keep the portal mounted after `open` flips so AnimatePresence can run + the sheet and overlay exit animations before Radix removes them. */} + + + {open ? ( + <> + + + + + +
+
+
+
+ {title} + {description ? {description} : null} +
+
{children}
+ + + + ) : null} + + + + ); +} diff --git a/brain-h5/src/mobile/COMPONENTS.md b/brain-h5/src/mobile/COMPONENTS.md new file mode 100644 index 0000000..653194a --- /dev/null +++ b/brain-h5/src/mobile/COMPONENTS.md @@ -0,0 +1,31 @@ +# Mobile runtime components + +## Carousel + +`Carousel` is the standard component for horizontal collections: cards, images, media, swipeable items, and chip or filter rails. Place it directly inside `MobileScroll`; consumers should not add gesture wrappers or pointer handlers. + +```tsx + +
+ + {cards} + +
+
+``` + +The runtime resolves nested gestures by axis. Horizontal intent stays with `Carousel`; vertical intent is handed to the parent `MobileScroll`. Slight vertical drift after a horizontal gesture is claimed does not move, rubber-band, or add momentum to the parent. Taps remain clickable, while a completed drag suppresses the item click. + +Do not use `data-scroll-drag="ignore"` for carousels or ordinary rails. It is a hard opt-out that prevents parent scrolling in every direction. Do not layer CSS scroll snapping over the runtime's JavaScript momentum. If snapping is added later, it should be a component option so one system owns release motion. + +## Keyboard-linked surfaces + +Use `KeyboardInput`, `KeyboardTextarea`, or `MobileTextField` for all text entry. Position a composer, search surface, or other keyboard-linked UI from `useKeyboardInsets().bottomInset`. The inset is relative to the app viewport: Android's closed-keyboard viewport already ends above its navigation bar, while iOS still needs its overlaid home-indicator inset; both platforms return the keyboard height while the keyboard is open. Never pin those surfaces to only `keyboardHeight`. When that surface closes, call `keyboard.hide()` in the same event before updating its own open state. + +## BottomSheet + +`BottomSheet` dismisses the keyboard before opening and animates both in and out by default. Keep its `open` state controlled through `onOpenChange`; no consumer exit-animation wrapper is needed. diff --git a/brain-h5/src/mobile/Carousel.tsx b/brain-h5/src/mobile/Carousel.tsx new file mode 100644 index 0000000..28f0997 --- /dev/null +++ b/brain-h5/src/mobile/Carousel.tsx @@ -0,0 +1,257 @@ +import { + useCallback, + useEffect, + useRef, + useState, + type CSSProperties, + type MouseEvent as ReactMouseEvent, + type PointerEvent as ReactPointerEvent, + type PropsWithChildren, +} from "react"; + +export type CarouselProps = PropsWithChildren<{ + className?: string; + contentClassName?: string; + ariaLabel?: string; + showScrollbar?: boolean; + draggingEnabled?: boolean; +}>; + +const physics = { + friction: 2.1, + velocityScale: 890, + velocityTolerance: 18, + bounceTension: 200, + bounceFriction: 40, + overdragScale: 0.5, + maxOverdrag: 96, + sampleWindow: 100, + dragThreshold: 8, +} as const; + +type Sample = { value: number; time: number }; +type DragSession = { + pointerId: number; + startPrimary: number; + startCross: number; + startOffset: number; + captured: boolean; + dragged: boolean; +}; + +export function Carousel({ + className, + contentClassName, + ariaLabel, + showScrollbar = false, + draggingEnabled = true, + children, +}: CarouselProps) { + const scrollRef = useRef(null); + const sessionRef = useRef(null); + const samplesRef = useRef([]); + const frameRef = useRef(null); + const overdragRef = useRef(0); + const suppressClickRef = useRef(false); + const [dragging, setDragging] = useState(false); + const [overdrag, setOverdrag] = useState(0); + const [thumb, setThumb] = useState({ visible: false, offset: 0, size: 0 }); + + const offset = useCallback((node: HTMLDivElement) => node.scrollLeft, []); + const setOffset = useCallback((node: HTMLDivElement, value: number) => { + node.scrollLeft = value; + }, []); + const clientSize = useCallback((node: HTMLDivElement) => node.clientWidth, []); + const scrollSize = useCallback((node: HTMLDivElement) => node.scrollWidth, []); + const maxOffset = useCallback((node: HTMLDivElement) => Math.max(0, scrollSize(node) - clientSize(node)), [clientSize, scrollSize]); + + const stopMotion = useCallback(() => { + if (frameRef.current !== null) window.cancelAnimationFrame(frameRef.current); + frameRef.current = null; + }, []); + const setRubberBand = useCallback((value: number) => { + const next = Math.max(-physics.maxOverdrag, Math.min(physics.maxOverdrag, value)); + overdragRef.current = next; + setOverdrag(next); + }, []); + + const updateThumb = useCallback((visible = true) => { + if (!showScrollbar || !scrollRef.current) return; + const node = scrollRef.current; + const viewport = clientSize(node); + const content = scrollSize(node); + const enabled = content > viewport + 2; + const size = enabled ? Math.max(36, (viewport / content) * viewport) : 0; + const track = Math.max(0, viewport - size - 8); + const progress = offset(node) / Math.max(1, content - viewport); + setThumb({ visible: visible && enabled, size, offset: enabled ? 4 + progress * track : 0 }); + }, [clientSize, offset, scrollSize, showScrollbar]); + + const springBack = useCallback((initialVelocity = 0) => { + stopMotion(); + let position = overdragRef.current; + let velocity = Math.max(-1400, Math.min(1400, initialVelocity)); + let previous: number | null = null; + const tick = (time: number) => { + const seconds = Math.min(0.034, ((previous === null ? 16 : time - previous) || 16) / 1000); + previous = time; + velocity += (-physics.bounceTension * position - physics.bounceFriction * velocity) * seconds; + position += velocity * seconds; + if (Math.abs(position) < 0.5 && Math.abs(velocity) < 0.5) { + setRubberBand(0); + frameRef.current = null; + return; + } + setRubberBand(position); + frameRef.current = window.requestAnimationFrame(tick); + }; + frameRef.current = window.requestAnimationFrame(tick); + }, [setRubberBand, stopMotion]); + + const momentum = useCallback((node: HTMLDivElement, initialVelocity: number) => { + let velocity = initialVelocity; + let previous: number | null = null; + const tick = (time: number) => { + const seconds = (previous === null ? 16 : Math.min(34, time - previous)) / 1000; + previous = time; + velocity *= Math.exp(-physics.friction * seconds); + if (Math.abs(velocity) < physics.velocityTolerance) { + frameRef.current = null; + updateThumb(true); + return; + } + const next = offset(node) + velocity * seconds; + const maximum = maxOffset(node); + if (next < 0 || next > maximum) { + setOffset(node, Math.max(0, Math.min(maximum, next))); + // Match MobileScroll's edge convention: positive displacement at the + // leading edge, negative displacement at the trailing edge. + setRubberBand((next < 0 ? -next : maximum - next) * physics.overdragScale); + springBack(velocity * physics.overdragScale); + return; + } + setOffset(node, next); + updateThumb(true); + frameRef.current = window.requestAnimationFrame(tick); + }; + if (Math.abs(velocity) >= physics.velocityTolerance) frameRef.current = window.requestAnimationFrame(tick); + }, [maxOffset, offset, setOffset, setRubberBand, springBack, updateThumb]); + + useEffect(() => { + const node = scrollRef.current; + if (!node) return; + const onScroll = () => updateThumb(true); + const observer = new ResizeObserver(() => updateThumb(false)); + node.addEventListener("scroll", onScroll, { passive: true }); + observer.observe(node); + if (node.firstElementChild) observer.observe(node.firstElementChild); + updateThumb(false); + return () => { + node.removeEventListener("scroll", onScroll); + observer.disconnect(); + stopMotion(); + }; + }, [stopMotion, updateThumb]); + + const primary = (event: ReactPointerEvent) => event.clientX; + const cross = (event: ReactPointerEvent) => event.clientY; + const record = (value: number) => { + const time = performance.now(); + samplesRef.current = [...samplesRef.current, { value, time }].filter((sample) => time - sample.time <= physics.sampleWindow); + }; + + const onPointerDown = (event: ReactPointerEvent) => { + const node = scrollRef.current; + if (!draggingEnabled || !node || maxOffset(node) <= 2 || (event.pointerType === "mouse" && event.button !== 0)) return; + stopMotion(); + samplesRef.current = []; + record(primary(event)); + setRubberBand(0); + sessionRef.current = { pointerId: event.pointerId, startPrimary: primary(event), startCross: cross(event), startOffset: offset(node), captured: false, dragged: false }; + }; + + const onPointerMove = (event: ReactPointerEvent) => { + const node = scrollRef.current; + const session = sessionRef.current; + if (!node || !session || session.pointerId !== event.pointerId) return; + const delta = primary(event) - session.startPrimary; + const crossDelta = cross(event) - session.startCross; + if (!session.dragged) { + // Keep the gesture pending until it clears tap slop. Pointer-down and + // these early moves must bubble so a parent MobileScroll can still win. + if (Math.max(Math.abs(delta), Math.abs(crossDelta)) < physics.dragThreshold) return; + if (Math.abs(crossDelta) > Math.abs(delta)) { + // The cross axis won. Abandon this session without capturing or + // canceling the event so the parent can handle this move and release. + sessionRef.current = null; + return; + } + // The scroller owns the gesture from this move onward. Capture keeps + // delivery stable outside its bounds; stopping propagation prevents the + // parent from accumulating vertical drift or release momentum. + event.currentTarget.setPointerCapture(event.pointerId); + session.captured = true; + } + event.preventDefault(); + event.stopPropagation(); + session.dragged = true; + setDragging(true); + suppressClickRef.current = true; + record(primary(event)); + const desired = session.startOffset - delta; + const maximum = maxOffset(node); + setOffset(node, Math.max(0, Math.min(maximum, desired))); + setRubberBand(desired < 0 ? -desired * physics.overdragScale : desired > maximum ? -(desired - maximum) * physics.overdragScale : 0); + updateThumb(true); + }; + + const finish = (event: ReactPointerEvent) => { + const node = scrollRef.current; + const session = sessionRef.current; + if (!node || !session || session.pointerId !== event.pointerId) return; + if (session.captured) event.currentTarget.releasePointerCapture(event.pointerId); + const samples = samplesRef.current; + const first = samples[0]; + const last = samples[samples.length - 1]; + const velocity = first && last ? -((last.value - first.value) / Math.max(1, last.time - first.time)) * physics.velocityScale : 0; + sessionRef.current = null; + setDragging(false); + if (session.dragged) event.preventDefault(); + if (Math.abs(overdragRef.current) > 0.1) springBack(velocity * physics.overdragScale); + else momentum(node, velocity); + }; + + const onClickCapture = (event: ReactMouseEvent) => { + if (!suppressClickRef.current) return; + suppressClickRef.current = false; + event.preventDefault(); + event.stopPropagation(); + }; + + const style = { "--mobile-carousel-overdrag": `${overdrag}px` } as CSSProperties; + const thumbStyle = { width: thumb.size, transform: `translateX(${thumb.offset}px)` }; + + return ( +
+
{children}
+ {showScrollbar ? ( + + ); +} diff --git a/brain-h5/src/mobile/Device.tsx b/brain-h5/src/mobile/Device.tsx new file mode 100644 index 0000000..aedf084 --- /dev/null +++ b/brain-h5/src/mobile/Device.tsx @@ -0,0 +1,115 @@ +import { createContext, type PropsWithChildren, useContext, useMemo, useState } from "react"; +import * as DropdownMenu from "@radix-ui/react-dropdown-menu"; +import { CheckIcon, ChevronDownIcon } from "@radix-ui/react-icons"; +import { mobileAssets } from "./assets"; +import { iphoneGeometry, pixelGeometry, type MobileDeviceGeometry } from "./geometry"; + +export type MobileDeviceId = "iphone" | "pixel-10"; + +type MobileDevicePreset = { + id: MobileDeviceId; + label: string; + platform: "ios" | "android"; + bezel: string; + bezelLayer: "above-screen" | "below-screen"; + geometry: MobileDeviceGeometry; + camera?: { + size: number; + top: number; + }; +}; + +export const mobileDevices: Record = { + iphone: { + id: "iphone", + label: "iPhone", + platform: "ios", + bezel: mobileAssets.iphoneBezel, + bezelLayer: "above-screen", + geometry: iphoneGeometry, + }, + "pixel-10": { + id: "pixel-10", + label: "Pixel 10", + platform: "android", + bezel: mobileAssets.pixel10Bezel, + bezelLayer: "below-screen", + geometry: pixelGeometry, + camera: { + size: 32, + top: 23, + }, + }, +}; + +type MobileDeviceContextValue = { + device: MobileDevicePreset; + deviceId: MobileDeviceId; + setDeviceId: (deviceId: MobileDeviceId) => void; +}; + +const MobileDeviceContext = createContext(null); + +export function MobileDeviceProvider({ children }: PropsWithChildren) { + const [deviceId, setDeviceId] = useState("iphone"); + const value = useMemo( + () => ({ device: mobileDevices[deviceId], deviceId, setDeviceId }), + [deviceId], + ); + + return {children}; +} + +export function useMobileDevice() { + const context = useContext(MobileDeviceContext); + + if (!context) { + throw new Error("useMobileDevice must be used inside MobileDeviceProvider"); + } + + return context; +} + +export function DevicePicker() { + const { device, deviceId, setDeviceId } = useMobileDevice(); + + return ( + +
+ + + +
+ + + setDeviceId(value as MobileDeviceId)} + > + {Object.values(mobileDevices).map((option) => ( + + {option.label} + + + + ))} + + + +
+ ); +} diff --git a/brain-h5/src/mobile/FlowStack.tsx b/brain-h5/src/mobile/FlowStack.tsx new file mode 100644 index 0000000..f98f257 --- /dev/null +++ b/brain-h5/src/mobile/FlowStack.tsx @@ -0,0 +1,234 @@ +import { + createContext, + type CSSProperties, + type PropsWithChildren, + type ReactNode, + useCallback, + useContext, + useMemo, + useRef, + useState, +} from "react"; +import { AnimatePresence, motion } from "motion/react"; +import { useDrag } from "@use-gesture/react"; +import { useMobileDevice } from "./Device"; +import { useKeyboard, useKeyboardDismissDrag, useKeyboardInsets } from "./Keyboard"; + +export type FlowScreen = { + id: string; + title?: string; + header?: (flow: FlowControls) => ReactNode; + headerHeight?: number; + footer?: (flow: FlowControls) => ReactNode; + footerHeight?: number; + render: (flow: FlowControls) => ReactNode; +}; + +type FlowEntry = FlowScreen & { + key: string; +}; + +export type FlowControls = { + current: FlowEntry; + previous: FlowEntry | null; + stack: FlowEntry[]; + canGoBack: boolean; + push: (screen: FlowScreen) => void; + pop: () => void; + replace: (screen: FlowScreen) => void; +}; + +const FlowContext = createContext(null); + +export function useFlow() { + const context = useContext(FlowContext); + + if (!context) { + throw new Error("useFlow must be used inside FlowStack"); + } + + return context; +} + +function FlowProvider({ value, children }: PropsWithChildren<{ value: FlowControls }>) { + return {children}; +} + +export function FlowStack({ initial }: { initial: FlowScreen }) { + const { device } = useMobileDevice(); + const keyboard = useKeyboard(); + const { bottomInset, keyboardDragging } = useKeyboardInsets(); + const dismissKeyboardDrag = useKeyboardDismissDrag(); + const sequence = useRef(1); + const gestureStartedAtEdge = useRef(false); + const initialEntry = useRef({ ...initial, key: `${initial.id}-0` }); + const [stack, setStack] = useState(() => [initialEntry.current]); + const [direction, setDirection] = useState(1); + const [swipeX, setSwipeX] = useState(0); + + const toEntry = useCallback((screen: FlowScreen): FlowEntry => { + const next = sequence.current; + sequence.current += 1; + return { ...screen, key: `${screen.id}-${next}` }; + }, []); + + const pop = useCallback(() => { + keyboard.hide(); + setDirection(-1); + setStack((currentStack) => { + if (currentStack.length <= 1) return currentStack; + return currentStack.slice(0, -1); + }); + }, [keyboard]); + + const controls = useMemo(() => { + const current = stack[stack.length - 1]; + const previous = stack.length > 1 ? stack[stack.length - 2] : null; + + return { + current, + previous, + stack, + canGoBack: stack.length > 1, + push: (screen) => { + keyboard.hide(); + setDirection(1); + setSwipeX(0); + setStack((currentStack) => [...currentStack, toEntry(screen)]); + }, + pop, + replace: (screen) => { + keyboard.hide(); + setDirection(1); + setSwipeX(0); + setStack((currentStack) => { + const next = currentStack.slice(0, -1); + return [...next, toEntry(screen)]; + }); + }, + }; + }, [keyboard, pop, stack, toEntry]); + + const bindEdgeSwipe = useDrag( + (state) => { + if (!controls.canGoBack) return; + + if (state.first) { + const target = state.event.currentTarget as HTMLElement; + const bounds = target.getBoundingClientRect(); + gestureStartedAtEdge.current = state.initial[0] - bounds.left < 28; + } + + if (!gestureStartedAtEdge.current) return; + + const [movementX] = state.movement; + const [velocityX] = state.velocity; + const [directionX] = state.direction; + const nextX = Math.max(0, Math.min(movementX, device.geometry.screen.width)); + + if (!state.last) { + setSwipeX(nextX); + return; + } + + const shouldPop = nextX > 92 || (velocityX > 0.45 && directionX > 0); + setSwipeX(0); + gestureStartedAtEdge.current = false; + + if (shouldPop) { + controls.pop(); + } + }, + { + axis: "x", + filterTaps: true, + pointer: { touch: true }, + }, + ); + + const screenWidth = device.geometry.screen.width; + const topIndex = stack.length - 1; + const parkedX = -screenWidth * 0.28; + const header = controls.current.header?.(controls); + const headerHeight = controls.current.headerHeight ?? 0; + const headerSafeArea = header ? device.geometry.safeArea.top : 0; + const totalHeaderHeight = header ? headerSafeArea + headerHeight : 0; + const footer = controls.current.footer?.(controls); + const footerHeight = controls.current.footerHeight ?? 0; + + const screenVariants = { + enter: (animationDirection: number) => ({ + x: animationDirection > 0 ? screenWidth : parkedX, + scale: animationDirection > 0 ? 1 : 0.985, + }), + exit: (animationDirection: number) => ({ + x: animationDirection < 0 ? screenWidth : parkedX, + scale: animationDirection < 0 ? 1 : 0.985, + }), + }; + + return ( + +
+ {header ? ( +
+ {header} +
+ ) : null} +
+ + {stack.map((entry, index) => { + const isTop = index === topIndex; + const isVisible = index >= topIndex - 1; + + return ( + + {entry.render(controls)} + + ); + })} + +
+ {footer ? ( +
+ {footer} +
+ ) : null} +
+
+ ); +} diff --git a/brain-h5/src/mobile/Keyboard.tsx b/brain-h5/src/mobile/Keyboard.tsx new file mode 100644 index 0000000..54d8464 --- /dev/null +++ b/brain-h5/src/mobile/Keyboard.tsx @@ -0,0 +1,241 @@ +import { + createContext, + type InputHTMLAttributes, + type PointerEvent as ReactPointerEvent, + type PropsWithChildren, + type Ref, + type TextareaHTMLAttributes, + useContext, + useMemo, + useRef, + useState, +} from "react"; +import { motion } from "motion/react"; +import { mobileAssets } from "./assets"; +import { useMobileDevice } from "./Device"; + +type KeyboardContextValue = { + visible: boolean; + height: number; + fullHeight: number; + progress: number; + dragOffset: number; + isDragging: boolean; + focusedElement: HTMLElement | null; + setDragOffset: (offset: number) => void; + setDragging: (dragging: boolean) => void; + show: (element?: HTMLElement | null) => void; + hide: () => void; +}; + +type KeyboardInputProps = InputHTMLAttributes & { + ref?: Ref; +}; + +const KeyboardContext = createContext(null); + +export function KeyboardProvider({ children }: PropsWithChildren) { + const { device } = useMobileDevice(); + const [visible, setVisible] = useState(false); + const [dragOffset, setRawDragOffset] = useState(0); + const [isDragging, setDragging] = useState(false); + const [focusedElement, setFocusedElement] = useState(null); + const fullHeight = device.geometry.keyboard.height; + const setDragOffset = (offset: number) => { + setRawDragOffset(Math.max(0, Math.min(fullHeight, offset))); + }; + + const value = useMemo( + () => ({ + visible, + height: visible ? Math.max(0, fullHeight - dragOffset) : 0, + fullHeight, + dragOffset, + isDragging, + progress: visible ? 1 : 0, + focusedElement, + setDragOffset, + setDragging, + show: (element) => { + setRawDragOffset(0); + setDragging(false); + setFocusedElement(element ?? null); + setVisible(true); + }, + hide: () => { + focusedElement?.blur(); + setDragging(false); + setFocusedElement(null); + setVisible(false); + }, + }), + [dragOffset, focusedElement, fullHeight, isDragging, visible], + ); + + return {children}; +} + +export function useKeyboard() { + const context = useContext(KeyboardContext); + + if (!context) { + throw new Error("useKeyboard must be used inside KeyboardProvider"); + } + + return context; +} + +export function useKeyboardInsets() { + const keyboard = useKeyboard(); + const { device } = useMobileDevice(); + const reservesAndroidNavigation = device.platform === "android" && !keyboard.visible; + + return { + keyboardHeight: keyboard.height, + keyboardFullHeight: keyboard.fullHeight, + keyboardDragging: keyboard.isDragging, + bottomInset: reservesAndroidNavigation + ? 0 + : device.platform === "android" + ? keyboard.height + : Math.max(device.geometry.safeArea.bottom, keyboard.height), + availableHeight: + device.geometry.screen.height - + keyboard.height - + (reservesAndroidNavigation ? device.geometry.safeArea.bottom : 0), + isKeyboardVisible: keyboard.visible, + }; +} + +export function useKeyboardDismissDrag() { + const keyboard = useKeyboard(); + const dragRef = useRef({ + pointerId: null as number | null, + startY: 0, + lastY: 0, + lastTime: 0, + velocityY: 0, + }); + + const endDismissDrag = (event: ReactPointerEvent) => { + const drag = dragRef.current; + if (drag.pointerId !== event.pointerId) return; + + try { + event.currentTarget.releasePointerCapture(event.pointerId); + } catch { + // Capture may already be gone after pointer cancel. + } + + const nextY = Math.max(0, event.clientY - drag.startY); + const shouldDismiss = nextY > 76 || drag.velocityY > 0.45; + drag.pointerId = null; + + if (shouldDismiss) { + keyboard.setDragOffset(nextY); + keyboard.hide(); + return; + } + + keyboard.setDragging(false); + keyboard.setDragOffset(0); + }; + + return { + onPointerDown: (event: ReactPointerEvent) => { + if (!keyboard.visible) return; + if (event.pointerType === "mouse" && event.button !== 0) return; + if ( + event.target instanceof Element && + event.target.closest('button, input, textarea, select, a, [role="button"], [contenteditable="true"]') + ) { + return; + } + + keyboard.setDragging(true); + dragRef.current = { + pointerId: event.pointerId, + startY: event.clientY, + lastY: event.clientY, + lastTime: performance.now(), + velocityY: 0, + }; + event.currentTarget.setPointerCapture(event.pointerId); + }, + onPointerMove: (event: ReactPointerEvent) => { + const drag = dragRef.current; + if (drag.pointerId !== event.pointerId) return; + + const now = performance.now(); + const elapsed = Math.max(1, now - drag.lastTime); + drag.velocityY = (event.clientY - drag.lastY) / elapsed; + drag.lastY = event.clientY; + drag.lastTime = now; + keyboard.setDragOffset(Math.max(0, event.clientY - drag.startY)); + }, + onPointerUp: endDismissDrag, + onPointerCancel: endDismissDrag, + }; +} + +export function KeyboardInput(props: KeyboardInputProps) { + const keyboard = useKeyboard(); + const { ref, ...inputProps } = props; + + return ( + { + keyboard.show(event.currentTarget); + inputProps.onFocus?.(event); + }} + /> + ); +} + +export function KeyboardTextarea(props: TextareaHTMLAttributes) { + const keyboard = useKeyboard(); + + return ( +