From 959b2cbd7387609680643b308a0eaa4cabaebbdf Mon Sep 17 00:00:00 2001 From: beingmartinbmc Date: Fri, 12 Jun 2026 00:02:06 +0530 Subject: [PATCH] feat: add iterative linked-list algorithms and standardize speed sliders - Add Reverse a Linked List, Add Two Numbers, and Reverse Nodes in k-Group (all iterative) with synced animated pseudocode, step playback, pointers, and meta - Wire new routes and problem ordering - Standardize animation speed sliders project-wide: Slow on left, Fast on right (drag right = faster) in AlgorithmPlaygroundPage and AdvancedStructurePage to match the rest of the app --- .github/workflows/ci.yml | 34 + README.md | 153 +-- docs/404.html | 4 +- docs/assets/AdvancedStructurePage-C3Gu2vhw.js | 1 + docs/assets/AlgorithmCodePanel-DWTIRULe.js | 1 + .../AlgorithmPlaygroundPage-BZcoKA4I.js | 1 + docs/assets/ArrayPage-BVw3oj1M.js | 5 + docs/assets/BalancedTreePage-BIWzF7Hd.js | 7 + docs/assets/BattlePage-BHrGHw2_.js | 1 + docs/assets/DijkstraGamePage-DPGMG41Z.js | 1 + .../assets/EvolutionSimulatorPage-ClEOzQ75.js | 1 + docs/assets/FibonacciGamePage-yra_MIZ2.js | 19 + docs/assets/GitPage-2cA3c4jf.js | 129 +++ docs/assets/GraphTraversalPage-D6V7J1Sh.js | 18 + docs/assets/LinkedListAlgoPage-wdM2t0_B.js | 1 + .../LinkedListAlgorithmsPage-4LF4-86u.js | 1 + docs/assets/LinkedListPage-DBaHdW5c.js | 1 + docs/assets/MahjongGamePage-CcjiTEak.js | 8 + docs/assets/QueuePage-Dm9bXwaQ.js | 5 + docs/assets/RubiksCubeGamePage-DGHevFh5.js | 1 + docs/assets/SortingPage--_1K-mN2.js | 11 + docs/assets/StackPage-1vXSCZRz.js | 5 + docs/assets/SudokuPage-Bwx9E4N_.js | 13 + docs/assets/TreeTraversalPage-DDkYMql2.js | 11 + docs/assets/TriePage-3KlcWkEC.js | 4 + docs/assets/WorldMapGamePage-B75VoKQY.js | 1 + docs/assets/arrow-left-CkNLVmJL.js | 1 + docs/assets/audioContext-NbgqvQGz.js | 1 + docs/assets/chevron-right-CNA9GG_w.js | 1 + docs/assets/eye-off-B7FP-9s5.js | 1 + docs/assets/index-BfWfBQOp.js | 32 + docs/assets/index-BlMQg5Z1.css | 1 + docs/assets/index-CGDPKfI1.css | 1 - docs/assets/index-Cj8HB9AY.js | 1 + docs/assets/index-DoyPNhOF.js | 256 ----- docs/assets/index-iw_6MvvU.js | 1 + docs/assets/lightbulb-D7RWgS3V.js | 1 + docs/assets/linkedListAlgo-0_WYfSZm.js | 1 + docs/assets/map-DMi7QK0E.js | 1 + docs/assets/pause-Bg-8t1oj.js | 1 + docs/assets/play-WRQgdyAG.js | 1 + docs/assets/plus-BEk43_MF.js | 1 + docs/assets/rotate-ccw-EKzY5q_W.js | 1 + docs/assets/route-CNnmHrEb.js | 1 + docs/assets/shuffle-Ri9xSsK2.js | 1 + docs/assets/skip-forward-DUFQw-PC.js | 1 + docs/assets/square-BSu6WBc6.js | 1 + docs/assets/timer-t0ca9c1j.js | 1 + docs/assets/trash-2-RJG3j28z.js | 1 + docs/assets/trophy-CUioHXrM.js | 1 + docs/assets/useDSSound-BMrOIkPj.js | 1 + docs/assets/volume-x-ChIHiT28.js | 1 + docs/assets/zap-CxtzYT6S.js | 1 + docs/index.html | 4 +- src/App.tsx | 146 +-- src/components/ErrorBoundary.tsx | 67 ++ src/components/Layout/Header.tsx | 124 ++- src/components/RouteFallback.tsx | 16 + .../algorithms/AlgorithmPlaygroundPage.tsx | 171 +++- src/features/algorithms/AlgorithmsPage.tsx | 12 +- .../algorithms/hooks/useAlgorithmSound.ts | 11 +- .../linked-list/LinkedListAlgoPage.tsx | 36 + .../linked-list/LinkedListAlgorithmsPage.tsx | 77 ++ .../algorithms/linkedListAlgorithms.ts | 875 ++++++++++++++++++ .../linked-list/algorithms/randomInput.ts | 54 ++ .../components/LinkedListAlgoCanvas.tsx | 229 +++++ .../components/LinkedListAlgoControls.tsx | 126 +++ .../linked-list/hooks/useLinkedListAlgo.ts | 121 +++ .../linked-list/types/linkedListAlgo.ts | 292 ++++++ .../algorithms/shared/AlgorithmCodePanel.tsx | 67 ++ .../advanced/AdvancedStructurePage.tsx | 9 +- .../data-structures/array/hooks/useArrayDS.ts | 10 +- .../balanced-trees/algorithms/avl.ts | 73 +- .../balanced-trees/algorithms/rbtree.ts | 95 +- .../data-structures/hooks/useDSSound.ts | 12 +- .../data-structures/queue/hooks/useQueue.ts | 6 +- .../data-structures/stack/hooks/useStack.ts | 6 +- .../games/battles/engine/recursionEngine.ts | 2 +- .../games/battles/hooks/useBattleSound.ts | 11 +- .../games/dijkstra/hooks/useDijkstraSound.ts | 17 +- .../hooks/useEvolutionSimulator.ts | 26 +- .../hooks/useEvolutionSound.ts | 10 +- .../games/fibonacci/hooks/useFibonacciGame.ts | 11 +- .../fibonacci/hooks/useFibonacciSound.ts | 16 +- .../games/mahjong/MahjongGamePage.tsx | 1 - .../mahjong/components/MahjongControls.tsx | 2 - .../mahjong/components/TwoPlayerMode.tsx | 3 +- .../games/mahjong/hooks/useMahjongSound.ts | 19 +- .../mahjong/hooks/useMahjongTwoPlayer.ts | 2 +- .../rubiks-cube/hooks/useRubiksCubeSound.ts | 11 +- .../games/world-map/hooks/useWorldMapSound.ts | 12 +- src/features/git/engine/gitEngine.ts | 4 +- src/features/git/hooks/useGitSound.ts | 12 +- src/features/sorting/hooks/useSortingSound.ts | 16 +- .../sudoku-solver/algorithms/generator.ts | 62 ++ .../traversals/graph/algorithms/astar.ts | 9 +- .../traversals/graph/algorithms/dijkstra.ts | 13 +- .../traversals/graph/components/Grid/Grid.tsx | 12 +- .../traversals/tree/hooks/useTreeSound.ts | 11 +- .../traversals/tree/hooks/useTreeTraversal.ts | 2 +- .../traversals/trie/hooks/useTrieSound.ts | 15 +- src/hooks/useSound.ts | 18 +- src/lib/MinHeap.ts | 71 ++ src/lib/audioContext.ts | 54 ++ 104 files changed, 3127 insertions(+), 704 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 docs/assets/AdvancedStructurePage-C3Gu2vhw.js create mode 100644 docs/assets/AlgorithmCodePanel-DWTIRULe.js create mode 100644 docs/assets/AlgorithmPlaygroundPage-BZcoKA4I.js create mode 100644 docs/assets/ArrayPage-BVw3oj1M.js create mode 100644 docs/assets/BalancedTreePage-BIWzF7Hd.js create mode 100644 docs/assets/BattlePage-BHrGHw2_.js create mode 100644 docs/assets/DijkstraGamePage-DPGMG41Z.js create mode 100644 docs/assets/EvolutionSimulatorPage-ClEOzQ75.js create mode 100644 docs/assets/FibonacciGamePage-yra_MIZ2.js create mode 100644 docs/assets/GitPage-2cA3c4jf.js create mode 100644 docs/assets/GraphTraversalPage-D6V7J1Sh.js create mode 100644 docs/assets/LinkedListAlgoPage-wdM2t0_B.js create mode 100644 docs/assets/LinkedListAlgorithmsPage-4LF4-86u.js create mode 100644 docs/assets/LinkedListPage-DBaHdW5c.js create mode 100644 docs/assets/MahjongGamePage-CcjiTEak.js create mode 100644 docs/assets/QueuePage-Dm9bXwaQ.js create mode 100644 docs/assets/RubiksCubeGamePage-DGHevFh5.js create mode 100644 docs/assets/SortingPage--_1K-mN2.js create mode 100644 docs/assets/StackPage-1vXSCZRz.js create mode 100644 docs/assets/SudokuPage-Bwx9E4N_.js create mode 100644 docs/assets/TreeTraversalPage-DDkYMql2.js create mode 100644 docs/assets/TriePage-3KlcWkEC.js create mode 100644 docs/assets/WorldMapGamePage-B75VoKQY.js create mode 100644 docs/assets/arrow-left-CkNLVmJL.js create mode 100644 docs/assets/audioContext-NbgqvQGz.js create mode 100644 docs/assets/chevron-right-CNA9GG_w.js create mode 100644 docs/assets/eye-off-B7FP-9s5.js create mode 100644 docs/assets/index-BfWfBQOp.js create mode 100644 docs/assets/index-BlMQg5Z1.css delete mode 100644 docs/assets/index-CGDPKfI1.css create mode 100644 docs/assets/index-Cj8HB9AY.js delete mode 100644 docs/assets/index-DoyPNhOF.js create mode 100644 docs/assets/index-iw_6MvvU.js create mode 100644 docs/assets/lightbulb-D7RWgS3V.js create mode 100644 docs/assets/linkedListAlgo-0_WYfSZm.js create mode 100644 docs/assets/map-DMi7QK0E.js create mode 100644 docs/assets/pause-Bg-8t1oj.js create mode 100644 docs/assets/play-WRQgdyAG.js create mode 100644 docs/assets/plus-BEk43_MF.js create mode 100644 docs/assets/rotate-ccw-EKzY5q_W.js create mode 100644 docs/assets/route-CNnmHrEb.js create mode 100644 docs/assets/shuffle-Ri9xSsK2.js create mode 100644 docs/assets/skip-forward-DUFQw-PC.js create mode 100644 docs/assets/square-BSu6WBc6.js create mode 100644 docs/assets/timer-t0ca9c1j.js create mode 100644 docs/assets/trash-2-RJG3j28z.js create mode 100644 docs/assets/trophy-CUioHXrM.js create mode 100644 docs/assets/useDSSound-BMrOIkPj.js create mode 100644 docs/assets/volume-x-ChIHiT28.js create mode 100644 docs/assets/zap-CxtzYT6S.js create mode 100644 src/components/ErrorBoundary.tsx create mode 100644 src/components/RouteFallback.tsx create mode 100644 src/features/algorithms/linked-list/LinkedListAlgoPage.tsx create mode 100644 src/features/algorithms/linked-list/LinkedListAlgorithmsPage.tsx create mode 100644 src/features/algorithms/linked-list/algorithms/linkedListAlgorithms.ts create mode 100644 src/features/algorithms/linked-list/algorithms/randomInput.ts create mode 100644 src/features/algorithms/linked-list/components/LinkedListAlgoCanvas.tsx create mode 100644 src/features/algorithms/linked-list/components/LinkedListAlgoControls.tsx create mode 100644 src/features/algorithms/linked-list/hooks/useLinkedListAlgo.ts create mode 100644 src/features/algorithms/linked-list/types/linkedListAlgo.ts create mode 100644 src/features/algorithms/shared/AlgorithmCodePanel.tsx create mode 100644 src/lib/MinHeap.ts create mode 100644 src/lib/audioContext.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..33c85fe --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,34 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + check: + name: Lint, typecheck, build + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '22' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: ESLint + run: npx eslint . --max-warnings=0 + + - name: TypeScript + run: npx tsc -b + + - name: Build + run: npm run build diff --git a/README.md b/README.md index d2e7761..b03c678 100644 --- a/README.md +++ b/README.md @@ -1,73 +1,106 @@ -# React + TypeScript + Vite +# Algorithm Visualizer -This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. +An interactive, browser-based playground for learning algorithms, data structures, and Git through animation. Every algorithm runs in the browser as pure TypeScript — no backend, no telemetry, no tracking. -Currently, two official plugins are available: +**Live demo:** https://anksharma11.github.io/algorithm-visualizer/ -- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh -- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh +--- -## React Compiler +## What's inside -The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation). +- **Sorting** — bubble, selection, insertion, quick, heap, merge with step-by-step bar animation and audio. +- **Graph traversals** — BFS, DFS, Dijkstra, A* on an interactive grid; draw walls, place start/end, generate mazes. +- **Tree traversals** — in/pre/post/level-order on a randomized binary tree. +- **Trie** — word and prefix search with character-by-character traversal. +- **Data structures** — Stack, Queue, Array, Linked List, BST/AVL/Red-Black trees, Trie, Segment Tree, Fenwick Tree. +- **Algorithm playground** — binary/ternary search, Tower of Hanoi, rat-in-a-maze, Dutch national flag, Top-K, queue-via-stacks, stack-via-queues, grid search. +- **Games** + - Fibonacci Spiral Builder + - Dijkstra Delivery Simulator + - World Map Flight Planner (Dijkstra, A*, BFS, greedy) + - Algorithm Battles (head-to-head sort & pathfind races) + - Sudoku Solver (4×4 / 9×9 / 16×16, with uniqueness-checked puzzles) + - Mahjong Hand Solver (backtracking) + - Evolution Simulator (genetic algorithm) + - Rubik's Cube Solver +- **Git Visualizer** — a 1.7k-LOC pure-TS Git simulator with terminal, commit-DAG canvas, freeplay mode, and guided lessons (init/add/commit, branching, merging, rebase, reset, stash, cherry-pick, remotes, push/pull, etc.). -## Expanding the ESLint configuration +## Quick start -If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules: +Requires Node 20+. -```js -export default defineConfig([ - globalIgnores(['dist']), - { - files: ['**/*.{ts,tsx}'], - extends: [ - // Other configs... +```bash +npm install +npm run dev # Vite dev server with HMR +npm run lint # ESLint (strict; CI blocks on errors) +npm run build # tsc + vite build → docs/ for GitHub Pages +npm run preview # serve the production build locally +``` + +## Architecture - // Remove tseslint.configs.recommended and replace with this - tseslint.configs.recommendedTypeChecked, - // Alternatively, use this for stricter rules - tseslint.configs.strictTypeChecked, - // Optionally, add this for stylistic rules - tseslint.configs.stylisticTypeChecked, +The codebase follows a strict feature-folder pattern. Every visualization lives in `src/features//` and is composed of: - // Other configs... - ], - languageOptions: { - parserOptions: { - project: ['./tsconfig.node.json', './tsconfig.app.json'], - tsconfigRootDir: import.meta.dirname, - }, - // other options... - }, - }, -]) ``` +features// +├── Page.tsx # thin composition: + +├── components/ # presentational React components +├── hooks/use.ts # state machine + step playback +├── algorithms/ (or engine/) # pure, framework-free TS — the actual algorithm +└── types/.ts # shared types and constants +``` + +The pure-TS layer (`algorithms/` or `engine/`) returns arrays of `Step` objects (step descriptions + visualization payloads). The hook drives forward/backward/auto-play through that array. The components render whatever the current step says. This: + +- keeps algorithm code unit-testable and reusable across features (e.g. `games/battles` reuses `traversals/graph/algorithms` directly), +- makes step-back / scrubbing / replay free, +- separates "what the algorithm does" from "how it animates." + +### Adding a new visualization + +1. Create `src/features/myThing/`. +2. Write `algorithms/myThing.ts` — a pure function from input → `MyThingStep[]`. +3. Write `hooks/useMyThing.ts` — `useState` for the step pointer, `setTimeout` (or shared `useTones`) for playback. +4. Write `components/MyThingCanvas.tsx` and `MyThingControls.tsx`. +5. Add a `MyThingPage.tsx` that composes the above. +6. Lazy-import the page in `src/App.tsx` and add a ``. + +### Cross-cutting helpers + +- `src/lib/MinHeap.ts` — generic binary heap. Used by Dijkstra and A*. +- `src/lib/audioContext.ts` — single shared, lazy `AudioContext` with autoplay-policy and Safari-interrupted-state handling. +- `src/components/ErrorBoundary.tsx` — wraps the route tree; one crashing visualization can't blank the app. +- `src/components/RouteFallback.tsx` — Suspense fallback for lazy-loaded routes. -You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules: - -```js -// eslint.config.js -import reactX from 'eslint-plugin-react-x' -import reactDom from 'eslint-plugin-react-dom' - -export default defineConfig([ - globalIgnores(['dist']), - { - files: ['**/*.{ts,tsx}'], - extends: [ - // Other configs... - // Enable lint rules for React - reactX.configs['recommended-typescript'], - // Enable lint rules for React DOM - reactDom.configs.recommended, - ], - languageOptions: { - parserOptions: { - project: ['./tsconfig.node.json', './tsconfig.app.json'], - tsconfigRootDir: import.meta.dirname, - }, - // other options... - }, - }, -]) +## Tech stack + +| Area | Choice | +|------------|---------------------------------------------| +| Build | Vite 7, React 19, TypeScript 5 (strict) | +| Styling | Tailwind CSS v4 (`@tailwindcss/vite`) | +| Routing | `react-router-dom` v7 with code-split routes | +| Icons | `lucide-react` | +| Audio | Web Audio API (single shared `AudioContext`) | +| Lint | ESLint flat config + `typescript-eslint` + `react-hooks` | + +## Deploy + +Production build outputs to `docs/`, ready for GitHub Pages: + +```bash +npm run build +# docs/index.html, docs/assets/*, docs/.nojekyll, docs/404.html ``` + +`docs/404.html` is a copy of `index.html` so GitHub Pages serves the SPA on deep links (the `BrowserRouter` `basename="/algorithm-visualizer"` matches the repo name). `.nojekyll` disables Jekyll processing of underscore-prefixed assets. + +## Project status + +- **TypeScript:** `tsc -b` passes with zero errors. Strict mode, `verbatimModuleSyntax`, `noUnusedLocals`, `noUnusedParameters`, `erasableSyntaxOnly`. +- **ESLint:** zero errors, zero warnings. +- **Tests:** none yet — pure step-builders in `engine/` and `algorithms/` are the natural targets when added. +- **Bundle:** initial route loads only landing-page + section-index chunks; feature pages are code-split. + +## License + +MIT. diff --git a/docs/404.html b/docs/404.html index 97b153e..16984f3 100644 --- a/docs/404.html +++ b/docs/404.html @@ -5,8 +5,8 @@ Algorithm Visualizer - - + +
diff --git a/docs/assets/AdvancedStructurePage-C3Gu2vhw.js b/docs/assets/AdvancedStructurePage-C3Gu2vhw.js new file mode 100644 index 0000000..ad75678 --- /dev/null +++ b/docs/assets/AdvancedStructurePage-C3Gu2vhw.js @@ -0,0 +1 @@ +import{r as N,j as t}from"./index-BfWfBQOp.js";import{u as O}from"./useDSSound-BMrOIkPj.js";import{S as P}from"./shuffle-Ri9xSsK2.js";import{C as E,a as D}from"./chevron-right-CNA9GG_w.js";import{P as F}from"./play-WRQgdyAG.js";import{V,a as W}from"./volume-x-ChIHiT28.js";import"./audioContext-NbgqvQGz.js";const Q={trie:{title:"Trie",subtitle:"Prefix tree for words",inputLabel:"Words; operation; query",defaultInput:"cat,car,cart,dog,dove;prefix;ca",helper:"Format: words; insert/delete/search/prefix; query"},"segment-tree":{title:"Segment Tree",subtitle:"Range query and point update",inputLabel:"Array; operation; args",defaultInput:"2,1,5,3,4,8;query;1,4",helper:"Operations: build, query;l,r, update;index,value"},"fenwick-tree":{title:"Fenwick Tree",subtitle:"Binary indexed tree",inputLabel:"Array; operation; args",defaultInput:"2,1,5,3,4,8;range;1,4",helper:"Operations use 1-based indexes: build, prefix;i, range;l,r, update;index,value"}};function re({structure:i}){const l=Q[i],[p,c]=N.useState(l.defaultInput),[e,d]=N.useState(()=>R(i,l.defaultInput)),[o,x]=N.useState(0),[h,f]=N.useState(650),{soundEnabled:n,toggleSound:s,playInsert:a,playDelete:r,playAccess:w,playTraverse:$,playFound:y,playNotFound:b}=O(),m=e[o]??e[0],j=(u,g)=>{u.event==="insert"?a():u.event==="delete"?r():u.event==="access"?w():u.event==="traverse"?$(g,e.length):u.event==="found"?y():b()},z=()=>{const u=R(i,p);d(u),x(0),u[0]&&j(u[0],0)},I=u=>{const g=Math.max(0,Math.min(e.length-1,u));x(g);const C=e[g];C&&j(C,g)},B=()=>{const u=J(i);c(u);const g=R(i,u);d(g),x(0)},L=()=>{for(let u=o;u{x(u);const g=e[u];g&&j(g,u)},(u-o)*h)};return t.jsxs("div",{className:"flex flex-1 flex-col gap-4 overflow-auto p-4 md:p-6 xl:flex-row",children:[t.jsxs("main",{className:"order-last flex min-h-[520px] flex-1 flex-col gap-4 xl:order-first",children:[t.jsxs("section",{className:"rounded-2xl border border-slate-700/50 bg-slate-900/60 p-5 backdrop-blur-sm",children:[t.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-[0.24em] text-rose-300",children:"Data Structures"}),t.jsx("h2",{className:"mt-1 text-xl font-bold text-white",children:l.title}),t.jsx("p",{className:"mt-1 text-sm text-slate-400",children:l.subtitle})]}),t.jsx("section",{className:"flex flex-1 items-center justify-center rounded-2xl border border-slate-700/50 bg-slate-950/60 p-5",children:m?.nodes?t.jsx(U,{step:m}):t.jsx(X,{step:m,structure:i})})]}),t.jsxs("aside",{className:"w-full space-y-4 xl:w-80 xl:shrink-0",children:[t.jsxs(k,{title:"Operation",children:[t.jsx("label",{className:"text-[11px] text-slate-500",children:l.inputLabel}),t.jsx("textarea",{value:p,onChange:u=>c(u.target.value),rows:2,className:"mt-1 w-full resize-none rounded-xl bg-slate-950/70 px-3 py-2 text-xs font-mono text-slate-200 ring-1 ring-slate-700/50 outline-none focus:ring-rose-500/50"}),t.jsx("p",{className:"mt-2 text-[10px] leading-relaxed text-slate-500",children:l.helper}),t.jsxs("div",{className:"mt-3 grid grid-cols-2 gap-2",children:[t.jsx("button",{onClick:z,className:"rounded-xl bg-rose-500/20 px-3 py-2 text-xs font-semibold text-rose-300 ring-1 ring-rose-500/40 hover:bg-rose-500/30",children:"Run"}),t.jsxs("button",{onClick:B,className:"inline-flex items-center justify-center gap-1 rounded-xl bg-slate-800/70 px-3 py-2 text-xs font-semibold text-slate-300 ring-1 ring-slate-700/50 hover:bg-slate-700/70",children:[t.jsx(P,{size:13})," Random"]})]})]}),t.jsxs(k,{title:"Step Playback",children:[t.jsx("p",{className:"min-h-12 text-xs leading-relaxed text-slate-300",children:m?.description}),m?.meta&&t.jsx("div",{className:"mt-2 flex flex-wrap gap-1",children:m.meta.map(u=>t.jsx("span",{className:"rounded-full bg-slate-800 px-2 py-0.5 text-[10px] font-mono text-slate-400",children:u},u))}),t.jsxs("div",{className:"mt-3 flex items-center justify-between text-xs text-slate-500",children:[t.jsx("span",{children:"Step"}),t.jsxs("span",{className:"font-mono text-rose-300",children:[Math.min(o+1,e.length)," / ",e.length]})]}),t.jsxs("div",{className:"mt-3 rounded-xl border border-slate-700/40 bg-slate-950/40 p-3",children:[t.jsxs("div",{className:"mb-2 flex items-center justify-between",children:[t.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-wider text-slate-500",children:"Animation Speed"}),t.jsxs("span",{className:"font-mono text-[10px] text-rose-300",children:[h,"ms"]})]}),t.jsx("input",{type:"range",min:120,max:1200,step:40,value:h,onChange:u=>f(Number(u.target.value)),className:"w-full accent-rose-400","aria-label":"Animation step delay"}),t.jsxs("div",{className:"mt-1 flex justify-between text-[9px] uppercase tracking-wide text-slate-600",children:[t.jsx("span",{children:"Fast"}),t.jsx("span",{children:"Slow"})]})]}),t.jsxs("div",{className:"mt-3 grid grid-cols-3 gap-2",children:[t.jsxs("button",{onClick:()=>I(o-1),disabled:o<=0,className:"inline-flex items-center justify-center gap-1 rounded-xl bg-slate-800/70 px-2 py-2 text-xs text-slate-300 ring-1 ring-slate-700/50 disabled:opacity-30",children:[t.jsx(E,{size:13})," Back"]}),t.jsxs("button",{onClick:L,disabled:o>=e.length-1,className:"inline-flex items-center justify-center gap-1 rounded-xl bg-emerald-500/15 px-2 py-2 text-xs font-semibold text-emerald-300 ring-1 ring-emerald-500/30 disabled:opacity-30",children:[t.jsx(F,{size:13})," Play"]}),t.jsxs("button",{onClick:()=>I(o+1),disabled:o>=e.length-1,className:"inline-flex items-center justify-center gap-1 rounded-xl bg-slate-800/70 px-2 py-2 text-xs text-slate-300 ring-1 ring-slate-700/50 disabled:opacity-30",children:["Next ",t.jsx(D,{size:13})]})]})]}),t.jsx(k,{title:"Audio",children:t.jsxs("button",{onClick:()=>s(!n),className:`inline-flex w-full items-center justify-center gap-2 rounded-xl px-3 py-2 text-xs font-semibold ring-1 ${n?"bg-rose-500/15 text-rose-300 ring-rose-500/30":"bg-slate-800/70 text-slate-400 ring-slate-700/40"}`,children:[n?t.jsx(V,{size:14}):t.jsx(W,{size:14}),n?"Sound On":"Sound Off"]})})]})]})}function k({title:i,children:l}){return t.jsxs("section",{className:"rounded-2xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[t.jsx("h3",{className:"mb-3 text-xs font-semibold uppercase tracking-wider text-slate-400",children:i}),l]})}function U({step:i}){const l=i.nodes??[],p=new Set(i.highlights??[]);return t.jsxs("svg",{viewBox:"0 0 720 380",className:"h-full min-h-[420px] w-full",children:[l.map(c=>{const e=l.find(d=>d.id===c.parentId);return e?t.jsx("line",{x1:e.x,y1:e.y,x2:c.x,y2:c.y,stroke:"#475569",strokeWidth:1.5},`${e.id}-${c.id}`):null}),l.map(c=>{const e=p.has(Number(c.id.replace(/\D/g,"")))||p.has(l.indexOf(c));return t.jsxs("g",{children:[t.jsx("circle",{cx:c.x,cy:c.y,r:22,fill:e?"rgba(244,63,94,0.22)":"rgba(30,41,59,0.9)",stroke:e?"#fb7185":"#64748b",strokeWidth:2}),t.jsx("text",{x:c.x,y:c.y+4,textAnchor:"middle",fontSize:"12",fontWeight:"800",fill:e?"#fecdd3":"#cbd5e1",children:c.label}),c.value!==void 0&&t.jsx("text",{x:c.x,y:c.y+35,textAnchor:"middle",fontSize:"10",fill:"#94a3b8",children:c.value})]},c.id)})]})}function X({step:i,structure:l}){const p=i?.array??[],c=new Set(i?.highlights??[]);return t.jsxs("div",{className:"w-full space-y-6",children:[t.jsx("div",{className:"flex flex-wrap justify-center gap-2",children:p.map((e,d)=>t.jsxs("div",{className:`relative flex h-14 min-w-14 items-center justify-center rounded-xl px-3 font-mono text-sm font-black ring-1 ${c.has(d)?"bg-rose-500/20 text-rose-200 ring-rose-500/50":"bg-slate-800/70 text-slate-200 ring-slate-700/50"}`,children:[e,t.jsx("span",{className:"absolute -bottom-5 text-[9px] text-slate-500",children:l==="fenwick-tree"?d+1:d})]},`${e}-${d}`))}),i?.queryRange&&t.jsxs("p",{className:"text-center text-xs text-slate-400",children:["Active range: [",i.queryRange[0],", ",i.queryRange[1],"]"]})]})}function R(i,l){return i==="trie"?_(l):i==="segment-tree"?G(l):H(l)}function M(i){return i.split(",").map(l=>l.trim()).filter(Boolean).map(Number).filter(Number.isFinite)}function _(i){const[l="",p="prefix",c=""]=i.split(";"),e=l.split(",").map(n=>n.trim().toLowerCase()).filter(Boolean),d=p.trim().toLowerCase(),o=c.trim().toLowerCase(),x=[];T=0;const h=A("*"),f=d==="insert"&&o?[...e,o]:e.filter(n=>!(d==="delete"&&n===o));if(e.forEach(n=>q(h,n)),x.push({description:`Build trie from ${e.length} word(s).`,event:"insert",nodes:v(h),meta:e}),d==="insert"&&o)q(h,o),x.push({description:`Insert "${o}" character by character.`,event:"insert",nodes:v(h),meta:f});else if(d==="delete"&&o){const n=A("*");f.forEach(s=>q(n,s)),x.push({description:`Delete "${o}" and rebuild active prefixes.`,event:"delete",nodes:v(n),meta:f})}else{let n=h;const s=[0];for(const r of o){if(n=n.children.get(r),!n)return x.push({description:`Character "${r}" is missing, so "${o}" was not found.`,event:"not-found",nodes:v(h),highlights:s,meta:e}),x;s.push(n.order),x.push({description:`Traverse character "${r}" in "${o}".`,event:"traverse",nodes:v(h),highlights:[...s],meta:e})}const a=e.filter(r=>d==="search"?r===o:r.startsWith(o));x.push({description:a.length?`Matched: ${a.join(", ")}.`:`No match for "${o}".`,event:a.length?"found":"not-found",nodes:v(h),highlights:s,meta:a})}return x}let T=0;function A(i){return{label:i,order:T++,terminal:!1,children:new Map}}function q(i,l){let p=i;for(const c of l)p.children.has(c)||p.children.set(c,A(c)),p=p.children.get(c);p.terminal=!0}function v(i){const l=[],p=new Map,c=(e,d,o)=>{const x=p.get(d)??[];x.push(e),p.set(d,x),l.push({id:`trie-${e.order}`,label:e.terminal?`${e.label}*`:e.label,x:0,y:d*72+42,parentId:o}),[...e.children.values()].forEach(h=>c(h,d+1,`trie-${e.order}`))};return c(i,0),l.forEach(e=>{const d=Math.round((e.y-42)/72),o=l.filter(h=>Math.round((h.y-42)/72)===d),x=o.indexOf(e);e.x=360+(x-(o.length-1)/2)*Math.max(46,520/Math.max(o.length,1))}),l}function G(i){const[l="",p="query",c="0,0"]=i.split(";"),e=M(l),d=p.trim(),o=M(c),x=Array(e.length*4).fill(0),h=[],f=(n,s,a)=>{if(s===a)x[n]=e[s];else{const r=Math.floor((s+a)/2);f(n*2,s,r),f(n*2+1,r+1,a),x[n]=x[n*2]+x[n*2+1]}h.push({description:`Build segment [${s}, ${a}] with sum ${x[n]}.`,event:"insert",array:[...e],highlights:S(s,a),queryRange:[s,a],meta:[`node:${n}`,`sum:${x[n]}`]})};if(e.length&&f(1,0,e.length-1),d==="query"){const[n,s]=o,a=Math.max(0,Math.min(e.length-1,n??0)),r=Math.max(a,Math.min(e.length-1,s??e.length-1)),w=(y,b,m)=>{if(h.push({description:`Visit segment [${b}, ${m}] for query [${a}, ${r}].`,event:"traverse",array:[...e],highlights:S(Math.max(b,a),Math.min(m,r)),queryRange:[a,r],meta:[`node:${y}`]}),r=0&&n{for(let r=s+1;r<=e.length;r+=r&-r)d[r]+=a,o.push({description:`Update BIT[${r}] += ${a}; next index is i + lowbit(i).`,event:"insert",array:d.slice(1),highlights:[r-1],meta:[`lowbit:${r&-r}`]})};e.forEach((s,a)=>x(a,s));const h=s=>{let a=0;for(let r=s+1;r>0;r-=r&-r)a+=d[r],o.push({description:`Read BIT[${r}] while computing prefix(${s}); next index is i - lowbit(i).`,event:"traverse",array:d.slice(1),highlights:[r-1],meta:[`partial:${a}`,`lowbit:${r&-r}`]});return a},f=p.trim(),n=M(c);if(f==="prefix"){const s=Math.max(0,Math.min(e.length-1,(n[0]??1)-1)),a=h(s);o.push({description:`Prefix sum up to position ${s+1} = ${a}.`,event:"found",array:d.slice(1),highlights:[s],meta:[`sum:${a}`]})}else if(f==="update"){const s=Math.max(0,Math.min(e.length-1,(n[0]??1)-1)),a=n[1]??e[s]??0;s>=0&&s0?h(s-1):0);o.push({description:`Range sum positions [${s+1}, ${a+1}] = ${r}.`,event:"found",array:d.slice(1),highlights:S(s,a),queryRange:[s+1,a+1],meta:[`sum:${r}`]})}return o}function S(i,l){return li+c)}function J(i){if(i==="trie")return"tree,trie,trial,algo,all,also;prefix;tr";const l=Array.from({length:6},()=>Math.floor(Math.random()*9)+1).join(",");return i==="segment-tree"?`${l};query;1,4`:`${l};range;1,4`}export{re as default}; diff --git a/docs/assets/AlgorithmCodePanel-DWTIRULe.js b/docs/assets/AlgorithmCodePanel-DWTIRULe.js new file mode 100644 index 0000000..ea1fe1d --- /dev/null +++ b/docs/assets/AlgorithmCodePanel-DWTIRULe.js @@ -0,0 +1 @@ +import{r,j as a,C as b}from"./index-BfWfBQOp.js";import{g as f}from"./audioContext-NbgqvQGz.js";const h=[220,261.63,293.66,329.63,392,440,523.25,659.25,783.99];function T(){const l=r.useRef(!0),[i,x]=r.useState(!0),u=r.useCallback(()=>f(),[]),e=r.useCallback((s,c=.08,g="sine",m=.04)=>{if(!l.current)return;const t=u();if(!t)return;const n=t.createOscillator(),p=t.createGain();n.type=g,n.frequency.setValueAtTime(s,t.currentTime),p.gain.setValueAtTime(m,t.currentTime),p.gain.exponentialRampToValueAtTime(.001,t.currentTime+c),n.connect(p),p.connect(t.destination),n.start(t.currentTime),n.stop(t.currentTime+c)},[u]),d=r.useCallback((s,c=0,g=1)=>{const m=h[Math.max(0,Math.min(h.length-1,Math.floor(c/Math.max(g-1,1)*(h.length-1))))];switch(s){case"compare":e(m,.055,"sine",.025);break;case"swap":e(329.63,.07,"square",.025),setTimeout(()=>e(523.25,.07,"square",.025),45);break;case"visit":case"enqueue":case"dequeue":e(m,.065,"triangle",.03);break;case"push":e(440,.08,"triangle",.035);break;case"pop":e(293.66,.08,"triangle",.035);break;case"recurse":e(392+c*24,.07,"sine",.03);break;case"found":[523.25,659.25,783.99].forEach((t,n)=>setTimeout(()=>e(t,.1,"sine",.045),n*70));break;case"not-found":e(185,.16,"sawtooth",.035);break;case"complete":[392,523.25,659.25,783.99].forEach((t,n)=>setTimeout(()=>e(t,.11,"sine",.045),n*75));break}},[e]),o=r.useCallback(s=>{l.current=s,x(s)},[]);return{soundEnabled:i,toggleSound:o,playEvent:d}}function C({pseudocode:l,activeLine:i=null,title:x="Code",language:u="pseudocode"}){const e=r.useRef(null);return r.useEffect(()=>{e.current?.scrollIntoView({block:"nearest",behavior:"smooth"})},[i]),a.jsxs("section",{className:"rounded-2xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[a.jsxs("div",{className:"mb-3 flex items-center justify-between",children:[a.jsxs("h3",{className:"inline-flex items-center gap-1.5 text-xs font-semibold uppercase tracking-wider text-slate-400",children:[a.jsx(b,{size:13,className:"text-indigo-400"})," ",x]}),a.jsx("span",{className:"rounded-full bg-slate-800/70 px-2 py-0.5 font-mono text-[9px] uppercase tracking-wide text-slate-500",children:u})]}),a.jsx("div",{className:"max-h-[420px] overflow-auto rounded-xl bg-slate-950/70 p-2 ring-1 ring-slate-800/70",children:a.jsx("pre",{className:"font-mono text-[11px] leading-relaxed",children:l.map((d,o)=>{const s=o===i;return a.jsxs("div",{ref:s?e:null,className:`flex gap-3 rounded-md px-2 py-0.5 transition-all duration-300 ${s?"bg-indigo-500/20 text-indigo-100 ring-1 ring-indigo-500/40":"text-slate-400"}`,children:[a.jsx("span",{className:`select-none text-right tabular-nums ${s?"text-indigo-300":"text-slate-600"}`,style:{minWidth:"1.6rem"},children:o+1}),a.jsx("span",{className:"whitespace-pre",children:d.length?d:" "})]},o)})})})]})}export{C as A,T as u}; diff --git a/docs/assets/AlgorithmPlaygroundPage-BZcoKA4I.js b/docs/assets/AlgorithmPlaygroundPage-BZcoKA4I.js new file mode 100644 index 0000000..1369467 --- /dev/null +++ b/docs/assets/AlgorithmPlaygroundPage-BZcoKA4I.js @@ -0,0 +1 @@ +import{r as b,j as i}from"./index-BfWfBQOp.js";import{u as M,A as C}from"./AlgorithmCodePanel-DWTIRULe.js";import{S as F}from"./shuffle-Ri9xSsK2.js";import{C as I,a as z}from"./chevron-right-CNA9GG_w.js";import{P as R}from"./play-WRQgdyAG.js";import{R as A}from"./rotate-ccw-EKzY5q_W.js";import{V as P,a as E}from"./volume-x-ChIHiT28.js";import"./audioContext-NbgqvQGz.js";const T={"binary-search":{title:"Binary Search",subtitle:"Search a sorted array in logarithmic time",inputLabel:"Sorted numbers; target",defaultInput:"2,5,8,12,16,23,38,56,72;23",helper:"Format: sorted comma-separated numbers; target",pseudocode:["function binarySearch(arr, target):"," low = 0; high = arr.length - 1"," while low <= high:"," mid = (low + high) / 2"," if arr[mid] == target: return mid"," if arr[mid] < target: low = mid + 1"," else: high = mid - 1"," return -1 // not found"]},"ternary-search":{title:"Ternary Search",subtitle:"Split a sorted search range into thirds",inputLabel:"Sorted numbers; target",defaultInput:"1,4,8,11,15,19,23,27,31,35,39;31",helper:"Format: sorted comma-separated numbers; target",pseudocode:["function ternarySearch(arr, target):"," low = 0; high = arr.length - 1"," while low <= high:"," mid1 = low + (high - low) / 3"," mid2 = high - (high - low) / 3"," if arr[mid1] == target: return mid1"," if arr[mid2] == target: return mid2"," if target < arr[mid1]: high = mid1 - 1"," elif target > arr[mid2]: low = mid2 + 1"," else: low = mid1 + 1; high = mid2 - 1"," return -1 // not found"]},"dutch-national-flag":{title:"Sort Colors",subtitle:"Dutch national flag partitioning",inputLabel:"Colors as 0, 1, 2",defaultInput:"2,0,2,1,1,0,2,0,1",helper:"Use only 0, 1, and 2.",pseudocode:["function sortColors(arr):"," low = 0; mid = 0; high = arr.length - 1"," while mid <= high:"," if arr[mid] == 0:"," swap(arr[low], arr[mid]); low++; mid++"," elif arr[mid] == 1:"," mid++"," else: // arr[mid] == 2"," swap(arr[mid], arr[high]); high--"," return arr"]},"top-k-frequent":{title:"Top K Frequent Elements",subtitle:"Count, rank, and extract frequent values",inputLabel:"Numbers; k",defaultInput:"1,1,1,2,2,3,3,3,3,4,5,5;3",helper:"Format: comma-separated numbers; k",pseudocode:["function topKFrequent(arr, k):"," counts = {}"," for value in arr:"," counts[value] += 1 // tally frequency"," ranked = sortByCountDescending(counts)"," return ranked[0 .. k]"]},"queue-using-stacks":{title:"Queue Using Two Stacks",subtitle:"Build FIFO behavior from LIFO stacks",inputLabel:"Enqueue values",defaultInput:"10,20,30,40",helper:"Values are enqueued, then all are dequeued.",pseudocode:["enqueue(x):"," input.push(x)","","dequeue():"," if output.isEmpty():"," while not input.isEmpty():"," output.push(input.pop()) // reverse order"," return output.pop()"]},"stack-using-queues":{title:"Stack Using Two Queues",subtitle:"Build LIFO behavior from FIFO queues",inputLabel:"Push values",defaultInput:"10,20,30,40",helper:"Values are pushed, then all are popped.",pseudocode:["push(x):"," helper.enqueue(x)"," while not primary.isEmpty():"," helper.enqueue(primary.dequeue())"," swap(primary, helper) // x now at front","","pop():"," return primary.dequeue()"]},"tower-of-hanoi":{title:"Tower of Hanoi",subtitle:"Recursive disk movement",inputLabel:"Disk count",defaultInput:"4",helper:"Use 2 to 5 disks for readable playback.",pseudocode:["function hanoi(n, from, to, aux):"," if n == 0: return"," hanoi(n - 1, from, aux, to) // move top n-1 aside"," move disk n: from -> to"," hanoi(n - 1, aux, to, from) // move them onto target"]},"rat-maze":{title:"Rat in a Maze",subtitle:"Recursive DFS and BFS on blocked cells",inputLabel:"Mode",defaultInput:"dfs",helper:"Use dfs or bfs. The maze is generated in the visualizer.",pseudocode:["function solve(grid, mode):"," frontier = [start]; visited = {start}"," while frontier not empty:"," cell = mode == DFS ? frontier.pop() : frontier.shift()"," if cell == target: break"," for n in freeNeighbors(cell):"," if n not visited:"," visited.add(n); parent[n] = cell"," frontier.push(n)"," return reconstructPath(parent, target)"]},"grid-search":{title:"Grid Search",subtitle:"Search allowed positions from source to target",inputLabel:"Mode",defaultInput:"bfs",helper:"Use bfs or dfs over free/occupied grid cells.",pseudocode:["function search(grid, mode):"," frontier = [start]; visited = {start}"," while frontier not empty:"," cell = mode == DFS ? frontier.pop() : frontier.shift()"," if cell == target: break"," for n in freeNeighbors(cell):"," if n not visited:"," visited.add(n); parent[n] = cell"," frontier.push(n)"," return reconstructPath(parent, target)"]}};function le({demo:a}){const n=T[a],[e,o]=b.useState(n.defaultInput),[s,t]=b.useState(()=>j(a,n.defaultInput)),[r,l]=b.useState(0),[d,u]=b.useState(800),{soundEnabled:p,toggleSound:g,playEvent:h}=M(),m=s[r]??s[0],$=s.length>0?(r+1)/s.length*100:0,S=()=>{const c=j(a,e);t(c),l(0),h(c[0]?.event??"visit",0,c.length)},L=()=>{const c=Z(a);o(c);const f=j(a,c);t(f),l(0)},w=c=>{const f=Math.max(0,Math.min(s.length-1,c));l(f);const y=s[f];y&&h(y.event,f,s.length)},q=()=>{for(let c=r;c{l(c);const f=s[c];f&&h(f.event,c,s.length)},(c-r)*d)};return i.jsxs("div",{className:"flex flex-1 flex-col gap-4 overflow-auto p-4 md:p-6 xl:flex-row",children:[i.jsxs("main",{className:"order-last flex min-h-[520px] flex-1 flex-col gap-4 xl:order-first",children:[i.jsxs("section",{className:"rounded-2xl border border-slate-700/50 bg-slate-900/60 p-5 backdrop-blur-sm",children:[i.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-[0.24em] text-indigo-300",children:"Algorithms"}),i.jsx("h2",{className:"mt-1 text-xl font-bold text-white",children:n.title}),i.jsx("p",{className:"mt-1 text-sm text-slate-400",children:n.subtitle})]}),i.jsx(D,{step:m,demo:a}),i.jsx(C,{pseudocode:n.pseudocode,activeLine:m?.codeLine??null})]}),i.jsxs("aside",{className:"w-full space-y-4 xl:w-80 xl:shrink-0",children:[i.jsxs("section",{className:"rounded-2xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[i.jsx("h3",{className:"mb-3 text-xs font-semibold uppercase tracking-wider text-slate-400",children:"Input"}),i.jsx("label",{className:"text-[11px] text-slate-500",children:n.inputLabel}),i.jsx("textarea",{value:e,onChange:c=>o(c.target.value),rows:2,className:"mt-1 w-full resize-none rounded-xl bg-slate-950/70 px-3 py-2 text-xs font-mono text-slate-200 ring-1 ring-slate-700/50 outline-none focus:ring-indigo-500/50"}),i.jsx("p",{className:"mt-2 text-[10px] leading-relaxed text-slate-500",children:n.helper}),i.jsxs("div",{className:"mt-3 grid grid-cols-2 gap-2",children:[i.jsx("button",{onClick:S,className:"rounded-xl bg-indigo-500/20 px-3 py-2 text-xs font-semibold text-indigo-300 ring-1 ring-indigo-500/40 hover:bg-indigo-500/30",children:"Run"}),i.jsxs("button",{onClick:L,className:"inline-flex items-center justify-center gap-1 rounded-xl bg-slate-800/70 px-3 py-2 text-xs font-semibold text-slate-300 ring-1 ring-slate-700/50 hover:bg-slate-700/70",children:[i.jsx(F,{size:13})," Random"]})]})]}),i.jsxs("section",{className:"rounded-2xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[i.jsxs("div",{className:"mb-3 flex items-center justify-between",children:[i.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400",children:"Step Playback"}),i.jsxs("span",{className:"font-mono text-xs text-indigo-300",children:[Math.min(r+1,s.length)," / ",s.length]})]}),i.jsx("div",{className:"h-2 overflow-hidden rounded-full bg-slate-800",children:i.jsx("div",{className:"h-full rounded-full bg-indigo-400 transition-all",style:{width:`${$}%`}})}),i.jsxs("div",{className:"mt-3 rounded-xl border border-slate-700/40 bg-slate-950/40 p-3",children:[i.jsxs("div",{className:"mb-2 flex items-center justify-between",children:[i.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-wider text-slate-500",children:"Animation Speed"}),i.jsxs("span",{className:"font-mono text-[10px] text-indigo-300",children:[(d/1e3).toFixed(2),"s"]})]}),i.jsx("input",{type:"range",min:120,max:3e3,step:20,value:d,onChange:c=>u(Number(c.target.value)),className:"w-full accent-indigo-400","aria-label":"Animation step delay"}),i.jsxs("div",{className:"mt-1 flex justify-between text-[9px] uppercase tracking-wide text-slate-600",children:[i.jsx("span",{children:"Fast"}),i.jsx("span",{children:"Slow"})]})]}),i.jsx("p",{className:"mt-3 min-h-12 text-xs leading-relaxed text-slate-300",children:m?.description}),m?.meta&&i.jsx("div",{className:"mt-2 flex flex-wrap gap-1",children:m.meta.map(c=>i.jsx("span",{className:"rounded-full bg-slate-800/80 px-2 py-0.5 text-[10px] font-mono text-slate-400",children:c},c))}),i.jsxs("div",{className:"mt-3 grid grid-cols-3 gap-2",children:[i.jsxs("button",{onClick:()=>w(r-1),disabled:r<=0,className:"inline-flex items-center justify-center gap-1 rounded-xl bg-slate-800/70 px-2 py-2 text-xs text-slate-300 ring-1 ring-slate-700/50 disabled:opacity-30",children:[i.jsx(I,{size:13})," Back"]}),i.jsxs("button",{onClick:q,disabled:r>=s.length-1,className:"inline-flex items-center justify-center gap-1 rounded-xl bg-emerald-500/15 px-2 py-2 text-xs font-semibold text-emerald-300 ring-1 ring-emerald-500/30 disabled:opacity-30",children:[i.jsx(R,{size:13})," Play"]}),i.jsxs("button",{onClick:()=>w(r+1),disabled:r>=s.length-1,className:"inline-flex items-center justify-center gap-1 rounded-xl bg-slate-800/70 px-2 py-2 text-xs text-slate-300 ring-1 ring-slate-700/50 disabled:opacity-30",children:["Next ",i.jsx(z,{size:13})]})]}),i.jsxs("button",{onClick:()=>w(0),className:"mt-2 inline-flex w-full items-center justify-center gap-1 rounded-xl bg-slate-800/70 px-3 py-2 text-xs text-slate-300 ring-1 ring-slate-700/50 hover:bg-slate-700/70",children:[i.jsx(A,{size:13})," Reset Steps"]})]}),i.jsx("section",{className:"rounded-2xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:i.jsxs("button",{onClick:()=>g(!p),className:`inline-flex w-full items-center justify-center gap-2 rounded-xl px-3 py-2 text-xs font-semibold ring-1 ${p?"bg-indigo-500/15 text-indigo-300 ring-indigo-500/30":"bg-slate-800/70 text-slate-400 ring-slate-700/40"}`,children:[p?i.jsx(P,{size:14}):i.jsx(E,{size:14}),p?"Sound On":"Sound Off"]})})]})]})}function D({step:a,demo:n}){return a?a.grid?i.jsx(B,{step:a}):a.pegs?i.jsx(U,{pegs:a.pegs}):a.stacks||a.queues?i.jsx(O,{step:a}):i.jsx(V,{step:a,demo:n}):null}function V({step:a,demo:n}){const e=a.values??[],o=new Set(a.highlights??[]),s=(t,r)=>n==="dutch-national-flag"?t===0?"bg-sky-500/25 text-sky-200 ring-sky-500/40":t===1?"bg-white/15 text-white ring-white/30":"bg-rose-500/25 text-rose-200 ring-rose-500/40":o.has(r)?"bg-indigo-500/25 text-indigo-200 ring-indigo-500/50":"bg-slate-800/70 text-slate-200 ring-slate-700/50";return i.jsx("section",{className:"flex flex-1 flex-col items-center justify-center rounded-2xl border border-slate-700/50 bg-slate-950/60 p-5",children:i.jsx("div",{className:"flex max-w-full flex-wrap items-end justify-center gap-2",children:e.map((t,r)=>i.jsxs("div",{className:`relative flex h-16 min-w-12 items-center justify-center rounded-xl px-3 font-mono text-sm font-black ring-1 transition-all ${s(t,r)}`,children:[t,Object.entries(a.pointers??{}).filter(([,l])=>l===r).map(([l])=>i.jsx("span",{className:"absolute -bottom-5 text-[9px] uppercase tracking-wide text-amber-300",children:l},l))]},`${t}-${r}`))})})}function O({step:a}){const n=a.stacks??a.queues??{};return i.jsx("section",{className:"grid flex-1 gap-4 rounded-2xl border border-slate-700/50 bg-slate-950/60 p-5 md:grid-cols-2",children:Object.entries(n).map(([e,o])=>i.jsxs("div",{className:"flex flex-col justify-end rounded-xl bg-slate-900/70 p-4 ring-1 ring-slate-700/50",children:[i.jsx("h3",{className:"mb-3 text-xs font-semibold uppercase tracking-wider text-slate-400",children:e}),i.jsx("div",{className:"flex min-h-64 flex-col-reverse gap-2",children:o.map((s,t)=>i.jsx("div",{className:"rounded-lg bg-indigo-500/15 px-3 py-2 text-center font-mono text-sm font-bold text-indigo-200 ring-1 ring-indigo-500/30",children:s},`${e}-${s}-${t}`))})]},e))})}function U({pegs:a}){return i.jsx("section",{className:"grid flex-1 items-end gap-4 rounded-2xl border border-slate-700/50 bg-slate-950/60 p-5 md:grid-cols-3",children:a.map((n,e)=>i.jsxs("div",{className:"relative flex h-72 flex-col-reverse items-center justify-start gap-1 rounded-xl bg-slate-900/70 p-4 ring-1 ring-slate-700/50",children:[i.jsx("div",{className:"absolute bottom-4 h-56 w-2 rounded-full bg-slate-700"}),n.map(o=>i.jsx("div",{className:"z-10 h-6 rounded-md bg-gradient-to-r from-cyan-500 to-indigo-500 ring-1 ring-cyan-300/40",style:{width:`${o*34+34}px`}},`${e}-${o}`)),i.jsxs("span",{className:"absolute bottom-0 text-[10px] font-mono text-slate-500",children:["Peg ",e+1]})]},e))})}function B({step:a}){const n=new Set(a.visited??[]),e=new Set(a.path??[]);return i.jsx("section",{className:"flex flex-1 items-center justify-center rounded-2xl border border-slate-700/50 bg-slate-950/60 p-5",children:i.jsx("div",{className:"grid gap-1",style:{gridTemplateColumns:`repeat(${a.grid?.[0]?.length??0}, minmax(0, 1fr))`},children:a.grid?.flatMap((o,s)=>o.map((t,r)=>{const l=s*o.length+r,d=e.has(l),u=n.has(l),p=l===0,g=l===o.length*(a.grid?.length??1)-1,h=t===1?"bg-slate-800 ring-slate-700":d?"bg-emerald-400 ring-emerald-200":p?"bg-sky-400 ring-sky-200":g?"bg-orange-400 ring-orange-200":u?"bg-indigo-500/70 ring-indigo-300":"bg-slate-900 ring-slate-700";return i.jsx("div",{className:`h-9 w-9 rounded-md ring-1 ${h}`},l)}))})})}function j(a,n){switch(a){case"binary-search":return G(n);case"ternary-search":return _(n);case"dutch-national-flag":return K(n);case"top-k-frequent":return Q(n);case"queue-using-stacks":return H(n);case"stack-using-queues":return X(n);case"tower-of-hanoi":return J(n);case"rat-maze":return k(n,!0);case"grid-search":return k(n,!1);default:return[]}}function x(a){return a.split(",").map(n=>n.trim()).filter(Boolean).map(Number).filter(Number.isFinite)}function N(a){const[n,e]=a.split(";");return{values:x(n??"").sort((o,s)=>o-s),target:Number(e)}}function G(a){const{values:n,target:e}=N(a),o=[];let s=0,t=n.length-1;for(;s<=t;){const r=Math.floor((s+t)/2);if(o.push({description:`Compare target ${e} with middle value ${n[r]} at index ${r}.`,event:"compare",values:n,highlights:[r],pointers:{low:s,mid:r,high:t},codeLine:4}),n[r]===e)return o.push({description:`Found ${e} at index ${r}.`,event:"found",values:n,highlights:[r],pointers:{low:s,mid:r,high:t},codeLine:4}),o;n[r]n[d]?s=d+1:(s=l+1,t=d-1)}return[...o,{description:`${e} is not present in the sorted array.`,event:"not-found",values:n,codeLine:10}]}function K(a){const e=[...x(a).filter(l=>l===0||l===1||l===2)],o=[{description:"Start with low, mid, and high pointers.",event:"visit",values:[...e],pointers:{low:0,mid:0,high:e.length-1},codeLine:1}];let s=0,t=0,r=e.length-1;for(;t<=r;)e[t]===0?([e[s],e[t]]=[e[t],e[s]],o.push({description:`Swap 0 at mid ${t} with low ${s}.`,event:"swap",values:[...e],highlights:[s,t],pointers:{low:s,mid:t,high:r},codeLine:4}),s+=1,t+=1):e[t]===1?(o.push({description:`Value 1 at mid ${t} is already in the middle partition.`,event:"compare",values:[...e],highlights:[t],pointers:{low:s,mid:t,high:r},codeLine:6}),t+=1):([e[t],e[r]]=[e[r],e[t]],o.push({description:`Swap 2 at mid ${t} with high ${r}.`,event:"swap",values:[...e],highlights:[t,r],pointers:{low:s,mid:t,high:r},codeLine:8}),r-=1);return[...o,{description:"Colors are sorted: all 0s, then 1s, then 2s.",event:"complete",values:[...e],codeLine:9}]}function Q(a){const[n,e]=a.split(";"),o=x(n??""),s=Math.max(1,Number(e)||3),t=new Map,r=[];o.forEach((d,u)=>{t.set(d,(t.get(d)??0)+1),r.push({description:`Count ${d}: frequency is now ${t.get(d)}.`,event:"visit",values:o,highlights:[u],meta:[...t.entries()].map(([p,g])=>`${p}:${g}`),codeLine:3})});const l=[...t.entries()].sort((d,u)=>u[1]-d[1]).map(([d])=>d);return[...r,{description:`Top ${s} frequent elements: ${l.slice(0,s).join(", ")}.`,event:"complete",values:l,highlights:l.slice(0,s).map((d,u)=>u),meta:[...t.entries()].map(([d,u])=>`${d}:${u}`),codeLine:5}]}function H(a){const n=x(a),e=[],o=[],s=[];for(n.forEach(t=>{e.push(t),s.push({description:`Enqueue ${t}: push onto input stack.`,event:"push",stacks:{input:[...e],output:[...o]},codeLine:1})});e.length>0;){const t=e.pop();o.push(t),s.push({description:`Move ${t} from input to output stack to expose queue front.`,event:"pop",stacks:{input:[...e],output:[...o]},codeLine:6})}for(;o.length>0;){const t=o.pop();s.push({description:`Dequeue ${t} from output stack.`,event:"dequeue",stacks:{input:[...e],output:[...o]},codeLine:7})}return s}function X(a){const n=x(a);let e=[],o=[];const s=[];for(n.forEach(t=>{for(o.push(t),s.push({description:`Push ${t}: enqueue into helper queue.`,event:"enqueue",queues:{primary:[...e],helper:[...o]},codeLine:1});e.length>0;)o.push(e.shift());[e,o]=[o,[]],s.push({description:`Rotate queues so ${t} becomes the next pop.`,event:"visit",queues:{primary:[...e],helper:[...o]},codeLine:4})});e.length>0;){const t=e.shift();s.push({description:`Pop ${t} from primary queue front.`,event:"dequeue",queues:{primary:[...e],helper:[...o]},codeLine:7})}return s}function J(a){const n=Math.max(2,Math.min(5,Number(a)||4)),e=[Array.from({length:n},(t,r)=>n-r),[],[]],o=[{description:`Start with ${n} disks on peg 1.`,event:"recurse",pegs:v(e),codeLine:0}],s=(t,r,l,d)=>{if(t===0)return;o.push({description:`Solve subproblem: move ${t-1} disk(s) from peg ${r+1} to peg ${d+1}.`,event:"recurse",pegs:v(e),codeLine:2}),s(t-1,r,d,l);const u=e[r].pop();u&&e[l].push(u),o.push({description:`Move disk ${u} from peg ${r+1} to peg ${l+1}.`,event:"visit",pegs:v(e),codeLine:3}),s(t-1,d,l,r)};return s(n,0,2,1),[...o,{description:"Tower complete.",event:"complete",pegs:v(e),codeLine:4}]}function v(a){return a.map(n=>[...n])}const W=[[0,0,0,1,0,0,0],[1,1,0,1,0,1,0],[0,0,0,0,0,1,0],[0,1,1,1,0,0,0],[0,0,0,1,1,1,0],[0,1,0,0,0,0,0]];function k(a,n){const e=a.trim().toLowerCase()==="dfs"?"dfs":"bfs",o=W.map(h=>[...h]),s=o[0].length,t=o.length*s-1,r=new Set,l=new Map,d=[],u=[0];for(r.add(0);u.length>0;){const h=e==="dfs"?u.pop():u.shift();if(d.push({description:`${n?"Rat maze":"Grid search"} ${e.toUpperCase()}: visit cell (${Math.floor(h/s)}, ${h%s}).`,event:e==="dfs"?"recurse":"visit",grid:o,visited:[...r],path:[h],codeLine:3}),h===t)break;for(const m of Y(h,o))r.has(m)||(r.add(m),l.set(m,h),u.push(m),d.push({description:`Add allowed neighbor (${Math.floor(m/s)}, ${m%s}) to ${e==="dfs"?"stack":"queue"}.`,event:e==="dfs"?"push":"enqueue",grid:o,visited:[...r],path:[m],codeLine:8}))}const p=[];let g=t;for(;g!==void 0&&(g===0||l.has(g))&&(p.unshift(g),g!==0);)g=l.get(g);return[...d,{description:p[0]===0?`Found path with ${p.length} cells.`:"No path found.",event:p[0]===0?"found":"not-found",grid:o,visited:[...r],path:p,codeLine:9}]}function Y(a,n){const e=n[0].length,o=Math.floor(a/e),s=a%e;return[[o-1,s],[o+1,s],[o,s-1],[o,s+1]].filter(([t,r])=>t>=0&&r>=0&&tt*e+r)}function Z(a){const n=Array.from({length:9},()=>Math.floor(Math.random()*40)+1);switch(a){case"binary-search":case"ternary-search":{const e=[...n].sort((t,r)=>t-r),o=Math.floor(e.length/2);let s=Math.floor(Math.random()*e.length);return a==="binary-search"&&e.length>1&&s===o&&(s=(s+1)%e.length),`${e.join(",")};${e[s]}`}case"dutch-national-flag":return Array.from({length:10},()=>Math.floor(Math.random()*3)).join(",");case"top-k-frequent":return`${Array.from({length:12},()=>Math.floor(Math.random()*5)+1).join(",")};3`;case"tower-of-hanoi":return String(Math.floor(Math.random()*3)+3);case"rat-maze":return Math.random()>.5?"dfs":"bfs";case"grid-search":return Math.random()>.5?"dfs":"bfs";default:return n.slice(0,4).join(",")}}export{le as default}; diff --git a/docs/assets/ArrayPage-BVw3oj1M.js b/docs/assets/ArrayPage-BVw3oj1M.js new file mode 100644 index 0000000..6c6c960 --- /dev/null +++ b/docs/assets/ArrayPage-BVw3oj1M.js @@ -0,0 +1,5 @@ +import{c as te,r as a,j as e,e as se}from"./index-BfWfBQOp.js";import{u as le}from"./useDSSound-BMrOIkPj.js";import{P as F}from"./plus-BEk43_MF.js";import{T as ae}from"./trash-2-RJG3j28z.js";import{R as ne}from"./rotate-ccw-EKzY5q_W.js";import{S as re}from"./shuffle-Ri9xSsK2.js";import{V as ie,a as oe}from"./volume-x-ChIHiT28.js";import{C as ce,a as de}from"./chevron-right-CNA9GG_w.js";import"./audioContext-NbgqvQGz.js";const he=[["path",{d:"M12.586 12.586 19 19",key:"ea5xo7"}],["path",{d:"M3.688 3.037a.497.497 0 0 0-.651.651l6.5 15.999a.501.501 0 0 0 .947-.062l1.569-6.083a2 2 0 0 1 1.448-1.479l6.124-1.579a.5.5 0 0 0 .063-.947z",key:"277e5u"}]],xe=te("mouse-pointer",he);let O=1;const ue=[4,2,7,1,9,3,6].map(h=>({id:O++,value:h}));function ge(){const[h,x]=a.useState(ue),[r,g]=a.useState([]),[i,c]=a.useState(-1),[p,k]=a.useState(""),[R,T]=a.useState(""),[D,z]=a.useState([]),[f,E]=a.useState(400),[S,N]=a.useState(!1),m=a.useRef(null),I=a.useRef(f),b=a.useRef(!1),{soundEnabled:L,toggleSound:_,playInsert:v,playDelete:w,playAccess:j,playTraverse:A,playFound:C,playNotFound:P}=le(),V=a.useRef(()=>{});a.useEffect(()=>{I.current=f},[f]),a.useEffect(()=>{if(!b.current||r.length===0)return;b.current=!1,m.current&&clearTimeout(m.current),N(!0);let t=0;const s=()=>{if(t>=r.length-1){N(!1);return}t++,c(t),V.current(t,r),m.current=setTimeout(s,I.current)};m.current=setTimeout(s,I.current)},[r]);const y=a.useCallback((t,s)=>{const n=s[t];n&&(n.highlightColor==="green"?C():n.highlightColor==="red"?w():n.highlightColor==="blue"?j():(n.highlightColor==="yellow"||n.highlightColor==="orange")&&A(t,s.length))},[C,w,j,A]);a.useEffect(()=>{V.current=y},[y]);const W=i>=0&&r[i]?r[i].array:h,l=i>=0?r[i]:null,u=t=>z(s=>[t,...s].slice(0,20)),G=a.useCallback(t=>{x(s=>{if(t<0||t>=s.length)return s;const n=[{description:`Access index ${t}: going to position ${t}...`,array:s,highlightIndices:[],highlightColor:null},{description:`Found value ${s[t].value} at index ${t}.`,array:s,highlightIndices:[t],highlightColor:"blue"}];return g(n),c(0),b.current=!0,j(),u(`Access [${t}] → ${s[t].value}`),s})},[j]),H=a.useCallback((t,s)=>{const n={id:O++,value:t};x(d=>{if(s<0||s>d.length)return d;const o=[];o.push({description:`Insert ${t} at index ${s}: shifting elements right from index ${s}...`,array:d,highlightIndices:Array.from({length:d.length-s},(M,ee)=>s+ee),highlightColor:"orange"});const $=[...d.slice(0,s),n,...d.slice(s)];return o.push({description:`${t} inserted at index ${s}. Array size: ${$.length}`,array:$,highlightIndices:[s],highlightColor:"green"}),g(o),c(0),b.current=!0,v(),u(`Insert ${t} at [${s}]`),$})},[v]),X=a.useCallback(t=>{x(s=>{if(t<0||t>=s.length)return s;const n=s[t].value,d=[{description:`Delete at index ${t}: marking element ${n} for removal...`,array:s,highlightIndices:[t],highlightColor:"red"},{description:"Shifting elements left to fill the gap...",array:s,highlightIndices:Array.from({length:s.length-t-1},($,M)=>t+1+M),highlightColor:"orange"}],o=s.filter(($,M)=>M!==t);return d.push({description:`${n} deleted. Array size: ${o.length}`,array:o,highlightIndices:[],highlightColor:null}),g(d),c(0),b.current=!0,w(),u(`Delete [${t}] → ${n}`),o})},[w]),q=a.useCallback(t=>{x(s=>{const n=[];let d=-1;for(let o=0;o{const s={id:O++,value:t};x(n=>{const d=[...n,s],o=[{description:`Appending ${t} to the end of the array...`,array:n,highlightIndices:[],highlightColor:null},{description:`${t} added at index ${n.length}. Array size: ${d.length}`,array:d,highlightIndices:[d.length-1],highlightColor:"green"}];return g(o),c(0),b.current=!0,v(),u(`Push ${t}`),d})},[v]),J=a.useCallback(()=>{x([]),g([]),c(-1),u("Clear array")},[]),K=a.useCallback(()=>{const t=Math.floor(Math.random()*5)+5,s=Array.from({length:t},()=>({id:O++,value:Math.floor(Math.random()*90)+1}));x(s),g([]),c(-1),u("Random array")},[]),Q=a.useCallback(()=>{c(t=>{const s=Math.min(t+1,r.length-1);return y(s,r),s})},[r,y]),U=a.useCallback(()=>{c(t=>Math.max(t-1,0))},[]),Z=a.useCallback(()=>{if(S){N(!1),m.current&&clearTimeout(m.current);return}if(i>=r.length-1)return;N(!0);let t=i;const s=()=>{if(t>=r.length-1){N(!1);return}t++,c(t),y(t,r),m.current=setTimeout(s,f)};m.current=setTimeout(s,f)},[S,i,r,f,y]);return{array:h,displayArray:W,steps:r,stepIndex:i,currentStep:l,inputValue:p,setInputValue:k,indexValue:R,setIndexValue:T,history:D,speed:f,setSpeed:E,isPlaying:S,access:G,insertAt:H,deleteAt:X,search:q,pushBack:Y,clear:J,generateRandom:K,nextStep:Q,prevStep:U,autoPlay:Z,soundEnabled:L,toggleSound:_,canGoNext:i0}}const me={green:"border-emerald-400 bg-emerald-500/20 text-emerald-300",red:"border-rose-400 bg-rose-500/20 text-rose-300",yellow:"border-amber-400 bg-amber-500/20 text-amber-300",blue:"border-blue-400 bg-blue-500/20 text-blue-300",orange:"border-orange-400 bg-orange-500/20 text-orange-300"},B=12;function pe({array:h,currentStep:x}){const r=h.slice(0,B),g=new Set(x?.highlightIndices??[]),i=x?.highlightColor??null;return e.jsxs("div",{className:"flex flex-col items-center justify-center w-full h-full min-h-[300px] gap-6 px-4",children:[e.jsxs("div",{className:"flex flex-col items-center gap-2",children:[h.length===0?e.jsx("div",{className:"flex items-center justify-center w-48 h-16 border-2 border-dashed border-slate-700 rounded-lg text-slate-600 text-xs",children:"Empty Array"}):e.jsxs("div",{className:"flex flex-wrap justify-center gap-1.5",children:[r.map((c,p)=>{const k=g.has(p);return e.jsxs("div",{className:"flex flex-col items-center gap-1",children:[e.jsx("div",{className:` + flex items-center justify-center rounded-lg border-2 w-12 h-12 md:w-14 md:h-14 font-bold text-sm md:text-base + transition-all duration-300 + ${k&&i?me[i]:"border-slate-600 bg-slate-800/60 text-slate-200"} + `,children:c.value}),e.jsxs("span",{className:"text-[10px] font-mono text-slate-600",children:["[",p,"]"]})]},c.id)}),h.length>B&&e.jsxs("div",{className:"flex flex-col items-center gap-1",children:[e.jsxs("div",{className:"flex items-center justify-center rounded-lg border-2 border-dashed border-slate-700 w-12 h-12 md:w-14 md:h-14 text-slate-600 text-xs",children:["+",h.length-B]}),e.jsx("span",{className:"text-[10px] font-mono text-slate-600",children:"..."})]})]}),h.length>0&&e.jsxs("div",{className:"flex items-center gap-1 text-slate-500 font-mono text-sm",children:[e.jsx("span",{children:"["}),e.jsxs("span",{className:"flex-1 text-center text-xs text-slate-600",children:["length = ",h.length]}),e.jsx("span",{children:"]"})]})]}),x?.description&&e.jsx("div",{className:"w-full max-w-sm rounded-lg bg-slate-800/60 px-4 py-2 text-center text-xs text-indigo-300 leading-relaxed",children:x.description})]})}const fe=[{label:"Slow",value:700},{label:"Med",value:350},{label:"Fast",value:120}];function be({hook:h}){const{array:x,steps:r,stepIndex:g,inputValue:i,setInputValue:c,indexValue:p,setIndexValue:k,history:R,speed:T,setSpeed:D,isPlaying:z,access:f,insertAt:E,deleteAt:S,search:N,pushBack:m,clear:I,generateRandom:b,nextStep:L,prevStep:_,canGoNext:v,canGoPrev:w,soundEnabled:j,toggleSound:A}=h,C=()=>{const l=parseInt(p);isNaN(l)||f(l)},P=()=>{const l=parseInt(i),u=parseInt(p);!isNaN(l)&&!isNaN(u)&&(E(l,u),c(""))},V=()=>{const l=parseInt(p);isNaN(l)||S(l)},y=()=>{const l=parseInt(i);isNaN(l)||N(l)},W=()=>{const l=parseInt(i);isNaN(l)||(m(l),c(""))};return e.jsxs("div",{className:"flex flex-col gap-4 w-full md:w-72 shrink-0 overflow-y-auto max-h-full pr-1",children:[e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-sm font-bold text-indigo-300 mb-1",children:"Array"}),e.jsxs("p",{className:"text-xs text-slate-400 leading-relaxed",children:["A contiguous block of memory. ",e.jsx("strong",{className:"text-slate-300",children:"Access"})," by index is O(1), but ",e.jsx("strong",{className:"text-slate-300",children:"insert/delete"})," requires shifting elements — O(n)."]}),e.jsx("div",{className:"mt-2 flex flex-wrap gap-1.5",children:["Access O(1)","Search O(n)","Insert O(n)","Delete O(n)"].map(l=>e.jsx("span",{className:"rounded-full bg-violet-500/10 px-2 py-0.5 text-[10px] font-medium text-violet-400 ring-1 ring-violet-500/20",children:l},l))})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Operations"}),e.jsxs("div",{className:"grid grid-cols-2 gap-2 mb-3",children:[e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("label",{className:"text-[10px] text-slate-500 uppercase tracking-wider",children:"Value"}),e.jsx("input",{type:"number",value:i,onChange:l=>c(l.target.value),placeholder:"e.g. 42",className:"w-full rounded-lg bg-slate-800/60 px-3 py-2 text-sm text-slate-200 placeholder-slate-600 outline-none ring-1 ring-slate-700/50 focus:ring-indigo-500/50 transition-all"})]}),e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("label",{className:"text-[10px] text-slate-500 uppercase tracking-wider",children:"Index"}),e.jsx("input",{type:"number",value:p,onChange:l=>k(l.target.value),placeholder:"e.g. 0",min:"0",className:"w-full rounded-lg bg-slate-800/60 px-3 py-2 text-sm text-slate-200 placeholder-slate-600 outline-none ring-1 ring-slate-700/50 focus:ring-indigo-500/50 transition-all"})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsxs("button",{onClick:C,className:"flex items-center justify-center gap-1.5 rounded-lg bg-blue-500/20 px-3 py-2 text-xs font-semibold text-blue-300 ring-1 ring-blue-500/30 transition-all hover:bg-blue-500/30 active:scale-[0.98]",children:[e.jsx(xe,{size:13})," Access"]}),e.jsxs("button",{onClick:y,className:"flex items-center justify-center gap-1.5 rounded-lg bg-amber-500/20 px-3 py-2 text-xs font-semibold text-amber-300 ring-1 ring-amber-500/30 transition-all hover:bg-amber-500/30 active:scale-[0.98]",children:[e.jsx(se,{size:13})," Search"]}),e.jsxs("button",{onClick:P,disabled:x.length>=12,className:"flex items-center justify-center gap-1.5 rounded-lg bg-gradient-to-r from-emerald-500/80 to-green-500/80 px-3 py-2 text-xs font-semibold text-white shadow-lg shadow-emerald-500/15 transition-all hover:brightness-110 active:scale-[0.98] disabled:opacity-40 disabled:cursor-not-allowed",children:[e.jsx(F,{size:13})," Insert"]}),e.jsxs("button",{onClick:V,disabled:x.length===0,className:"flex items-center justify-center gap-1.5 rounded-lg bg-gradient-to-r from-rose-500/80 to-pink-500/80 px-3 py-2 text-xs font-semibold text-white shadow-lg shadow-rose-500/15 transition-all hover:brightness-110 active:scale-[0.98] disabled:opacity-40 disabled:cursor-not-allowed",children:[e.jsx(ae,{size:13})," Delete"]}),e.jsxs("button",{onClick:W,disabled:x.length>=12,className:"flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-emerald-300 transition-all hover:bg-slate-700/60 disabled:opacity-40 disabled:cursor-not-allowed",children:[e.jsx(F,{size:13})," Push Back"]}),e.jsxs("button",{onClick:I,disabled:x.length===0,className:"flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-slate-400 transition-all hover:bg-slate-700/60 disabled:opacity-40 disabled:cursor-not-allowed",children:[e.jsx(ne,{size:13})," Clear"]})]}),e.jsxs("button",{onClick:b,className:"mt-2 w-full flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300",children:[e.jsx(re,{size:12})," Random Array"]}),e.jsxs("button",{onClick:()=>A(!j),className:`mt-2 w-full flex items-center justify-center gap-1.5 rounded-lg px-3 py-2 text-xs font-medium transition-all ${j?"bg-indigo-500/15 text-indigo-300 ring-1 ring-indigo-500/30":"bg-slate-800/60 text-slate-400 hover:bg-slate-700/60"}`,children:[j?e.jsx(ie,{size:12}):e.jsx(oe,{size:12}),j?"Sound On":"Sound Off"]})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Animation Speed"}),e.jsx("div",{className:"flex gap-1",children:fe.map(l=>e.jsx("button",{onClick:()=>D(l.value),className:`flex-1 rounded-lg px-2 py-1.5 text-xs font-medium transition-all duration-200 ${T===l.value?"bg-violet-500/20 text-violet-300 ring-1 ring-violet-500/40":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50 hover:text-slate-300"}`,children:l.label},l.value))})]}),r.length>0&&e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Step Through"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("button",{onClick:_,disabled:!w||z,className:"flex-1 flex items-center justify-center gap-1 rounded-lg bg-slate-800/60 px-3 py-2.5 text-sm font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300 disabled:opacity-30 disabled:cursor-not-allowed",children:[e.jsx(ce,{size:16})," Prev"]}),e.jsxs("button",{onClick:L,disabled:!v||z,className:"flex-1 flex items-center justify-center gap-1 rounded-lg bg-slate-800/60 px-3 py-2.5 text-sm font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300 disabled:opacity-30 disabled:cursor-not-allowed",children:["Next ",e.jsx(de,{size:16})]})]}),e.jsxs("div",{className:"mt-2 flex items-center justify-between",children:[e.jsx("span",{className:"text-xs text-slate-500",children:"Step"}),e.jsxs("span",{className:"text-sm font-mono font-semibold text-indigo-400",children:[Math.max(0,g+1)," / ",r.length]})]})]}),R.length>0&&e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"History"}),e.jsx("div",{className:"max-h-36 overflow-y-auto space-y-1",children:R.map((l,u)=>e.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[e.jsx("span",{className:"font-mono text-slate-600 w-4 text-right",children:u+1}),e.jsx("span",{className:l.startsWith("Insert")||l.startsWith("Push")?"text-emerald-400":l.startsWith("Delete")?"text-rose-400":l.startsWith("Search")?"text-amber-400":l.startsWith("Access")?"text-blue-400":"text-slate-400",children:l})]},u))})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Legend"}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-blue-500"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Access"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-amber-400"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Search scan"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-emerald-500"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Insert / found"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-rose-500"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Delete"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-orange-400"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Shift"})]})]})]})]})}function Ae(){const h=ge();return e.jsxs("div",{className:"flex flex-1 flex-col md:flex-row gap-4 md:gap-6 overflow-auto p-4 md:p-6",children:[e.jsx("div",{className:"order-last md:order-first flex md:flex-1 flex-col items-center justify-center gap-3 min-h-[40vh] md:min-h-0 max-h-[55vh] md:max-h-none overflow-hidden",children:e.jsx(pe,{array:h.displayArray,currentStep:h.currentStep})}),e.jsx(be,{hook:h})]})}export{Ae as default}; diff --git a/docs/assets/BalancedTreePage-BIWzF7Hd.js b/docs/assets/BalancedTreePage-BIWzF7Hd.js new file mode 100644 index 0000000..dbe880f --- /dev/null +++ b/docs/assets/BalancedTreePage-BIWzF7Hd.js @@ -0,0 +1,7 @@ +import{c as jt,r as p,j as a}from"./index-BfWfBQOp.js";import{P as Nt}from"./plus-BEk43_MF.js";import{S as wt}from"./shuffle-Ri9xSsK2.js";import{C as $t,a as yt}from"./chevron-right-CNA9GG_w.js";const kt=[["path",{d:"M5 12h14",key:"1ays0h"}]],It=jt("minus",kt);function K(t){return t?[t,...K(t.left),...K(t.right)]:[]}function X(t){if(!t)return[];const e=[];return t.left&&(e.push({from:t,to:t.left}),e.push(...X(t.left))),t.right&&(e.push({from:t,to:t.right}),e.push(...X(t.right))),e}function Rt({root:t,treeType:e,highlightIds:r}){const s=p.useMemo(()=>K(t),[t]),n=p.useMemo(()=>X(t),[t]);if(!t)return a.jsx("div",{className:"flex flex-1 w-full h-full items-center justify-center rounded-xl border border-slate-700/50 bg-slate-950/80 text-slate-500",children:"No tree — insert a value to begin"});const l=Math.min(...s.map(u=>u.x),0)-40,i=Math.max(...s.map(u=>u.x),0)+40,c=Math.max(...s.map(u=>u.y),0)+40,h=i-l+80,m=c+80;return a.jsx("div",{className:"flex-1 w-full rounded-xl border border-slate-700/50 bg-slate-950/80 p-4 shadow-2xl backdrop-blur-sm overflow-auto",children:a.jsxs("svg",{viewBox:`${l-40} -20 ${h} ${m}`,className:"w-full h-full",preserveAspectRatio:"xMidYMid meet",children:[n.map((u,g)=>a.jsx("line",{x1:u.from.x,y1:u.from.y,x2:u.to.x,y2:u.to.y,stroke:"#475569",strokeWidth:2,strokeOpacity:.5},g)),s.map(u=>{const g=r.includes(u.id),b=e==="rbtree";let N="#1e293b",w="#475569",v="#e2e8f0";return b?u.color==="red"?(N=g?"#f87171":"#dc2626",w="#fca5a5",v="#ffffff"):(N=g?"#475569":"#1e293b",w=g?"#94a3b8":"#64748b",v="#e2e8f0"):g&&(N="#fbbf24",w="#f59e0b",v="#1e293b"),a.jsxs("g",{children:[a.jsx("circle",{cx:u.x,cy:u.y,r:22,fill:N,stroke:w,strokeWidth:g?3:2,className:"transition-all duration-200"}),a.jsx("text",{x:u.x,y:u.y+1,textAnchor:"middle",dominantBaseline:"central",fill:v,fontSize:12,fontWeight:600,fontFamily:"ui-monospace, monospace",children:u.value}),e==="avl"&&a.jsxs("text",{x:u.x+20,y:u.y-18,textAnchor:"middle",dominantBaseline:"central",fill:"#94a3b8",fontSize:9,fontFamily:"ui-monospace, monospace",children:["h",u.height]})]},u.id)})]})})}const St={bst:{name:"Binary Search Tree",description:"A binary tree where left child < parent < right child. No self-balancing — can degenerate to a linked list.",properties:["Unbalanced","O(h) operations","Simple"]},avl:{name:"AVL Tree",description:"A self-balancing BST where the heights of left and right subtrees differ by at most 1. Uses rotations to maintain balance.",properties:["Height-balanced","O(log n)","Rotations"]},rbtree:{name:"Red-Black Tree",description:"A self-balancing BST using node coloring (red/black) and rules to ensure the tree stays approximately balanced.",properties:["Color-balanced","O(log n)","Recoloring"]}},Ct=[{label:"Slow",value:600},{label:"Medium",value:300},{label:"Fast",value:100}],Tt=["bst","avl","rbtree"];function Vt({treeType:t,changeTreeType:e,inputValue:r,setInputValue:s,description:n,stepIndex:l,totalSteps:i,canGoNext:c,canGoPrev:h,history:m,speed:u,setSpeed:g,isPlaying:b,onInsert:N,onDelete:w,onNextStep:v,onPrevStep:j,onGenerateRandom:F}){const I=St[t],R=()=>{const o=parseInt(r);!isNaN(o)&&o>0&&(N(o),s(""))},G=()=>{const o=parseInt(r);!isNaN(o)&&o>0&&(w(o),s(""))},W=o=>{o.key==="Enter"&&R()};return a.jsxs("div",{className:"flex flex-col gap-5 w-full md:w-72 shrink-0 overflow-y-auto max-h-full pr-1",children:[a.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[a.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Tree Type"}),a.jsx("div",{className:"flex gap-2",children:Tt.map(o=>a.jsx("button",{onClick:()=>e(o),className:` + flex-1 rounded-lg px-2 py-2 text-xs font-medium transition-all duration-200 + ${t===o?"bg-indigo-500/20 text-indigo-300 ring-1 ring-indigo-500/40 shadow-lg shadow-indigo-500/10":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50 hover:text-slate-300"} + `,children:o==="rbtree"?"RB Tree":o.toUpperCase()},o))}),a.jsxs("div",{className:"mt-3 rounded-lg bg-slate-800/40 p-3",children:[a.jsx("p",{className:"text-xs text-slate-400 leading-relaxed",children:I.description}),a.jsx("div",{className:"mt-2 flex flex-wrap gap-1.5",children:I.properties.map(o=>a.jsx("span",{className:"inline-flex items-center rounded-full bg-violet-500/10 px-2 py-0.5 text-[10px] font-medium text-violet-400 ring-1 ring-violet-500/20",children:o},o))})]})]}),a.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[a.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Speed"}),a.jsx("div",{className:"flex gap-1",children:Ct.map(o=>a.jsx("button",{onClick:()=>g(o.value),className:` + flex-1 rounded-lg px-2 py-1.5 text-xs font-medium transition-all duration-200 + ${u===o.value?"bg-violet-500/20 text-violet-300 ring-1 ring-violet-500/40":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50 hover:text-slate-300"} + `,children:o.label},o.value))})]}),a.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[a.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Operations"}),a.jsx("input",{type:"number",min:"1",max:"999",value:r,onChange:o=>s(o.target.value),onKeyDown:W,placeholder:"Enter value...",disabled:b,className:"w-full rounded-lg bg-slate-800/60 px-3 py-2 text-sm text-slate-200 placeholder-slate-600 outline-none ring-1 ring-slate-700/50 focus:ring-indigo-500/50 transition-all disabled:opacity-50"}),a.jsxs("div",{className:"mt-3 grid grid-cols-2 gap-2",children:[a.jsxs("button",{onClick:R,disabled:b,className:"flex items-center justify-center gap-1.5 rounded-lg bg-gradient-to-r from-emerald-500/80 to-green-500/80 px-3 py-2 text-xs font-semibold text-white shadow-lg shadow-emerald-500/15 transition-all hover:brightness-110 active:scale-[0.98] disabled:opacity-50 disabled:cursor-not-allowed",children:[a.jsx(Nt,{size:14}),"Insert"]}),a.jsxs("button",{onClick:G,disabled:b,className:"flex items-center justify-center gap-1.5 rounded-lg bg-gradient-to-r from-rose-500/80 to-pink-500/80 px-3 py-2 text-xs font-semibold text-white shadow-lg shadow-rose-500/15 transition-all hover:brightness-110 active:scale-[0.98] disabled:opacity-50 disabled:cursor-not-allowed",children:[a.jsx(It,{size:14}),"Delete"]})]}),a.jsxs("button",{onClick:F,className:"mt-2 w-full flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300",children:[a.jsx(wt,{size:12}),"Random Tree"]})]}),i>0&&a.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[a.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Step Through"}),n&&a.jsx("p",{className:"mb-3 rounded-lg bg-slate-800/40 p-2 text-xs text-indigo-300 leading-relaxed",children:n}),a.jsxs("div",{className:"flex gap-2",children:[a.jsxs("button",{onClick:j,disabled:!h||b,className:"flex-1 flex items-center justify-center gap-1 rounded-lg bg-slate-800/60 px-3 py-2.5 text-sm font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300 disabled:opacity-30 disabled:cursor-not-allowed",children:[a.jsx($t,{size:16}),"Prev"]}),a.jsxs("button",{onClick:v,disabled:!c||b,className:"flex-1 flex items-center justify-center gap-1 rounded-lg bg-slate-800/60 px-3 py-2.5 text-sm font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300 disabled:opacity-30 disabled:cursor-not-allowed",children:["Next",a.jsx(yt,{size:16})]})]}),a.jsxs("div",{className:"mt-2 flex items-center justify-between",children:[a.jsx("span",{className:"text-xs text-slate-500",children:"Step"}),a.jsxs("span",{className:"text-sm font-mono font-semibold text-indigo-400",children:[Math.max(0,l+1)," / ",i]})]})]}),m.length>0&&a.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[a.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"History"}),a.jsx("div",{className:"max-h-36 overflow-y-auto space-y-1",children:m.map((o,C)=>a.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[a.jsx("span",{className:"font-mono text-slate-600 w-4 text-right",children:C+1}),a.jsx("span",{className:o.startsWith("Insert")?"text-emerald-400":"text-rose-400",children:o})]},C))})]}),a.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[a.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Legend"}),a.jsxs("div",{className:"space-y-2",children:[a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx("div",{className:"h-3 w-5 rounded-sm bg-amber-400"}),a.jsx("span",{className:"text-xs text-slate-400",children:"Highlighted Node"})]}),t==="rbtree"&&a.jsxs(a.Fragment,{children:[a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx("div",{className:"h-3 w-5 rounded-sm bg-red-600"}),a.jsx("span",{className:"text-xs text-slate-400",children:"Red Node"})]}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx("div",{className:"h-3 w-5 rounded-sm bg-slate-800 ring-1 ring-slate-600"}),a.jsx("span",{className:"text-xs text-slate-400",children:"Black Node"})]})]}),t==="avl"&&a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx("span",{className:"text-[10px] font-mono text-slate-500 bg-slate-800 px-1.5 py-0.5 rounded",children:"h3"}),a.jsx("span",{className:"text-xs text-slate-400",children:"Height label"})]})]})]})]})}let O=0;function at(t,e){return{id:O++,value:t,left:null,right:null,parent:e,height:1,color:"black",x:0,y:0}}function T(t,e=null){if(!t)return null;const r={...t,parent:e,left:null,right:null};return r.left=T(t.left,r),r.right=T(t.right,r),r}function S(t,e,r,s){t&&(t.x=r,t.y=e*70,S(t.left,e+1,r-s,s*.55),S(t.right,e+1,r+s,s*.55))}function E(t){const e=T(t);return e&&S(e,0,0,300),e}function $(t){return t?[...$(t.left),t.value,...$(t.right)]:[]}function Mt(t){for(;t.left;)t=t.left;return t}function Bt(t,e){O=t?L(t)+1:0;const r=[];function s(l,i){if(!l){const c=at(e,i);return r.push({description:`Insert ${e}`,highlightIds:[c.id],snapshotValues:$(t),snapshotRoot:null}),c}return r.push({description:`Compare ${e} with ${l.value}`,highlightIds:[l.id],snapshotValues:$(t),snapshotRoot:null}),el.value&&(l.right=s(l.right,l)),l}const n=s(t?T(t):null,null);return n&&S(n,0,0,300),r.forEach(l=>{l.snapshotRoot=E(n)}),r.push({description:`Inserted ${e} — done`,highlightIds:[],snapshotValues:$(n),snapshotRoot:E(n)}),{root:n,steps:r}}function Dt(t,e){if(!t)return{root:null,steps:[{description:"Tree is empty",highlightIds:[],snapshotValues:[],snapshotRoot:null}]};O=L(t)+1;const r=[];let s=T(t);function n(l){if(!l)return r.push({description:`${e} not found`,highlightIds:[],snapshotValues:$(s),snapshotRoot:null}),null;if(r.push({description:`Compare ${e} with ${l.value}`,highlightIds:[l.id],snapshotValues:$(s),snapshotRoot:null}),el.value)l.right=n(l.right);else{if(r.push({description:`Found ${e}, removing`,highlightIds:[l.id],snapshotValues:$(s),snapshotRoot:null}),!l.left)return l.right;if(!l.right)return l.left;const i=Mt(l.right);r.push({description:`Replace with successor ${i.value}`,highlightIds:[i.id],snapshotValues:$(s),snapshotRoot:null}),l.value=i.value,l.right=n(l.right)}return l}return s=n(s),s&&S(s,0,0,300),r.forEach(l=>{l.snapshotRoot=E(s)}),r.push({description:`Deleted ${e} — done`,highlightIds:[],snapshotValues:$(s),snapshotRoot:E(s)}),{root:s,steps:r}}function L(t){return t?Math.max(t.id,L(t.left),L(t.right)):-1}function ct(t){O=0;let e=null;for(const r of t)e=q(e,r);return e&&S(e,0,0,300),e}function q(t,e){return t?(et.value&&(t.right=q(t.right,e),t.right.parent=t),t):at(e,null)}let Z=0;function Ft(t){return{id:Z++,value:t,left:null,right:null,parent:null,height:1,color:"black",x:0,y:0}}function z(t){return t?t.height:0}function V(t){t.height=1+Math.max(z(t.left),z(t.right))}function U(t){return z(t.left)-z(t.right)}function y(t,e,r,s){const n=Pt(s.current);t.push({description:e,highlightIds:r,snapshotValues:J(n),snapshotRoot:n})}function et(t,e,r){const s=t.left;return t.left=s.right,s.right=t,V(t),V(s),r.current===t&&(r.current=s),y(e,`Right rotate at ${t.value}`,[t.id,s.id],r),s}function rt(t,e,r){const s=t.right;return t.right=s.left,s.left=t,V(t),V(s),r.current===t&&(r.current=s),y(e,`Left rotate at ${t.value}`,[t.id,s.id],r),s}function M(t,e,r,s){t&&(t.x=r,t.y=e*70,M(t.left,e+1,r-s,s*.55),M(t.right,e+1,r+s,s*.55))}function B(t){if(!t)return null;const e={...t,parent:null,left:null,right:null};return e.left=B(t.left),e.right=B(t.right),e}function Pt(t){const e=B(t);return e&&M(e,0,0,300),e}function J(t){return t?[...J(t.left),t.value,...J(t.right)]:[]}function A(t){return t?Math.max(t.id,A(t.left),A(t.right)):-1}function Et(t){for(;t.left;)t=t.left;return t}function ot(t,e,r){V(t);const s=U(t);return s>1?(U(t.left)<0&&(t.left=rt(t.left,e,r)),et(t,e,r)):s<-1?(U(t.right)>0&&(t.right=et(t.right,e,r)),rt(t,e,r)):t}function ut(t,e){Z=t?A(t)+1:0;const r=[],s={current:t?B(t):null};function n(i){if(!i){const c=Ft(e);return s.current||(s.current=c),y(r,`Insert ${e}`,[c.id],s),c}if(y(r,`Compare ${e} with ${i.value}`,[i.id],s),ei.value)i.right=n(i.right);else return i;return ot(i,r,s)}const l=n(s.current);return s.current=l,M(l,0,0,300),y(r,`Inserted ${e} — balanced`,[],s),{root:l,steps:r}}function Lt(t,e){if(!t)return{root:null,steps:[{description:"Tree is empty",highlightIds:[],snapshotValues:[],snapshotRoot:null}]};Z=A(t)+1;const r=[],s={current:B(t)};function n(i){if(!i)return y(r,`${e} not found`,[],s),null;if(y(r,`Compare ${e} with ${i.value}`,[i.id],s),ei.value)i.right=n(i.right);else{if(y(r,`Found ${e}, removing`,[i.id],s),!i.left)return i.right;if(!i.right)return i.left;const c=Et(i.right);y(r,`Replace with successor ${c.value}`,[c.id],s),i.value=c.value,i.right=n(i.right)}return ot(i,r,s)}const l=n(s.current);return s.current=l,l&&M(l,0,0,300),y(r,`Deleted ${e} — balanced`,[],s),{root:l,steps:r}}function zt(t){let e=null;for(const r of t)e=ut(e,r).root;return e}let tt=0;function At(t,e){return{id:tt++,value:t,left:null,right:null,parent:null,height:1,color:e,x:0,y:0}}function D(t,e=null){if(!t)return null;const r={...t,parent:e,left:null,right:null};return r.left=D(t.left,r),r.right=D(t.right,r),r}function k(t,e,r,s){t&&(t.x=r,t.y=e*70,k(t.left,e+1,r-s,s*.55),k(t.right,e+1,r+s,s*.55))}function Ht(t){const e=D(t);return e&&k(e,0,0,300),e}function Q(t){return t?[...Q(t.left),t.value,...Q(t.right)]:[]}function H(t){return t?Math.max(t.id,H(t.left),H(t.right)):-1}function st(t){return t?t.color:"black"}function d(t,e,r,s){const n=Ht(s.current);t.push({description:e,highlightIds:r,snapshotValues:Q(n),snapshotRoot:n})}function lt(t,e){const r=e.right;return e.right=r.left,r.left&&(r.left.parent=e),r.parent=e.parent,e.parent?e===e.parent.left?e.parent.left=r:e.parent.right=r:t=r,r.left=e,e.parent=r,t}function nt(t,e){const r=e.left;return e.left=r.right,r.right&&(r.right.parent=e),r.parent=e.parent,e.parent?e===e.parent.right?e.parent.right=r:e.parent.left=r:t=r,r.right=e,e.parent=r,t}function Ot(t,e,r){let s=t.current,n=e;for(;n.parent&&n.parent.color==="red";){const l=n.parent.parent;if(!l)break;if(n.parent===l.left){const i=l.right;st(i)==="red"?(n.parent.color="black",i.color="black",l.color="red",t.current=s,d(r,`Recolor: parent ${n.parent.value} & uncle ${i.value} → black, grandparent ${l.value} → red`,[n.parent.id,i.id,l.id],t),n=l):(n===n.parent.right&&(n=n.parent,s=lt(s,n),t.current=s,d(r,`Left rotate at ${n.value}`,[n.id],t)),n.parent.color="black",l.color="red",s=nt(s,l),t.current=s,d(r,`Right rotate at ${l.value}`,[l.id],t))}else{const i=l.left;st(i)==="red"?(n.parent.color="black",i.color="black",l.color="red",t.current=s,d(r,`Recolor: parent ${n.parent.value} & uncle ${i.value} → black, grandparent ${l.value} → red`,[n.parent.id,i.id,l.id],t),n=l):(n===n.parent.left&&(n=n.parent,s=nt(s,n),t.current=s,d(r,`Right rotate at ${n.value}`,[n.id],t)),n.parent.color="black",l.color="red",s=lt(s,l),t.current=s,d(r,`Left rotate at ${l.value}`,[l.id],t))}}return s.color="black",t.current=s,s}function ht(t,e){tt=t?H(t)+1:0;const r=[],s={current:t?D(t):null},n=At(e,"red");if(!s.current)return n.color="black",s.current=n,k(n,0,0,300),d(r,`Insert ${e} (red)`,[n.id],s),d(r,`${e} is root — color black`,[n.id],s),{root:n,steps:r};d(r,`Insert ${e} (red)`,[n.id],s);let l=s.current,i=null;for(;l;)if(i=l,d(r,`Compare ${e} with ${l.value}`,[l.id],s),el.value)l=l.right;else return k(s.current,0,0,300),d(r,`${e} already exists`,[],s),{root:s.current,steps:r};n.parent=i,eh.value?n(h.right,m):h:null}const l=n(s.current,e);if(!l)return d(r,`${e} not found`,[],s),{root:s.current,steps:r};d(r,`Found ${e}, deleting`,[l.id],s);let i=l;if(l.left&&l.right){let h=l.right;for(;h.left;)h=h.left;l.value=h.value,i=h,d(r,`Replace with successor ${h.value}`,[h.id],s)}const c=i.left||i.right;return c&&(c.parent=i.parent),i.parent?i===i.parent.left?i.parent.left=c:i.parent.right=c:s.current=c,s.current&&(s.current.color="black",k(s.current,0,0,300)),d(r,`Deleted ${e} — done`,[],s),{root:s.current,steps:r}}function Wt(t){let e=null;for(const r of t)e=ht(e,r).root;return e}function Y(t){const e=new Set;for(;e.sizect(Y(7))),[n,l]=p.useState([]),[i,c]=p.useState(-1),[h,m]=p.useState(""),[u,g]=p.useState([]),[b,N]=p.useState(300),[w,v]=p.useState(!1),j=p.useRef(null),I=(i>=0&&i=0&&i=0&&i{e(f);const x=it(f,Y(7));s(x),l([]),c(-1),g([])},[]),o=p.useCallback(()=>{const f=it(t,Y(7));s(f),l([]),c(-1),g([])},[t]),C=p.useCallback(()=>{j.current&&(clearInterval(j.current),j.current=null),v(!1)},[]),P=p.useCallback((f,x,bt)=>{C(),l(f),c(0),v(!0),g(vt=>[...vt,bt]);let _=0;j.current=window.setInterval(()=>{if(_++,_>=f.length){j.current&&clearInterval(j.current),j.current=null,v(!1),c(f.length-1),s(x);return}c(_)},b)},[b,C]),ft=p.useCallback(f=>{let x;switch(t){case"bst":x=Bt(r,f);break;case"avl":x=ut(r,f);break;case"rbtree":x=ht(r,f);break}P(x.steps,x.root,`Insert ${f}`)},[t,r,P]),pt=p.useCallback(f=>{let x;switch(t){case"bst":x=Dt(r,f);break;case"avl":x=Lt(r,f);break;case"rbtree":x=Gt(r,f);break}P(x.steps,x.root,`Delete ${f}`)},[t,r,P]),dt=p.useCallback(()=>{if+1)},[i,n.length]),gt=p.useCallback(()=>{i>0&&c(f=>f-1)},[i]),xt=i0;return{treeType:t,changeTreeType:W,root:r,displayRoot:I,highlightIds:R,description:G,steps:n,stepIndex:i,canGoNext:xt,canGoPrev:mt,inputValue:h,setInputValue:m,history:u,speed:b,setSpeed:N,isPlaying:w,generateRandom:o,doInsert:ft,doDelete:pt,nextStep:dt,prevStep:gt}}function qt(){const{treeType:t,changeTreeType:e,displayRoot:r,highlightIds:s,description:n,steps:l,stepIndex:i,canGoNext:c,canGoPrev:h,inputValue:m,setInputValue:u,history:g,speed:b,setSpeed:N,isPlaying:w,generateRandom:v,doInsert:j,doDelete:F,nextStep:I,prevStep:R}=_t();return a.jsxs("div",{className:"flex flex-1 flex-col md:flex-row gap-4 md:gap-6 overflow-auto p-4 md:p-6",children:[a.jsx("div",{className:"order-last md:order-first flex md:flex-1 flex-col items-center justify-center gap-3 min-h-[40vh] md:min-h-0 max-h-[50vh] md:max-h-none overflow-auto",children:a.jsx(Rt,{root:r,treeType:t,highlightIds:s})}),a.jsx(Vt,{treeType:t,changeTreeType:e,inputValue:m,setInputValue:u,description:n,stepIndex:i,totalSteps:l.length,canGoNext:c,canGoPrev:h,history:g,speed:b,setSpeed:N,isPlaying:w,onInsert:j,onDelete:F,onNextStep:I,onPrevStep:R,onGenerateRandom:v})]})}export{qt as default}; diff --git a/docs/assets/BattlePage-BHrGHw2_.js b/docs/assets/BattlePage-BHrGHw2_.js new file mode 100644 index 0000000..740c52c --- /dev/null +++ b/docs/assets/BattlePage-BHrGHw2_.js @@ -0,0 +1 @@ +import{c as He,j as e,f as Le,r as u,g as Ve}from"./index-BfWfBQOp.js";import{V as ge,a as fe}from"./volume-x-ChIHiT28.js";import{S as Ge}from"./shuffle-Ri9xSsK2.js";import{P as be}from"./play-WRQgdyAG.js";import{T as je}from"./trophy-CUioHXrM.js";import{R as xe}from"./rotate-ccw-EKzY5q_W.js";import{P as ve}from"./pause-Bg-8t1oj.js";import{N as D,r as _e}from"./index-Cj8HB9AY.js";import{r as Me}from"./index-iw_6MvvU.js";import{g as qe}from"./audioContext-NbgqvQGz.js";import{A as Ye}from"./arrow-left-CkNLVmJL.js";import{M as Ee}from"./map-DMi7QK0E.js";const Xe=[["path",{d:"M3 3v16a2 2 0 0 0 2 2h16",key:"c24i48"}],["path",{d:"M18 17V9",key:"2bz60n"}],["path",{d:"M13 17V5",key:"1frdt8"}],["path",{d:"M8 17v-3",key:"17ska0"}]],Ke=He("chart-column",Xe);const Qe=[["line",{x1:"5",x2:"19",y1:"9",y2:"9",key:"1nwqeh"}],["line",{x1:"5",x2:"19",y1:"15",y2:"15",key:"g8yjpy"}]],ye=He("equal",Qe),X=[{value:"bubble",label:"Bubble Sort"},{value:"selection",label:"Selection Sort"},{value:"insertion",label:"Insertion Sort"},{value:"quick",label:"Quick Sort"},{value:"heap",label:"Heap Sort"},{value:"merge",label:"Merge Sort"}],ze={bubble:{best:"O(n)",average:"O(n²)",worst:"O(n²)",space:"O(1)"},selection:{best:"O(n²)",average:"O(n²)",worst:"O(n²)",space:"O(1)"},insertion:{best:"O(n)",average:"O(n²)",worst:"O(n²)",space:"O(1)"},quick:{best:"O(n log n)",average:"O(n log n)",worst:"O(n²)",space:"O(log n)"},heap:{best:"O(n log n)",average:"O(n log n)",worst:"O(n log n)",space:"O(1)"},merge:{best:"O(n log n)",average:"O(n log n)",worst:"O(n log n)",space:"O(n)"}},me=[{label:"Slow",value:150},{label:"Medium",value:50},{label:"Fast",value:15},{label:"Turbo",value:1}];function Ue(t,a){const s=[];for(let l=0;ln-c);const l=Math.max(1,Math.floor(t*.05));for(let n=0;nn-l);return s}function Ze(t,a,s,l,n,c){const i=X.find(f=>f.value===a).label,o=X.find(f=>f.value===s).label;if(t==="tie")return`Both ${i} and ${o} completed in the same number of operations. This can happen with small inputs or similar-complexity algorithms.`;const r=t==="A"?i:o,d=t==="A"?o:i,m=t==="A"?l:n,x=t==="A"?n:l,g=(x.totalSteps/Math.max(m.totalSteps,1)).toFixed(1);let p=`${r} won with ${m.totalSteps} steps vs ${x.totalSteps} steps (${g}x fewer operations). `;return c==="nearly-sorted"?p+="On nearly-sorted data, algorithms like Insertion Sort have a natural advantage due to their O(n) best-case performance.":c==="reversed"?p+="Reversed input is the worst case for O(n²) algorithms, making the performance gap with O(n log n) algorithms very visible.":p+=`${d} performed more operations because its average-case complexity is higher for this input distribution.`,p}const Je=[{value:"random",label:"Random"},{value:"nearly-sorted",label:"Nearly Sorted"},{value:"reversed",label:"Reversed"}],et=[{value:"realtime",label:"Real-Time",desc:"Watch both algorithms animate step-by-step"},{value:"turbo",label:"Turbo",desc:"Instant execution, metrics only"},{value:"prediction",label:"Prediction",desc:"Predict the winner before starting"}];function tt({algorithmA:t,algorithmB:a,inputSize:s,inputType:l,gameMode:n,speed:c,soundEnabled:i,prediction:o,onSetAlgorithmA:r,onSetAlgorithmB:d,onSetInputSize:m,onSetInputType:x,onSetGameMode:g,onSetSpeed:p,onToggleSound:f,onSetPrediction:y,onStart:C}){const w=X.find(h=>h.value===t).label,S=X.find(h=>h.value===a).label;return e.jsxs("div",{className:"flex-1 overflow-y-auto",children:[e.jsxs("section",{className:"flex flex-col items-center justify-center px-6 pt-8 pb-4 text-center",children:[e.jsxs("div",{className:"mb-3 inline-flex items-center gap-2 rounded-full bg-rose-500/10 px-4 py-1.5 ring-1 ring-rose-500/20",children:[e.jsx(Le,{size:14,className:"text-rose-400"}),e.jsx("span",{className:"text-xs font-medium text-rose-300",children:"Algorithm Battles"})]}),e.jsxs("h2",{className:"text-2xl font-extrabold tracking-tight text-white",children:[e.jsx("span",{className:"bg-gradient-to-r from-rose-400 to-orange-400 bg-clip-text text-transparent",children:w})," ","vs"," ",e.jsx("span",{className:"bg-gradient-to-r from-cyan-400 to-blue-400 bg-clip-text text-transparent",children:S})]})]}),e.jsx("section",{className:"px-4 pb-8",children:e.jsxs("div",{className:"mx-auto max-w-2xl space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-rose-400 mb-3",children:"Algorithm A"}),e.jsx("div",{className:"grid grid-cols-2 gap-1.5",children:X.map(h=>e.jsx("button",{onClick:()=>r(h.value),className:`rounded-lg px-2 py-2 text-[11px] font-medium transition-all ${t===h.value?"bg-rose-500/20 text-rose-300 ring-1 ring-rose-500/40":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50"}`,children:h.label},h.value))})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-cyan-400 mb-3",children:"Algorithm B"}),e.jsx("div",{className:"grid grid-cols-2 gap-1.5",children:X.map(h=>e.jsx("button",{onClick:()=>d(h.value),className:`rounded-lg px-2 py-2 text-[11px] font-medium transition-all ${a===h.value?"bg-cyan-500/20 text-cyan-300 ring-1 ring-cyan-500/40":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50"}`,children:h.label},h.value))})]})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Input Configuration"}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-1",children:[e.jsx("span",{className:"text-xs text-slate-500",children:"Array Size"}),e.jsx("span",{className:"text-sm font-mono font-bold text-indigo-300",children:s})]}),e.jsx("input",{type:"range",min:10,max:200,step:10,value:s,onChange:h=>m(Number(h.target.value)),className:"w-full accent-indigo-500"})]}),e.jsx("div",{className:"flex gap-1.5",children:Je.map(h=>e.jsx("button",{onClick:()=>x(h.value),className:`flex-1 rounded-lg px-2 py-2 text-[11px] font-medium transition-all ${l===h.value?"bg-indigo-500/20 text-indigo-300 ring-1 ring-indigo-500/40":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50"}`,children:h.label},h.value))})]})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Game Mode"}),e.jsx("div",{className:"grid grid-cols-3 gap-1.5",children:et.map(h=>e.jsxs("button",{onClick:()=>g(h.value),className:`flex flex-col items-center rounded-lg px-2 py-2.5 text-[11px] font-medium transition-all ${n===h.value?"bg-violet-500/20 text-violet-300 ring-1 ring-violet-500/40":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50"}`,children:[e.jsx("span",{className:"font-semibold",children:h.label}),e.jsx("span",{className:"text-[9px] text-slate-500 mt-0.5 hidden sm:block",children:h.desc})]},h.value))})]}),n==="prediction"&&e.jsxs("div",{className:"rounded-xl border border-amber-500/20 bg-amber-500/5 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-amber-400 mb-3",children:"Your Prediction"}),e.jsx("p",{className:"text-[10px] text-amber-300/60 mb-3",children:"Who will win with fewer operations?"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("button",{onClick:()=>y("A"),className:`flex-1 rounded-lg px-3 py-2.5 text-sm font-medium transition-all ${o==="A"?"bg-rose-500/20 text-rose-300 ring-1 ring-rose-500/40":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50"}`,children:w}),e.jsx("button",{onClick:()=>y("B"),className:`flex-1 rounded-lg px-3 py-2.5 text-sm font-medium transition-all ${o==="B"?"bg-cyan-500/20 text-cyan-300 ring-1 ring-cyan-500/40":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50"}`,children:S})]})]}),e.jsxs("div",{className:"flex gap-4",children:[e.jsxs("div",{className:"flex-1 rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Speed"}),e.jsx("div",{className:"flex gap-1.5",children:me.map(h=>e.jsx("button",{onClick:()=>p(h.value),className:`flex-1 rounded-lg px-2 py-2 text-[11px] font-medium transition-all ${c===h.value?"bg-emerald-500/20 text-emerald-300 ring-1 ring-emerald-500/40":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50"}`,children:h.label},h.value))})]}),e.jsxs("button",{onClick:()=>f(!i),className:`shrink-0 flex flex-col items-center justify-center rounded-xl px-4 transition-all ${i?"bg-indigo-500/15 text-indigo-300 ring-1 ring-indigo-500/30":"bg-slate-800/60 text-slate-500 ring-1 ring-slate-700/40"}`,children:[i?e.jsx(ge,{size:18}):e.jsx(fe,{size:18}),e.jsx("span",{className:"text-[10px] mt-1",children:i?"On":"Off"})]})]}),e.jsxs("button",{onClick:C,disabled:n==="prediction"&&!o,className:"w-full flex items-center justify-center gap-2 rounded-xl bg-gradient-to-r from-rose-500/20 to-cyan-500/20 px-6 py-4 text-base font-bold text-white ring-1 ring-white/10 transition-all hover:from-rose-500/30 hover:to-cyan-500/30 hover:ring-white/20 active:scale-[0.98] disabled:opacity-40 disabled:cursor-not-allowed",children:[e.jsx(Ge,{size:18,className:"text-rose-300"}),e.jsx(be,{size:18,className:"text-cyan-300"}),"Start Battle"]})]})})]})}function ke({state:t,color:a,maxVal:s}){const l=X.find(x=>x.value===t.algorithm).label,n=t.status==="finished",c=t.array.length,o={rose:{default:"bg-rose-500/60",comparing:"bg-amber-400",swapping:"bg-rose-300",sorted:"bg-emerald-500/70",border:n?"ring-2 ring-emerald-500/50":"ring-1 ring-slate-700/50",label:"text-rose-400",badge:"bg-rose-500/15 text-rose-300 ring-rose-500/30"},cyan:{default:"bg-cyan-500/60",comparing:"bg-amber-400",swapping:"bg-cyan-300",sorted:"bg-emerald-500/70",border:n?"ring-2 ring-emerald-500/50":"ring-1 ring-slate-700/50",label:"text-cyan-400",badge:"bg-cyan-500/15 text-cyan-300 ring-cyan-500/30"}}[a],r=new Set(t.comparing||[]),d=new Set(t.swapping||[]),m=new Set(t.sorted);return e.jsxs("div",{className:"flex-1 min-w-0 flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between px-1",children:[e.jsx("span",{className:`text-xs font-bold ${o.label}`,children:l}),e.jsx("span",{className:`rounded-full px-2 py-0.5 text-[10px] font-medium ring-1 ${o.badge}`,children:n?"Finished":"Running"})]}),e.jsx("div",{className:`rounded-xl border border-slate-700/50 bg-slate-950/80 p-2 ${o.border} transition-all overflow-hidden`,children:e.jsx("div",{className:"flex items-end gap-px h-32 sm:h-44 md:h-52",children:t.array.map((x,g)=>{const p=x/s*100;let f=o.default;return r.has(g)?f=o.comparing:d.has(g)?f=o.swapping:m.has(g)&&(f=o.sorted),e.jsx("div",{className:`flex-1 rounded-t-sm transition-all duration-75 ${f}`,style:{height:`${p}%`,minWidth:c>100?"1px":"2px"}},g)})})}),e.jsxs("div",{className:"grid grid-cols-3 gap-1.5 px-1",children:[e.jsxs("div",{className:"rounded-lg bg-slate-800/50 px-2 py-1.5 text-center",children:[e.jsx("div",{className:"text-[10px] text-slate-500",children:"Comparisons"}),e.jsx("div",{className:"text-xs font-mono font-bold text-white",children:t.metrics.comparisons})]}),e.jsxs("div",{className:"rounded-lg bg-slate-800/50 px-2 py-1.5 text-center",children:[e.jsx("div",{className:"text-[10px] text-slate-500",children:"Swaps"}),e.jsx("div",{className:"text-xs font-mono font-bold text-white",children:t.metrics.swaps})]}),e.jsxs("div",{className:"rounded-lg bg-slate-800/50 px-2 py-1.5 text-center",children:[e.jsx("div",{className:"text-[10px] text-slate-500",children:"Steps"}),e.jsxs("div",{className:"text-xs font-mono font-bold text-white",children:[t.metrics.stepsCompleted,"/",t.metrics.totalSteps]})]})]})]})}function st({history:t,nameA:a,nameB:s}){const{pathA:l,pathB:n,maxOps:c,maxTime:i}=u.useMemo(()=>{if(t.length<2)return{pathA:"",pathB:"",maxOps:1,maxTime:1};const o=Math.max(...t.map(g=>Math.max(g.opsA,g.opsB)),1),r=t.length-1,d=400,m=120,x=g=>t.map((p,f)=>{const y=f/r*d,C=m-p[g]/o*m;return`${f===0?"M":"L"}${y.toFixed(1)},${C.toFixed(1)}`}).join(" ");return{pathA:x("opsA"),pathB:x("opsB"),maxOps:o,maxTime:r}},[t]);return t.length<2?null:e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Live Performance"}),e.jsxs("div",{className:"flex items-center gap-4 mb-2",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("div",{className:"h-2 w-4 rounded-full bg-rose-400"}),e.jsx("span",{className:"text-[10px] text-slate-400",children:a})]}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("div",{className:"h-2 w-4 rounded-full bg-cyan-400"}),e.jsx("span",{className:"text-[10px] text-slate-400",children:s})]}),e.jsxs("span",{className:"ml-auto text-[10px] text-slate-500",children:["Max ops: ",c]})]}),e.jsxs("svg",{viewBox:"0 0 400 120",className:"w-full h-20 sm:h-28",preserveAspectRatio:"none",children:[e.jsx("path",{d:l,fill:"none",stroke:"#fb7185",strokeWidth:2,strokeLinecap:"round"}),e.jsx("path",{d:n,fill:"none",stroke:"#22d3ee",strokeWidth:2,strokeLinecap:"round"})]}),e.jsxs("div",{className:"flex justify-between mt-1",children:[e.jsx("span",{className:"text-[9px] text-slate-600",children:"0"}),e.jsxs("span",{className:"text-[9px] text-slate-600",children:["Steps → ",i]})]})]})}function nt({stateA:t,stateB:a,winner:s,prediction:l,predictionCorrect:n,inputType:c,onReset:i}){const o=X.find(g=>g.value===t.algorithm).label,r=X.find(g=>g.value===a.algorithm).label,d=ze[t.algorithm],m=ze[a.algorithm],x=Ze(s,t.algorithm,a.algorithm,t.metrics,a.metrics,c);return e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-5 backdrop-blur-sm space-y-4",children:[e.jsx("div",{className:"text-center",children:s==="tie"?e.jsxs("div",{className:"inline-flex items-center gap-2 rounded-full bg-amber-500/10 px-5 py-2 ring-1 ring-amber-500/20",children:[e.jsx(ye,{size:18,className:"text-amber-400"}),e.jsx("span",{className:"text-sm font-bold text-amber-300",children:"It's a Tie!"})]}):e.jsxs("div",{className:`inline-flex items-center gap-2 rounded-full px-5 py-2 ring-1 ${s==="A"?"bg-rose-500/10 ring-rose-500/20":"bg-cyan-500/10 ring-cyan-500/20"}`,children:[e.jsx(je,{size:18,className:s==="A"?"text-rose-400":"text-cyan-400"}),e.jsxs("span",{className:`text-sm font-bold ${s==="A"?"text-rose-300":"text-cyan-300"}`,children:[s==="A"?o:r," Wins!"]})]})}),l&&n!==null&&e.jsx("div",{className:`rounded-lg px-4 py-2.5 text-center text-xs font-medium ${n?"bg-emerald-500/10 text-emerald-300 ring-1 ring-emerald-500/20":"bg-rose-500/10 text-rose-300 ring-1 ring-rose-500/20"}`,children:n?"🎯 Your prediction was correct!":"❌ Your prediction was wrong. Keep learning!"}),e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-xs",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-slate-700/50",children:[e.jsx("th",{className:"py-2 text-left text-slate-500 font-medium",children:"Metric"}),e.jsx("th",{className:"py-2 text-center text-rose-400 font-semibold",children:o}),e.jsx("th",{className:"py-2 text-center text-cyan-400 font-semibold",children:r})]})}),e.jsx("tbody",{className:"font-mono",children:[{label:"Total Steps",a:t.metrics.totalSteps,b:a.metrics.totalSteps},{label:"Comparisons",a:t.metrics.comparisons,b:a.metrics.comparisons},{label:"Swaps",a:t.metrics.swaps,b:a.metrics.swaps},{label:"Array Accesses",a:t.metrics.arrayAccesses,b:a.metrics.arrayAccesses},{label:"Time (s)",a:t.metrics.timeElapsed.toFixed(2),b:a.metrics.timeElapsed.toFixed(2)}].map(({label:g,a:p,b:f})=>{const y=typeof p=="string"?parseFloat(p):p,C=typeof f=="string"?parseFloat(f):f;return e.jsxs("tr",{className:"border-b border-slate-800/50",children:[e.jsx("td",{className:"py-2 text-slate-400",children:g}),e.jsxs("td",{className:`py-2 text-center font-semibold ${y<=C?"text-emerald-300":"text-white"}`,children:[p,ye.jsxs("div",{className:"rounded-lg bg-slate-800/40 p-3",children:[e.jsx("h4",{className:`text-[10px] font-bold uppercase tracking-wider ${f==="rose"?"text-rose-400":"text-cyan-400"} mb-2`,children:g}),e.jsxs("div",{className:"space-y-1 text-[10px] font-mono",children:[e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-slate-500",children:"Best"}),e.jsx("span",{className:"text-slate-300",children:p.best})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-slate-500",children:"Average"}),e.jsx("span",{className:"text-slate-300",children:p.average})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-slate-500",children:"Worst"}),e.jsx("span",{className:"text-slate-300",children:p.worst})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-slate-500",children:"Space"}),e.jsx("span",{className:"text-slate-300",children:p.space})]})]})]},g))}),e.jsxs("div",{className:"rounded-lg bg-indigo-500/5 px-4 py-3 ring-1 ring-indigo-500/15",children:[e.jsx("h4",{className:"text-[10px] font-bold uppercase tracking-wider text-indigo-400 mb-1",children:"Why?"}),e.jsx("p",{className:"text-xs text-slate-400 leading-relaxed",children:x})]}),e.jsxs("button",{onClick:i,className:"w-full flex items-center justify-center gap-2 rounded-xl bg-slate-800/60 px-6 py-3 text-sm font-medium text-slate-300 ring-1 ring-slate-700/50 transition-all hover:bg-slate-700/60 active:scale-[0.98]",children:[e.jsx(xe,{size:14}),"New Battle"]})]})}function at({stateA:t,stateB:a,status:s,winner:l,prediction:n,predictionCorrect:c,inputType:i,speed:o,soundEnabled:r,metricsHistory:d,onPause:m,onResume:x,onReset:g,onSetSpeed:p,onToggleSound:f}){const y=X.find(h=>h.value===t.algorithm).label,C=X.find(h=>h.value===a.algorithm).label,w=Math.max(...t.array,...a.array,1),S=s==="running";return e.jsx("div",{className:"flex-1 overflow-y-auto p-4 md:p-6",children:e.jsxs("div",{className:"mx-auto max-w-5xl space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3 flex-wrap",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[s!=="finished"&&e.jsxs("button",{onClick:S?m:x,className:"flex items-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-slate-300 ring-1 ring-slate-700/50 transition-all hover:bg-slate-700/60",children:[S?e.jsx(ve,{size:14}):e.jsx(be,{size:14}),S?"Pause":"Resume"]}),e.jsxs("button",{onClick:g,className:"flex items-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-slate-300 ring-1 ring-slate-700/50 transition-all hover:bg-slate-700/60",children:[e.jsx(xe,{size:14}),"Reset"]}),e.jsx("button",{onClick:()=>f(!r),className:`flex items-center gap-1.5 rounded-lg px-3 py-2 text-xs font-medium transition-all ring-1 ${r?"bg-indigo-500/15 text-indigo-300 ring-indigo-500/30":"bg-slate-800/60 text-slate-500 ring-slate-700/40"}`,children:r?e.jsx(ge,{size:14}):e.jsx(fe,{size:14})})]}),s!=="finished"&&e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"text-[10px] text-slate-500",children:"Speed:"}),me.map(h=>e.jsx("button",{onClick:()=>p(h.value),className:`rounded px-2 py-1 text-[10px] font-medium transition-all ${o===h.value?"bg-emerald-500/20 text-emerald-300 ring-1 ring-emerald-500/40":"bg-slate-800/50 text-slate-500 hover:bg-slate-700/50"}`,children:h.label},h.value))]}),e.jsxs("div",{className:"text-xs text-slate-500 font-mono",children:[t.metrics.timeElapsed.toFixed(1),"s"]})]}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-4",children:[e.jsx(ke,{state:t,color:"rose",maxVal:w}),e.jsx(ke,{state:a,color:"cyan",maxVal:w})]}),e.jsx(st,{history:d,nameA:y,nameB:C}),s==="finished"&&l&&e.jsx(nt,{stateA:t,stateB:a,winner:l,prediction:n,predictionCorrect:c,inputType:i,onReset:g})]})})}const ne=15,Z=25,lt=.25,rt=[{value:"random",label:"Random Scatter"},{value:"recursive-division",label:"Recursive Division"},{value:"dfs-maze",label:"DFS Maze"}];function Re(t,a){return`${t},${a}`}function it(){const t=[];for(let a=0;ac===a.row&&i===a.col||c===s.row&&i===s.col;function n(c,i,o,r,d){if(d){if(i-c<2)return;const m=[];for(let p=c+1;p.5)}function dt(t,a,s){for(let o=0;oMath.random()-.5);for(const[m,x]of d){const g=o+m,p=r+x;g>=0&&g=0&&p=0&&(t[s.row][s.col-1].type=D.EMPTY)}function ut(t="random"){const a=it(),s={row:Math.floor(ne/2),col:1},l={row:Math.floor(ne/2),col:Z-2};switch(t){case"recursive-division":ot(a,s,l);break;case"dfs-maze":dt(a,s,l);break;default:ct(a,s,l);break}return a[s.row][s.col].type=D.START,a[l.row][l.col].type=D.END,{grid:a,start:s,end:l}}function Te(t,a,s,l){const n=_e(l,t,a,s),c=n.visitedNodesInOrder,i=n.shortestPath,o=[],r=new Set;for(let d=0;d0){const d=new Set(r);for(let m=0;mRe(x.row,x.col)))})}return{steps:o,totalVisited:c.length,pathLength:i.length,found:i.length>0}}const de=[{value:"bfs",label:"BFS"},{value:"dfs",label:"DFS"},{value:"dijkstra",label:"Dijkstra"},{value:"astar",label:"A*"}],$e={bfs:{time:"O(V + E)",space:"O(V)",optimal:!0},dfs:{time:"O(V + E)",space:"O(V)",optimal:!1},dijkstra:{time:"O(V² / V+E log V)",space:"O(V)",optimal:!0},astar:{time:"O(E)",space:"O(V)",optimal:!0}};function Be({grid:t,step:a,algorithm:s,color:l,finished:n,totalVisited:c,pathLength:i,currentIndex:o,totalSteps:r}){const d=de.find(g=>g.value===s).label,x={rose:{visited:"bg-rose-500/40",path:"bg-rose-300",current:"bg-rose-400",label:"text-rose-400",badge:"bg-rose-500/15 text-rose-300 ring-rose-500/30",border:n?"ring-2 ring-emerald-500/50":"ring-1 ring-slate-700/50"},cyan:{visited:"bg-cyan-500/40",path:"bg-cyan-300",current:"bg-cyan-400",label:"text-cyan-400",badge:"bg-cyan-500/15 text-cyan-300 ring-cyan-500/30",border:n?"ring-2 ring-emerald-500/50":"ring-1 ring-slate-700/50"}}[l];return e.jsxs("div",{className:"flex-1 min-w-0 flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between px-1",children:[e.jsx("span",{className:`text-xs font-bold ${x.label}`,children:d}),e.jsx("span",{className:`rounded-full px-2 py-0.5 text-[10px] font-medium ring-1 ${x.badge}`,children:n?"Finished":"Running"})]}),e.jsx("div",{className:`rounded-xl border border-slate-700/50 bg-slate-950/80 p-1 ${x.border} transition-all overflow-hidden`,children:e.jsx("div",{className:"grid",style:{gridTemplateColumns:`repeat(${Z}, 1fr)`,gap:"1px"},children:t.map((g,p)=>g.map((f,y)=>{const C=`${p},${y}`;let w="bg-slate-800/40";return f.type===D.WALL?w="bg-slate-600":f.type===D.START?w="bg-emerald-500":f.type===D.END?w="bg-amber-500":a&&(a.pathNodes.has(C)?w=x.path:a.currentNode&&a.currentNode.row===p&&a.currentNode.col===y?w=x.current:a.visitedSoFar.has(C)&&(w=x.visited)),e.jsx("div",{className:`aspect-square rounded-[1px] ${w} transition-colors duration-75`},C)}))})}),e.jsxs("div",{className:"grid grid-cols-3 gap-1.5 px-1",children:[e.jsxs("div",{className:"rounded-lg bg-slate-800/50 px-2 py-1.5 text-center",children:[e.jsx("div",{className:"text-[10px] text-slate-500",children:"Visited"}),e.jsx("div",{className:"text-xs font-mono font-bold text-white",children:c})]}),e.jsxs("div",{className:"rounded-lg bg-slate-800/50 px-2 py-1.5 text-center",children:[e.jsx("div",{className:"text-[10px] text-slate-500",children:"Path"}),e.jsx("div",{className:"text-xs font-mono font-bold text-white",children:i})]}),e.jsxs("div",{className:"rounded-lg bg-slate-800/50 px-2 py-1.5 text-center",children:[e.jsx("div",{className:"text-[10px] text-slate-500",children:"Steps"}),e.jsxs("div",{className:"text-xs font-mono font-bold text-white",children:[o,"/",r]})]})]})]})}function xt({grid:t,stateA:a,stateB:s,status:l,winner:n,prediction:c,predictionCorrect:i,speed:o,soundEnabled:r,onPause:d,onResume:m,onReset:x,onSetSpeed:g,onToggleSound:p}){const f=l==="running",y=de.find(h=>h.value===a.algorithm).label,C=de.find(h=>h.value===s.algorithm).label,w=a.currentIndexp(!r),className:`flex items-center gap-1.5 rounded-lg px-3 py-2 text-xs font-medium ring-1 ${r?"bg-indigo-500/15 text-indigo-300 ring-indigo-500/30":"bg-slate-800/60 text-slate-500 ring-slate-700/40"}`,children:r?e.jsx(ge,{size:14}):e.jsx(fe,{size:14})})]}),l!=="finished"&&e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"text-[10px] text-slate-500",children:"Speed:"}),me.map(h=>e.jsx("button",{onClick:()=>g(h.value),className:`rounded px-2 py-1 text-[10px] font-medium ${o===h.value?"bg-emerald-500/20 text-emerald-300 ring-1 ring-emerald-500/40":"bg-slate-800/50 text-slate-500 hover:bg-slate-700/50"}`,children:h.label},h.value))]})]}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-4",children:[e.jsx(Be,{grid:t,step:w,algorithm:a.algorithm,color:"rose",finished:a.finished,totalVisited:a.totalVisited,pathLength:a.pathLength,currentIndex:a.currentIndex,totalSteps:a.steps.length}),e.jsx(Be,{grid:t,step:S,algorithm:s.algorithm,color:"cyan",finished:s.finished,totalVisited:s.totalVisited,pathLength:s.pathLength,currentIndex:s.currentIndex,totalSteps:s.steps.length})]}),l==="finished"&&n&&e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-5 backdrop-blur-sm space-y-4",children:[e.jsx("div",{className:"text-center",children:n==="tie"?e.jsxs("div",{className:"inline-flex items-center gap-2 rounded-full bg-amber-500/10 px-5 py-2 ring-1 ring-amber-500/20",children:[e.jsx(ye,{size:18,className:"text-amber-400"}),e.jsx("span",{className:"text-sm font-bold text-amber-300",children:"It's a Tie!"})]}):e.jsxs("div",{className:`inline-flex items-center gap-2 rounded-full px-5 py-2 ring-1 ${n==="A"?"bg-rose-500/10 ring-rose-500/20":"bg-cyan-500/10 ring-cyan-500/20"}`,children:[e.jsx(je,{size:18,className:n==="A"?"text-rose-400":"text-cyan-400"}),e.jsxs("span",{className:`text-sm font-bold ${n==="A"?"text-rose-300":"text-cyan-300"}`,children:[n==="A"?y:C," Wins!"]})]})}),c&&i!==null&&e.jsx("div",{className:`rounded-lg px-4 py-2.5 text-center text-xs font-medium ${i?"bg-emerald-500/10 text-emerald-300 ring-1 ring-emerald-500/20":"bg-rose-500/10 text-rose-300 ring-1 ring-rose-500/20"}`,children:i?"🎯 Correct prediction!":"❌ Wrong prediction. Keep learning!"}),e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-xs",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-slate-700/50",children:[e.jsx("th",{className:"py-2 text-left text-slate-500",children:"Metric"}),e.jsx("th",{className:"py-2 text-center text-rose-400 font-semibold",children:y}),e.jsx("th",{className:"py-2 text-center text-cyan-400 font-semibold",children:C})]})}),e.jsx("tbody",{className:"font-mono",children:[{label:"Nodes Visited",a:a.totalVisited,b:s.totalVisited},{label:"Path Length",a:a.pathLength,b:s.pathLength},{label:"Total Steps",a:a.steps.length,b:s.steps.length}].map(({label:h,a:z,b:B})=>e.jsxs("tr",{className:"border-b border-slate-800/50",children:[e.jsx("td",{className:"py-2 text-slate-400",children:h}),e.jsxs("td",{className:`py-2 text-center font-semibold ${z<=B?"text-emerald-300":"text-white"}`,children:[z,ze.jsxs("div",{className:"rounded-lg bg-slate-800/40 p-3",children:[e.jsx("h4",{className:`text-[10px] font-bold uppercase tracking-wider ${B==="rose"?"text-rose-400":"text-cyan-400"} mb-2`,children:h}),e.jsxs("div",{className:"space-y-1 text-[10px] font-mono",children:[e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-slate-500",children:"Time"}),e.jsx("span",{className:"text-slate-300",children:z.time})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-slate-500",children:"Space"}),e.jsx("span",{className:"text-slate-300",children:z.space})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-slate-500",children:"Optimal"}),e.jsx("span",{className:z.optimal?"text-emerald-300":"text-rose-300",children:z.optimal?"Yes":"No"})]})]})]},h))}),e.jsxs("button",{onClick:x,className:"w-full flex items-center justify-center gap-2 rounded-xl bg-slate-800/60 px-6 py-3 text-sm font-medium text-slate-300 ring-1 ring-slate-700/50 hover:bg-slate-700/60 active:scale-[0.98]",children:[e.jsx(xe,{size:14})," New Battle"]})]})]})})}const Ne=[{value:"fibonacci",label:"Fibonacci",desc:"Compute the Nth Fibonacci number",inputLabel:"N",inputMin:5,inputMax:25,defaultN:15},{value:"factorial",label:"Factorial",desc:"Compute N! (N factorial)",inputLabel:"N",inputMin:3,inputMax:20,defaultN:10},{value:"staircase",label:"Staircase",desc:"Ways to climb N stairs (1 or 2 steps)",inputLabel:"Stairs",inputMin:5,inputMax:25,defaultN:15},{value:"coin-change",label:"Coin Change",desc:"Min coins to make amount N (coins: 1,3,5)",inputLabel:"Amount",inputMin:5,inputMax:30,defaultN:15}];function Ie(t){const a=[];let s=0,l=0;function n(i,o){if(s++,l=Math.max(l,o),a.push({callCount:s,cacheHits:0,currentDepth:o,maxDepth:l,currentN:i,result:null,cacheSize:0}),i<=1)return a.push({callCount:s,cacheHits:0,currentDepth:o,maxDepth:l,currentN:i,result:i,cacheSize:0}),i;const r=n(i-1,o+1)+n(i-2,o+1);return a.push({callCount:s,cacheHits:0,currentDepth:o,maxDepth:l,currentN:i,result:r,cacheSize:0}),r}const c=n(t,0);return{steps:a,finalResult:c,totalCalls:s,totalCacheHits:0,maxDepth:l}}function mt(t){const a=[];let s=0,l=0,n=0;const c=new Map;function i(r,d){if(s++,n=Math.max(n,d),c.has(r)){l++;const x=c.get(r);return a.push({callCount:s,cacheHits:l,currentDepth:d,maxDepth:n,currentN:r,result:x,cacheSize:c.size}),x}if(a.push({callCount:s,cacheHits:l,currentDepth:d,maxDepth:n,currentN:r,result:null,cacheSize:c.size}),r<=1)return c.set(r,r),a.push({callCount:s,cacheHits:l,currentDepth:d,maxDepth:n,currentN:r,result:r,cacheSize:c.size}),r;const m=i(r-1,d+1)+i(r-2,d+1);return c.set(r,m),a.push({callCount:s,cacheHits:l,currentDepth:d,maxDepth:n,currentN:r,result:m,cacheSize:c.size}),m}const o=i(t,0);return{steps:a,finalResult:o,totalCalls:s,totalCacheHits:l,maxDepth:n}}function pt(t){const a=[];let s=0;if(t<=1)return s=1,a.push({callCount:s,cacheHits:0,currentDepth:0,maxDepth:0,currentN:t,result:t,cacheSize:0}),{steps:a,finalResult:t,totalCalls:1,totalCacheHits:0,maxDepth:0};let l=0,n=1;for(let c=2;c<=t;c++){s++;const i=l+n;l=n,n=i,a.push({callCount:s,cacheHits:0,currentDepth:0,maxDepth:0,currentN:c,result:n,cacheSize:0})}return{steps:a,finalResult:n,totalCalls:s,totalCacheHits:0,maxDepth:0}}const ue=[{value:"naive",label:"Naive Recursive"},{value:"memoized",label:"Memoized"},{value:"iterative",label:"Iterative"}],De={naive:{time:"O(2ⁿ)",space:"O(n)"},memoized:{time:"O(n)",space:"O(n)"},iterative:{time:"O(n)",space:"O(1)"}};function ht(t){const a=[];let s=0,l=0;function n(i,o){if(s++,l=Math.max(l,o),a.push({callCount:s,cacheHits:0,currentDepth:o,maxDepth:l,currentN:i,result:null,cacheSize:0}),i<=1)return a.push({callCount:s,cacheHits:0,currentDepth:o,maxDepth:l,currentN:i,result:1,cacheSize:0}),1;const r=i*n(i-1,o+1);return a.push({callCount:s,cacheHits:0,currentDepth:o,maxDepth:l,currentN:i,result:r,cacheSize:0}),r}const c=n(t,0);return{steps:a,finalResult:c,totalCalls:s,totalCacheHits:0,maxDepth:l}}function gt(t){const a=[];let s=0,l=0,n=0;const c=new Map;function i(r,d){if(s++,n=Math.max(n,d),c.has(r)){l++;const x=c.get(r);return a.push({callCount:s,cacheHits:l,currentDepth:d,maxDepth:n,currentN:r,result:x,cacheSize:c.size}),x}if(a.push({callCount:s,cacheHits:l,currentDepth:d,maxDepth:n,currentN:r,result:null,cacheSize:c.size}),r<=1)return c.set(r,1),a.push({callCount:s,cacheHits:l,currentDepth:d,maxDepth:n,currentN:r,result:1,cacheSize:c.size}),1;const m=r*i(r-1,d+1);return c.set(r,m),a.push({callCount:s,cacheHits:l,currentDepth:d,maxDepth:n,currentN:r,result:m,cacheSize:c.size}),m}const o=i(t,0);return{steps:a,finalResult:o,totalCalls:s,totalCacheHits:l,maxDepth:n}}function ft(t){const a=[];let s=1;for(let l=2;l<=t;l++)s*=l,a.push({callCount:l-1,cacheHits:0,currentDepth:0,maxDepth:0,currentN:l,result:s,cacheSize:0});return a.length===0&&a.push({callCount:1,cacheHits:0,currentDepth:0,maxDepth:0,currentN:t,result:1,cacheSize:0}),{steps:a,finalResult:s,totalCalls:Math.max(t-1,1),totalCacheHits:0,maxDepth:0}}function bt(t){const a=[];let s=0,l=0;function n(i,o){if(s++,l=Math.max(l,o),a.push({callCount:s,cacheHits:0,currentDepth:o,maxDepth:l,currentN:i,result:null,cacheSize:0}),i<=1)return a.push({callCount:s,cacheHits:0,currentDepth:o,maxDepth:l,currentN:i,result:1,cacheSize:0}),1;const r=n(i-1,o+1)+n(i-2,o+1);return a.push({callCount:s,cacheHits:0,currentDepth:o,maxDepth:l,currentN:i,result:r,cacheSize:0}),r}const c=n(t,0);return{steps:a,finalResult:c,totalCalls:s,totalCacheHits:0,maxDepth:l}}function Nt(t){const a=[];let s=0,l=0,n=0;const c=new Map;function i(r,d){if(s++,n=Math.max(n,d),c.has(r)){l++;const x=c.get(r);return a.push({callCount:s,cacheHits:l,currentDepth:d,maxDepth:n,currentN:r,result:x,cacheSize:c.size}),x}if(a.push({callCount:s,cacheHits:l,currentDepth:d,maxDepth:n,currentN:r,result:null,cacheSize:c.size}),r<=1)return c.set(r,1),a.push({callCount:s,cacheHits:l,currentDepth:d,maxDepth:n,currentN:r,result:1,cacheSize:c.size}),1;const m=i(r-1,d+1)+i(r-2,d+1);return c.set(r,m),a.push({callCount:s,cacheHits:l,currentDepth:d,maxDepth:n,currentN:r,result:m,cacheSize:c.size}),m}const o=i(t,0);return{steps:a,finalResult:o,totalCalls:s,totalCacheHits:l,maxDepth:n}}function jt(t){const a=[];if(t<=1)return a.push({callCount:1,cacheHits:0,currentDepth:0,maxDepth:0,currentN:t,result:1,cacheSize:0}),{steps:a,finalResult:1,totalCalls:1,totalCacheHits:0,maxDepth:0};let s=1,l=1;for(let n=2;n<=t;n++){const c=s+l;s=l,l=c,a.push({callCount:n-1,cacheHits:0,currentDepth:0,maxDepth:0,currentN:n,result:l,cacheSize:0})}return{steps:a,finalResult:l,totalCalls:t-1,totalCacheHits:0,maxDepth:0}}const Se=[1,3,5];function vt(t){const a=[];let s=0,l=0;function n(i,o){if(s++,l=Math.max(l,o),a.push({callCount:s,cacheHits:0,currentDepth:o,maxDepth:l,currentN:i,result:null,cacheSize:0}),i===0)return a.push({callCount:s,cacheHits:0,currentDepth:o,maxDepth:l,currentN:i,result:0,cacheSize:0}),0;if(i<0)return a.push({callCount:s,cacheHits:0,currentDepth:o,maxDepth:l,currentN:i,result:1/0,cacheSize:0}),1/0;let r=1/0;for(const d of Se){const m=n(i-d,o+1);m!==1/0&&(r=Math.min(r,m+1))}return a.push({callCount:s,cacheHits:0,currentDepth:o,maxDepth:l,currentN:i,result:r===1/0?-1:r,cacheSize:0}),r}const c=n(t,0);return{steps:a,finalResult:c===1/0?-1:c,totalCalls:s,totalCacheHits:0,maxDepth:l}}function yt(t){const a=[];let s=0,l=0,n=0;const c=new Map;function i(r,d){if(s++,n=Math.max(n,d),c.has(r)){l++;const x=c.get(r);return a.push({callCount:s,cacheHits:l,currentDepth:d,maxDepth:n,currentN:r,result:x===1/0?-1:x,cacheSize:c.size}),x}if(a.push({callCount:s,cacheHits:l,currentDepth:d,maxDepth:n,currentN:r,result:null,cacheSize:c.size}),r===0)return c.set(0,0),a.push({callCount:s,cacheHits:l,currentDepth:d,maxDepth:n,currentN:r,result:0,cacheSize:c.size}),0;if(r<0)return 1/0;let m=1/0;for(const x of Se){const g=i(r-x,d+1);g!==1/0&&(m=Math.min(m,g+1))}return c.set(r,m),a.push({callCount:s,cacheHits:l,currentDepth:d,maxDepth:n,currentN:r,result:m===1/0?-1:m,cacheSize:c.size}),m}const o=i(t,0);return{steps:a,finalResult:o===1/0?-1:o,totalCalls:s,totalCacheHits:l,maxDepth:n}}function St(t){const a=[],s=new Array(t+1).fill(1/0);s[0]=0;let l=0;for(let n=1;n<=t;n++){for(const c of Se)n>=c&&s[n-c]+1r.value===t.algorithm).label,n=t.currentIndex0?t.currentIndex/c*100:0,o=a==="rose"?{label:"text-rose-400",badge:"bg-rose-500/15 text-rose-300 ring-rose-500/30",bar:"bg-rose-500",border:t.finished?"ring-2 ring-emerald-500/50":"ring-1 ring-slate-700/50"}:{label:"text-cyan-400",badge:"bg-cyan-500/15 text-cyan-300 ring-cyan-500/30",bar:"bg-cyan-500",border:t.finished?"ring-2 ring-emerald-500/50":"ring-1 ring-slate-700/50"};return e.jsxs("div",{className:"flex-1 min-w-0 flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between px-1",children:[e.jsx("span",{className:`text-xs font-bold ${o.label}`,children:l}),e.jsx("span",{className:`rounded-full px-2 py-0.5 text-[10px] font-medium ring-1 ${o.badge}`,children:t.finished?"Finished":"Running"})]}),e.jsxs("div",{className:`rounded-xl border border-slate-700/50 bg-slate-950/80 p-3 ${o.border} transition-all`,children:[e.jsxs("div",{className:"mb-2",children:[e.jsxs("div",{className:"flex justify-between mb-1",children:[e.jsx("span",{className:"text-[10px] text-slate-500",children:"Function Calls"}),e.jsxs("span",{className:"text-[10px] font-mono text-slate-400",children:[n?n.callCount:0," / ",t.totalCalls]})]}),e.jsx("div",{className:"h-4 rounded-full bg-slate-800/60 overflow-hidden",children:e.jsx("div",{className:`h-full rounded-full ${o.bar} transition-all duration-75`,style:{width:`${i}%`}})})]}),e.jsxs("div",{className:"mb-2",children:[e.jsx("span",{className:"text-[10px] text-slate-500 block mb-1",children:"Stack Depth"}),e.jsx("div",{className:"flex items-end gap-px h-16",children:Array.from({length:Math.max(n?.maxDepth||1,1)},(r,d)=>{const m=n?dS.value===t.algorithm).label,C=ue.find(S=>S.value===a.algorithm).label,w=wt[r];return e.jsx("div",{className:"flex-1 overflow-y-auto p-4 md:p-6",children:e.jsxs("div",{className:"mx-auto max-w-5xl space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3 flex-wrap",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[s!=="finished"&&e.jsxs("button",{onClick:f?d:m,className:"flex items-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-slate-300 ring-1 ring-slate-700/50 hover:bg-slate-700/60",children:[f?e.jsx(ve,{size:14}):e.jsx(be,{size:14}),f?"Pause":"Resume"]}),e.jsxs("button",{onClick:x,className:"flex items-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-slate-300 ring-1 ring-slate-700/50 hover:bg-slate-700/60",children:[e.jsx(xe,{size:14})," Reset"]}),e.jsx("button",{onClick:()=>p(!o),className:`flex items-center gap-1.5 rounded-lg px-3 py-2 text-xs font-medium ring-1 ${o?"bg-indigo-500/15 text-indigo-300 ring-indigo-500/30":"bg-slate-800/60 text-slate-500 ring-slate-700/40"}`,children:o?e.jsx(ge,{size:14}):e.jsx(fe,{size:14})})]}),s!=="finished"&&e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"text-[10px] text-slate-500",children:"Speed:"}),me.map(S=>e.jsx("button",{onClick:()=>g(S.value),className:`rounded px-2 py-1 text-[10px] font-medium ${i===S.value?"bg-emerald-500/20 text-emerald-300 ring-1 ring-emerald-500/40":"bg-slate-800/50 text-slate-500 hover:bg-slate-700/50"}`,children:S.label},S.value))]})]}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-4",children:[e.jsx(Pe,{state:t,color:"rose",funcName:w}),e.jsx(Pe,{state:a,color:"cyan",funcName:w})]}),s==="finished"&&l&&e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-5 backdrop-blur-sm space-y-4",children:[e.jsx("div",{className:"text-center",children:l==="tie"?e.jsxs("div",{className:"inline-flex items-center gap-2 rounded-full bg-amber-500/10 px-5 py-2 ring-1 ring-amber-500/20",children:[e.jsx(ye,{size:18,className:"text-amber-400"}),e.jsx("span",{className:"text-sm font-bold text-amber-300",children:"It's a Tie!"})]}):e.jsxs("div",{className:`inline-flex items-center gap-2 rounded-full px-5 py-2 ring-1 ${l==="A"?"bg-rose-500/10 ring-rose-500/20":"bg-cyan-500/10 ring-cyan-500/20"}`,children:[e.jsx(je,{size:18,className:l==="A"?"text-rose-400":"text-cyan-400"}),e.jsxs("span",{className:`text-sm font-bold ${l==="A"?"text-rose-300":"text-cyan-300"}`,children:[l==="A"?y:C," Wins!"]})]})}),n&&c!==null&&e.jsx("div",{className:`rounded-lg px-4 py-2.5 text-center text-xs font-medium ${c?"bg-emerald-500/10 text-emerald-300 ring-1 ring-emerald-500/20":"bg-rose-500/10 text-rose-300 ring-1 ring-rose-500/20"}`,children:c?"🎯 Correct prediction!":"❌ Wrong prediction. Keep learning!"}),e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-xs",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-slate-700/50",children:[e.jsx("th",{className:"py-2 text-left text-slate-500",children:"Metric"}),e.jsx("th",{className:"py-2 text-center text-rose-400 font-semibold",children:y}),e.jsx("th",{className:"py-2 text-center text-cyan-400 font-semibold",children:C})]})}),e.jsx("tbody",{className:"font-mono",children:[{label:"Total Calls",a:t.totalCalls,b:a.totalCalls},{label:"Cache Hits",a:t.totalCacheHits,b:a.totalCacheHits},{label:"Max Stack Depth",a:t.maxDepth,b:a.maxDepth},{label:"Total Steps",a:t.steps.length,b:a.steps.length}].map(({label:S,a:h,b:z})=>e.jsxs("tr",{className:"border-b border-slate-800/50",children:[e.jsx("td",{className:"py-2 text-slate-400",children:S}),e.jsxs("td",{className:`py-2 text-center font-semibold ${h<=z?"text-emerald-300":"text-white"}`,children:[h,he.jsxs("div",{className:"rounded-lg bg-slate-800/40 p-3",children:[e.jsx("h4",{className:`text-[10px] font-bold uppercase tracking-wider ${z==="rose"?"text-rose-400":"text-cyan-400"} mb-2`,children:S}),e.jsxs("div",{className:"space-y-1 text-[10px] font-mono",children:[e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-slate-500",children:"Time"}),e.jsx("span",{className:"text-slate-300",children:h.time})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-slate-500",children:"Space"}),e.jsx("span",{className:"text-slate-300",children:h.space})]})]})]},S))}),e.jsxs("div",{className:"rounded-lg bg-indigo-500/5 px-4 py-3 ring-1 ring-indigo-500/15",children:[e.jsx("h4",{className:"text-[10px] font-bold uppercase tracking-wider text-indigo-400 mb-1",children:"Why?"}),e.jsxs("p",{className:"text-xs text-slate-400 leading-relaxed",children:[t.totalCalls>a.totalCalls?`${y} made ${t.totalCalls} function calls compared to ${C}'s ${a.totalCalls}. `:a.totalCalls>t.totalCalls?`${C} made ${a.totalCalls} function calls compared to ${y}'s ${t.totalCalls}. `:`Both made ${t.totalCalls} calls. `,r==="factorial"?"Factorial is inherently linear — naive and memoized perform similarly. The iterative version avoids stack overhead.":r==="coin-change"?"Naive coin change explores all combinations (branching factor 3), while memoization caches sub-amounts to avoid redundant work. Iterative DP builds the table bottom-up.":"Naive recursion recalculates the same subproblems exponentially (O(2ⁿ)), while memoization caches results reducing to O(n). The iterative approach avoids recursion overhead entirely with O(1) space."]})]}),e.jsxs("button",{onClick:x,className:"w-full flex items-center justify-center gap-2 rounded-xl bg-slate-800/60 px-6 py-3 text-sm font-medium text-slate-300 ring-1 ring-slate-700/50 hover:bg-slate-700/60 active:scale-[0.98]",children:[e.jsx(xe,{size:14})," New Battle"]})]})]})})}const Fe=[261.63,293.66,329.63,392,440,523.25,587.33,659.25,783.99,880];function we(){const t=u.useRef(!0),a=u.useCallback(()=>qe(),[]),s=u.useCallback(i=>{t.current=i},[]),l=u.useCallback((i,o,r)=>{if(!t.current)return;const d=a();if(!d)return;const m=i/Math.max(o-1,1),x=Fe[Math.floor(m*(Fe.length-1))],g=d.createOscillator(),p=d.createGain(),f=d.createStereoPanner();g.type="sine",g.frequency.value=x,p.gain.setValueAtTime(.04,d.currentTime),p.gain.exponentialRampToValueAtTime(.001,d.currentTime+.08),f.pan.value=r,g.connect(p),p.connect(f),f.connect(d.destination),g.start(),g.stop(d.currentTime+.08)},[a]),n=u.useCallback((i,o,r)=>{if(!t.current)return;const d=a();if(!d)return;const x=200+i/Math.max(o-1,1)*600,g=d.createOscillator(),p=d.createGain(),f=d.createStereoPanner();g.type="triangle",g.frequency.value=x,p.gain.setValueAtTime(.06,d.currentTime),p.gain.exponentialRampToValueAtTime(.001,d.currentTime+.1),f.pan.value=r,g.connect(p),p.connect(f),f.connect(d.destination),g.start(),g.stop(d.currentTime+.1)},[a]),c=u.useCallback(()=>{if(!t.current)return;const i=a();i&&[523.25,659.25,783.99].forEach((o,r)=>{const d=i.createOscillator(),m=i.createGain();d.type="sine",d.frequency.value=o,m.gain.setValueAtTime(.1,i.currentTime+r*.12),m.gain.exponentialRampToValueAtTime(.001,i.currentTime+r*.12+.2),d.connect(m),m.connect(i.destination),d.start(i.currentTime+r*.12),d.stop(i.currentTime+r*.12+.2)})},[a]);return{playCompareTone:l,playSwapTone:n,playWinTone:c,setEnabled:s}}function te(t,a){let s=0,l=0,n=0;for(let c=0;c<=a&&c{y(j),ie(j)},[ie]),Q=u.useCallback(()=>{L.current&&(cancelAnimationFrame(L.current),L.current=null)},[]),A=u.useCallback(()=>{const j=Ue(n,i);ae(j);const b=Me(t,[...j]),v=Me(s,[...j]);P.current=b,F.current=v,E.current=0,H.current=0;const T=te(b,0),V=te(v,0);if(w(se(t,b[0],T,0,b.length,!1)),h(se(s,v[0],V,0,v.length,!1)),B(null),G(null),_([{stepA:0,stepB:0,opsA:0,opsB:0}]),ee.current=performance.now(),r==="turbo"){const le=te(b,b.length-1),U=te(v,v.length-1);le.timeElapsed=0,U.timeElapsed=0;const oe=b[b.length-1],pe=v[v.length-1];w(se(t,oe,le,b.length-1,b.length,!0)),h(se(s,pe,U,v.length-1,v.length,!0));let I="tie";le.totalSteps{const j=P.current,b=F.current;let v=E.current,T=H.current;const V=v>=j.length-1,le=T>=b.length-1;if(V&&le){const I=te(j,v),Ce=te(b,T),Ae=(performance.now()-ee.current)/1e3;I.timeElapsed=Ae,Ce.timeElapsed=Ae,w(se(t,j[v],I,v,j.length,!0)),h(se(s,b[T],Ce,T,b.length,!0));let he="tie";j.length=j.length-1)),h(se(s,b[T],oe,T,b.length,T>=b.length-1)),_(I=>[...I,{stepA:U.stepsCompleted,stepB:oe.stepsCompleted,opsA:U.totalOperations,opsB:oe.totalOperations}])},[t,s,n,f,$,q,Y,W]);u.useEffect(()=>{if(g!=="running"){Q();return}let j=0;const b=v=>{v-j>=m&&(j=v,k()),L.current=requestAnimationFrame(b)};return L.current=requestAnimationFrame(b),Q},[g,m,k,Q]);const N=u.useCallback(()=>{g==="running"&&p("paused")},[g]),M=u.useCallback(()=>{g==="paused"&&p("running")},[g]),R=u.useCallback(()=>{Q(),P.current=[],F.current=[],E.current=0,H.current=0,w(null),h(null),B(null),O(null),G(null),_([]),p("setup")},[Q]);return{algorithmA:t,setAlgorithmA:a,algorithmB:s,setAlgorithmB:l,inputSize:n,setInputSize:c,inputType:i,setInputType:o,gameMode:r,setGameMode:d,speed:m,setSpeed:x,status:g,soundEnabled:f,toggleSound:ce,stateA:C,stateB:S,winner:z,prediction:$,setPrediction:O,predictionCorrect:re,inputData:K,metricsHistory:J,startBattle:A,pause:N,resume:M,reset:R}}function Mt(){const[t,a]=u.useState("bfs"),[s,l]=u.useState("dfs"),[n,c]=u.useState("random"),[i,o]=u.useState("realtime"),[r,d]=u.useState(50),[m,x]=u.useState("setup"),[g,p]=u.useState(!0),[f,y]=u.useState(null),[C,w]=u.useState(null),[S,h]=u.useState(null),[z,B]=u.useState(null),[$,O]=u.useState(null),[re,G]=u.useState(null),K=u.useRef([]),ae=u.useRef([]),J=u.useRef(0),_=u.useRef(0),P=u.useRef(null),F=u.useRef({totalVisited:0,pathLength:0,found:!1}),E=u.useRef({totalVisited:0,pathLength:0,found:!1}),{playCompareTone:H,playWinTone:L,setEnabled:ee}=we(),q=u.useCallback(N=>{p(N),ee(N)},[ee]),Y=u.useCallback(()=>{P.current&&(cancelAnimationFrame(P.current),P.current=null)},[]),W=u.useCallback((N,M)=>{let R="tie";return N.found&&!M.found?R="A":!N.found&&M.found?R="B":N.found&&M.found&&(N.totalVisited{const{grid:N,start:M,end:R}=ut(n);y(N);const j=Te(N,M,R,t),b=Te(N,M,R,s);K.current=j.steps,ae.current=b.steps,J.current=0,_.current=0,F.current={totalVisited:j.totalVisited,pathLength:j.pathLength,found:j.found},E.current={totalVisited:b.totalVisited,pathLength:b.pathLength,found:b.found};const v={algorithm:t,steps:j.steps,currentIndex:0,totalVisited:j.totalVisited,pathLength:j.pathLength,found:j.found,finished:!1},T={algorithm:s,steps:b.steps,currentIndex:0,totalVisited:b.totalVisited,pathLength:b.pathLength,found:b.found,finished:!1};if(i==="turbo"){w({...v,currentIndex:j.steps.length-1,finished:!0}),h({...T,currentIndex:b.steps.length-1,finished:!0});const V=W(F.current,E.current);B(V),$&&G($===V),x("finished"),L();return}w(v),h(T),B(null),G(null),x("running")},[t,s,n,i,$,W,L]),ce=u.useCallback(()=>{let N=J.current,M=_.current;const R=K.current,j=ae.current,b=N>=R.length-1,v=M>=j.length-1;if(b&&v){w(V=>V?{...V,currentIndex:N,finished:!0}:null),h(V=>V?{...V,currentIndex:M,finished:!0}:null);const T=W(F.current,E.current);B(T),$&&G($===T),x("finished"),L();return}b||(N++,J.current=N,g&&H(N,R.length,-.8)),v||(M++,_.current=M,g&&H(M,j.length,.8)),w(T=>T?{...T,currentIndex:N,finished:N>=R.length-1}:null),h(T=>T?{...T,currentIndex:M,finished:M>=j.length-1}:null)},[g,$,W,H,L]);u.useEffect(()=>{if(m!=="running"){Y();return}let N=0;const M=R=>{R-N>=r&&(N=R,ce()),P.current=requestAnimationFrame(M)};return P.current=requestAnimationFrame(M),Y},[m,r,ce,Y]);const Q=u.useCallback(()=>{m==="running"&&x("paused")},[m]),A=u.useCallback(()=>{m==="paused"&&x("running")},[m]),k=u.useCallback(()=>{Y(),y(null),w(null),h(null),B(null),O(null),G(null),x("setup")},[Y]);return{algorithmA:t,setAlgorithmA:a,algorithmB:s,setAlgorithmB:l,mazeType:n,setMazeType:c,gameMode:i,setGameMode:o,speed:r,setSpeed:d,status:m,soundEnabled:g,toggleSound:q,grid:f,stateA:C,stateB:S,winner:z,prediction:$,setPrediction:O,predictionCorrect:re,startBattle:ie,pause:Q,resume:A,reset:k}}function zt(){const[t,a]=u.useState("naive"),[s,l]=u.useState("memoized"),[n,c]=u.useState("fibonacci"),[i,o]=u.useState(15),r=u.useCallback(A=>{c(A);const k=Ne.find(N=>N.value===A);k&&o(k.defaultN)},[]),[d,m]=u.useState("realtime"),[x,g]=u.useState(50),[p,f]=u.useState("setup"),[y,C]=u.useState(!0),[w,S]=u.useState(null),[h,z]=u.useState(null),[B,$]=u.useState(null),[O,re]=u.useState(null),[G,K]=u.useState(null),ae=u.useRef([]),J=u.useRef([]),_=u.useRef(0),P=u.useRef(0),F=u.useRef(null),{playCompareTone:E,playWinTone:H,setEnabled:L}=we(),ee=u.useCallback(A=>{C(A),L(A)},[L]),q=u.useCallback(()=>{F.current&&(cancelAnimationFrame(F.current),F.current=null)},[]),Y=u.useCallback(()=>{const A=Oe(t,i,n),k=Oe(s,i,n);ae.current=A.steps,J.current=k.steps,_.current=0,P.current=0;const N={algorithm:t,steps:A.steps,currentIndex:0,totalCalls:A.totalCalls,totalCacheHits:A.totalCacheHits,maxDepth:A.maxDepth,finalResult:A.finalResult,finished:!1},M={algorithm:s,steps:k.steps,currentIndex:0,totalCalls:k.totalCalls,totalCacheHits:k.totalCacheHits,maxDepth:k.maxDepth,finalResult:k.finalResult,finished:!1};if(d==="turbo"){S({...N,currentIndex:A.steps.length-1,finished:!0}),z({...M,currentIndex:k.steps.length-1,finished:!0});let R="tie";A.totalCalls{let A=_.current,k=P.current;const N=ae.current,M=J.current,R=A>=N.length-1,j=k>=M.length-1;if(R&&j){S(v=>v?{...v,currentIndex:A,finished:!0}:null),z(v=>v?{...v,currentIndex:k,finished:!0}:null);let b="tie";N.lengthb?{...b,currentIndex:A,finished:A>=N.length-1}:null),z(b=>b?{...b,currentIndex:k,finished:k>=M.length-1}:null)},[y,O,E,H]);u.useEffect(()=>{if(p!=="running"){q();return}let A=0;const k=N=>{N-A>=x&&(A=N,W()),F.current=requestAnimationFrame(k)};return F.current=requestAnimationFrame(k),q},[p,x,W,q]);const ie=u.useCallback(()=>{p==="running"&&f("paused")},[p]),ce=u.useCallback(()=>{p==="paused"&&f("running")},[p]),Q=u.useCallback(()=>{q(),S(null),z(null),$(null),re(null),K(null),f("setup")},[q]);return{algorithmA:t,setAlgorithmA:a,algorithmB:s,setAlgorithmB:l,problem:n,changeProblem:r,inputN:i,setInputN:o,gameMode:d,setGameMode:m,speed:x,setSpeed:g,status:p,soundEnabled:y,toggleSound:ee,stateA:w,stateB:h,winner:B,prediction:O,setPrediction:re,predictionCorrect:G,startBattle:Y,pause:ie,resume:ce,reset:Q}}const kt=[{value:"sorting",label:"Sorting",desc:"Bubble, Quick, Merge & more",icon:Ke},{value:"pathfinding",label:"Pathfinding",desc:"BFS, DFS, Dijkstra, A*",icon:Ee},{value:"recursion",label:"Recursion",desc:"Fibonacci, Factorial, Staircase & more",icon:Ve}];function Rt({onSelect:t}){return e.jsxs("div",{className:"flex-1 overflow-y-auto",children:[e.jsxs("section",{className:"flex flex-col items-center justify-center px-6 pt-10 pb-6 text-center",children:[e.jsxs("div",{className:"mb-3 inline-flex items-center gap-2 rounded-full bg-rose-500/10 px-4 py-1.5 ring-1 ring-rose-500/20",children:[e.jsx(Le,{size:14,className:"text-rose-400"}),e.jsx("span",{className:"text-xs font-medium text-rose-300",children:"Algorithm Battles"})]}),e.jsxs("h2",{className:"text-2xl font-extrabold tracking-tight text-white",children:["Choose Your ",e.jsx("span",{className:"bg-gradient-to-r from-rose-400 to-cyan-400 bg-clip-text text-transparent",children:"Arena"})]}),e.jsx("p",{className:"mt-2 max-w-md text-sm text-slate-400",children:"Pick a battle category to pit two algorithms head-to-head."})]}),e.jsx("section",{className:"px-4 pb-10",children:e.jsx("div",{className:"mx-auto max-w-lg grid grid-cols-1 gap-3",children:kt.map(({value:a,label:s,desc:l,icon:n})=>e.jsxs("button",{onClick:()=>t(a),className:"group flex items-center gap-4 rounded-xl border border-slate-700/50 bg-slate-900/60 p-5 text-left backdrop-blur-sm transition-all hover:border-slate-600/60 hover:bg-slate-900/80 hover:scale-[1.01] active:scale-[0.99]",children:[e.jsx("div",{className:"flex h-12 w-12 shrink-0 items-center justify-center rounded-xl bg-gradient-to-br from-rose-500/20 to-cyan-500/20 ring-1 ring-white/10",children:e.jsx(n,{size:22,className:"text-white"})}),e.jsxs("div",{children:[e.jsxs("h3",{className:"text-sm font-bold text-white",children:[s," Battles"]}),e.jsx("p",{className:"text-xs text-slate-400 mt-0.5",children:l})]})]},a))})})]})}function Tt({battle:t}){const a=de.find(l=>l.value===t.algorithmA).label,s=de.find(l=>l.value===t.algorithmB).label;return e.jsxs("div",{className:"flex-1 overflow-y-auto",children:[e.jsxs("section",{className:"flex flex-col items-center px-6 pt-8 pb-4 text-center",children:[e.jsxs("h2",{className:"text-2xl font-extrabold text-white",children:[e.jsx("span",{className:"bg-gradient-to-r from-rose-400 to-orange-400 bg-clip-text text-transparent",children:a})," ","vs"," ",e.jsx("span",{className:"bg-gradient-to-r from-cyan-400 to-blue-400 bg-clip-text text-transparent",children:s})]}),e.jsx("p",{className:"text-xs text-slate-500 mt-1",children:"Race to find a path on the same random grid"})]}),e.jsx("section",{className:"px-4 pb-8",children:e.jsxs("div",{className:"mx-auto max-w-2xl space-y-4",children:[e.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:["A","B"].map(l=>e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsxs("h3",{className:`text-xs font-semibold uppercase tracking-wider ${l==="A"?"text-rose-400":"text-cyan-400"} mb-3`,children:["Algorithm ",l]}),e.jsx("div",{className:"grid grid-cols-2 gap-1.5",children:de.map(n=>e.jsx("button",{onClick:()=>l==="A"?t.setAlgorithmA(n.value):t.setAlgorithmB(n.value),className:`rounded-lg px-2 py-2 text-[11px] font-medium transition-all ${(l==="A"?t.algorithmA:t.algorithmB)===n.value?l==="A"?"bg-rose-500/20 text-rose-300 ring-1 ring-rose-500/40":"bg-cyan-500/20 text-cyan-300 ring-1 ring-cyan-500/40":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50"}`,children:n.label},n.value))})]},l))}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Maze Type"}),e.jsx("div",{className:"grid grid-cols-3 gap-1.5",children:rt.map(l=>e.jsx("button",{onClick:()=>t.setMazeType(l.value),className:`rounded-lg px-2 py-2 text-[11px] font-medium transition-all ${t.mazeType===l.value?"bg-emerald-500/20 text-emerald-300 ring-1 ring-emerald-500/40":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50"}`,children:l.label},l.value))})]}),e.jsx(We,{gameMode:t.gameMode,setGameMode:t.setGameMode,speed:t.speed,setSpeed:t.setSpeed,soundEnabled:t.soundEnabled,toggleSound:t.toggleSound,prediction:t.prediction,setPrediction:t.setPrediction,nameA:a,nameB:s}),e.jsxs("button",{onClick:t.startBattle,disabled:t.gameMode==="prediction"&&!t.prediction,className:"w-full flex items-center justify-center gap-2 rounded-xl bg-gradient-to-r from-rose-500/20 to-cyan-500/20 px-6 py-4 text-base font-bold text-white ring-1 ring-white/10 transition-all hover:from-rose-500/30 hover:to-cyan-500/30 active:scale-[0.98] disabled:opacity-40 disabled:cursor-not-allowed",children:[e.jsx(Ee,{size:18,className:"text-rose-300"})," Start Battle"]})]})})]})}function $t({battle:t}){const a=ue.find(n=>n.value===t.algorithmA).label,s=ue.find(n=>n.value===t.algorithmB).label,l=Ne.find(n=>n.value===t.problem);return e.jsxs("div",{className:"flex-1 overflow-y-auto",children:[e.jsxs("section",{className:"flex flex-col items-center px-6 pt-8 pb-4 text-center",children:[e.jsxs("h2",{className:"text-2xl font-extrabold text-white",children:[e.jsx("span",{className:"bg-gradient-to-r from-rose-400 to-orange-400 bg-clip-text text-transparent",children:a})," ","vs"," ",e.jsx("span",{className:"bg-gradient-to-r from-cyan-400 to-blue-400 bg-clip-text text-transparent",children:s})]}),e.jsx("p",{className:"text-xs text-slate-500 mt-1",children:l.desc})]}),e.jsx("section",{className:"px-4 pb-8",children:e.jsxs("div",{className:"mx-auto max-w-2xl space-y-4",children:[e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Problem"}),e.jsx("div",{className:"grid grid-cols-2 sm:grid-cols-4 gap-1.5",children:Ne.map(n=>e.jsxs("button",{onClick:()=>t.changeProblem(n.value),className:`rounded-lg px-2 py-2 text-[11px] font-medium transition-all ${t.problem===n.value?"bg-amber-500/20 text-amber-300 ring-1 ring-amber-500/40":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50"}`,children:[e.jsx("span",{className:"block font-semibold",children:n.label}),e.jsx("span",{className:"block text-[9px] text-slate-500 mt-0.5",children:n.desc})]},n.value))})]}),e.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:["A","B"].map(n=>e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsxs("h3",{className:`text-xs font-semibold uppercase tracking-wider ${n==="A"?"text-rose-400":"text-cyan-400"} mb-3`,children:["Algorithm ",n]}),e.jsx("div",{className:"space-y-1.5",children:ue.map(c=>e.jsx("button",{onClick:()=>n==="A"?t.setAlgorithmA(c.value):t.setAlgorithmB(c.value),className:`w-full rounded-lg px-3 py-2 text-[11px] font-medium transition-all text-left ${(n==="A"?t.algorithmA:t.algorithmB)===c.value?n==="A"?"bg-rose-500/20 text-rose-300 ring-1 ring-rose-500/40":"bg-cyan-500/20 text-cyan-300 ring-1 ring-cyan-500/40":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50"}`,children:c.label},c.value))})]},n))}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Input"}),e.jsxs("div",{className:"flex items-center justify-between mb-1",children:[e.jsx("span",{className:"text-xs text-slate-500",children:l.inputLabel}),e.jsx("span",{className:"text-sm font-mono font-bold text-indigo-300",children:t.inputN})]}),e.jsx("input",{type:"range",min:l.inputMin,max:l.inputMax,value:t.inputN,onChange:n=>t.setInputN(Number(n.target.value)),className:"w-full accent-indigo-500"}),e.jsx("p",{className:"text-[10px] text-slate-500 mt-1",children:t.problem==="fibonacci"||t.problem==="staircase"?"⚠️ Naive recursive is exponential — large N generates many steps":t.problem==="coin-change"?"⚠️ Naive coin change branches 3 ways per call — grows very fast":"⚠️ Factorial is linear — naive and memoized are similar here"})]}),e.jsx(We,{gameMode:t.gameMode,setGameMode:t.setGameMode,speed:t.speed,setSpeed:t.setSpeed,soundEnabled:t.soundEnabled,toggleSound:t.toggleSound,prediction:t.prediction,setPrediction:t.setPrediction,nameA:a,nameB:s}),e.jsxs("button",{onClick:t.startBattle,disabled:t.gameMode==="prediction"&&!t.prediction,className:"w-full flex items-center justify-center gap-2 rounded-xl bg-gradient-to-r from-rose-500/20 to-cyan-500/20 px-6 py-4 text-base font-bold text-white ring-1 ring-white/10 transition-all hover:from-rose-500/30 hover:to-cyan-500/30 active:scale-[0.98] disabled:opacity-40 disabled:cursor-not-allowed",children:[e.jsx(Ve,{size:18,className:"text-rose-300"})," Start Battle"]})]})})]})}function We({gameMode:t,setGameMode:a,speed:s,setSpeed:l,soundEnabled:n,toggleSound:c,prediction:i,setPrediction:o,nameA:r,nameB:d}){const m=[{value:"realtime",label:"Real-Time"},{value:"turbo",label:"Turbo"},{value:"prediction",label:"Prediction"}];return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Game Mode"}),e.jsx("div",{className:"grid grid-cols-3 gap-1.5",children:m.map(x=>e.jsx("button",{onClick:()=>a(x.value),className:`rounded-lg px-2 py-2 text-[11px] font-semibold transition-all ${t===x.value?"bg-violet-500/20 text-violet-300 ring-1 ring-violet-500/40":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50"}`,children:x.label},x.value))})]}),t==="prediction"&&e.jsxs("div",{className:"rounded-xl border border-amber-500/20 bg-amber-500/5 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-amber-400 mb-3",children:"Your Prediction"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("button",{onClick:()=>o("A"),className:`flex-1 rounded-lg px-3 py-2.5 text-sm font-medium transition-all ${i==="A"?"bg-rose-500/20 text-rose-300 ring-1 ring-rose-500/40":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50"}`,children:r}),e.jsx("button",{onClick:()=>o("B"),className:`flex-1 rounded-lg px-3 py-2.5 text-sm font-medium transition-all ${i==="B"?"bg-cyan-500/20 text-cyan-300 ring-1 ring-cyan-500/40":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50"}`,children:d})]})]}),e.jsxs("div",{className:"flex gap-4",children:[e.jsxs("div",{className:"flex-1 rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Speed"}),e.jsx("div",{className:"flex gap-1.5",children:me.map(x=>e.jsx("button",{onClick:()=>l(x.value),className:`flex-1 rounded-lg px-2 py-2 text-[11px] font-medium transition-all ${s===x.value?"bg-emerald-500/20 text-emerald-300 ring-1 ring-emerald-500/40":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50"}`,children:x.label},x.value))})]}),e.jsxs("button",{onClick:()=>c(!n),className:`shrink-0 flex flex-col items-center justify-center rounded-xl px-4 transition-all ${n?"bg-indigo-500/15 text-indigo-300 ring-1 ring-indigo-500/30":"bg-slate-800/60 text-slate-500 ring-1 ring-slate-700/40"}`,children:[n?"🔊":"🔇",e.jsx("span",{className:"text-[10px] mt-1",children:n?"On":"Off"})]})]})]})}function _t(){const[t,a]=u.useState(null),s=At(),l=Mt(),n=zt(),c=()=>{s.reset(),l.reset(),n.reset(),a(null)};if(!t)return e.jsx(Rt,{onSelect:a});const i=e.jsxs("button",{onClick:c,className:"fixed top-16 left-4 z-10 flex items-center gap-1 rounded-lg bg-slate-800/80 px-3 py-1.5 text-xs font-medium text-slate-400 ring-1 ring-slate-700/50 backdrop-blur-sm hover:bg-slate-700/80 hover:text-slate-300",children:[e.jsx(Ye,{size:12})," Back"]});if(t==="sorting"){if(s.status==="setup")return e.jsxs(e.Fragment,{children:[i,e.jsx(tt,{algorithmA:s.algorithmA,algorithmB:s.algorithmB,inputSize:s.inputSize,inputType:s.inputType,gameMode:s.gameMode,speed:s.speed,soundEnabled:s.soundEnabled,prediction:s.prediction,onSetAlgorithmA:s.setAlgorithmA,onSetAlgorithmB:s.setAlgorithmB,onSetInputSize:s.setInputSize,onSetInputType:s.setInputType,onSetGameMode:s.setGameMode,onSetSpeed:s.setSpeed,onToggleSound:s.toggleSound,onSetPrediction:s.setPrediction,onStart:s.startBattle})]});if(s.stateA&&s.stateB)return e.jsxs(e.Fragment,{children:[i,e.jsx(at,{stateA:s.stateA,stateB:s.stateB,status:s.status,winner:s.winner,prediction:s.prediction,predictionCorrect:s.predictionCorrect,inputType:s.inputType,speed:s.speed,soundEnabled:s.soundEnabled,metricsHistory:s.metricsHistory,onPause:s.pause,onResume:s.resume,onReset:s.reset,onSetSpeed:s.setSpeed,onToggleSound:s.toggleSound})]})}if(t==="pathfinding"){if(l.status==="setup")return e.jsxs(e.Fragment,{children:[i,e.jsx(Tt,{battle:l})]});if(l.stateA&&l.stateB&&l.grid)return e.jsxs(e.Fragment,{children:[i,e.jsx(xt,{grid:l.grid,stateA:l.stateA,stateB:l.stateB,status:l.status,winner:l.winner,prediction:l.prediction,predictionCorrect:l.predictionCorrect,speed:l.speed,soundEnabled:l.soundEnabled,onPause:l.pause,onResume:l.resume,onReset:l.reset,onSetSpeed:l.setSpeed,onToggleSound:l.toggleSound})]})}if(t==="recursion"){if(n.status==="setup")return e.jsxs(e.Fragment,{children:[i,e.jsx($t,{battle:n})]});if(n.stateA&&n.stateB)return e.jsxs(e.Fragment,{children:[i,e.jsx(Ct,{stateA:n.stateA,stateB:n.stateB,status:n.status,winner:n.winner,prediction:n.prediction,predictionCorrect:n.predictionCorrect,speed:n.speed,soundEnabled:n.soundEnabled,problem:n.problem,onPause:n.pause,onResume:n.resume,onReset:n.reset,onSetSpeed:n.setSpeed,onToggleSound:n.toggleSound})]})}return null}export{_t as default}; diff --git a/docs/assets/DijkstraGamePage-DPGMG41Z.js b/docs/assets/DijkstraGamePage-DPGMG41Z.js new file mode 100644 index 0000000..782c7cd --- /dev/null +++ b/docs/assets/DijkstraGamePage-DPGMG41Z.js @@ -0,0 +1 @@ +import{c as Ge,r as x,j as e,E as Ve}from"./index-BfWfBQOp.js";import{M as Be}from"./map-DMi7QK0E.js";import{S as Fe}from"./shuffle-Ri9xSsK2.js";import{C as Oe,a as _e}from"./chevron-right-CNA9GG_w.js";import{P as Le}from"./pause-Bg-8t1oj.js";import{P as Pe}from"./play-WRQgdyAG.js";import{R as ue}from"./route-CNnmHrEb.js";import{T as qe}from"./timer-t0ca9c1j.js";import{T as We}from"./trophy-CUioHXrM.js";import{R as He}from"./rotate-ccw-EKzY5q_W.js";import{E as Ue}from"./eye-off-B7FP-9s5.js";import{V as Ye,a as Qe}from"./volume-x-ChIHiT28.js";import{g as Ze}from"./audioContext-NbgqvQGz.js";const Xe=[["path",{d:"M9 14 4 9l5-5",key:"102s5s"}],["path",{d:"M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5a5.5 5.5 0 0 1-5.5 5.5H11",key:"f3b9sd"}]],Je=Ge("undo-2",Xe),L=20,Ke=["#1e293b","#0f3b3f","#312e81","#3b2416","#064e3b"];function et({graph:s,startNode:n,endNode:d,playerPath:r,optimalPath:f,showOptimal:l,currentAlgoStep:p,selectingPhase:j,onClickNode:a}){const i=x.useMemo(()=>{const t=new Set;for(let o=0;o{const t=new Set;if(l)for(let o=0;o{const t={};for(const o of s.nodes)t[o.id]={x:o.x,y:o.y};return t},[s.nodes]),A=j==="start"||j==="end"?"cursor-crosshair":"cursor-pointer",z=j==="start"?"Click an intersection to set START DEPOT":j==="end"?"Click an intersection to set DELIVERY DESTINATION":null,$=[...p?.queue??[]].sort((t,o)=>t.distance-o.distance).slice(0,5),C={intersections:s.nodes.length,roads:s.edges.length,avgTraffic:s.edges.length?Math.round(s.edges.reduce((t,o)=>t+o.weight,0)/s.edges.length):0};return e.jsxs("div",{className:`relative flex-1 w-full overflow-hidden rounded-[1.5rem] border border-slate-700/50 bg-slate-950/90 p-3 shadow-2xl shadow-black/40 backdrop-blur-sm ${A}`,children:[e.jsx("div",{className:"absolute inset-0 bg-[radial-gradient(circle_at_20%_10%,rgba(56,189,248,0.14),transparent_28%),radial-gradient(circle_at_80%_80%,rgba(34,197,94,0.1),transparent_30%)]"}),z&&e.jsx("div",{className:"absolute top-5 left-1/2 z-20 -translate-x-1/2 rounded-full bg-slate-950/90 px-4 py-2 text-xs font-semibold uppercase tracking-wide text-sky-200 ring-1 ring-sky-500/30 shadow-xl shadow-sky-950/40 animate-pulse",children:z}),e.jsxs("div",{className:"absolute left-5 top-5 z-10 rounded-2xl border border-slate-700/60 bg-slate-950/85 px-4 py-3 shadow-xl shadow-black/30 backdrop-blur-sm",children:[e.jsx("div",{className:"text-[10px] font-semibold uppercase tracking-[0.24em] text-slate-500",children:"City Routing Map"}),e.jsxs("div",{className:"mt-2 flex gap-3 text-[11px] text-slate-300",children:[e.jsxs("span",{children:[e.jsx("strong",{className:"font-mono text-white",children:C.intersections})," intersections"]}),e.jsxs("span",{children:[e.jsx("strong",{className:"font-mono text-white",children:C.roads})," roads"]}),e.jsxs("span",{children:[e.jsx("strong",{className:"font-mono text-white",children:C.avgTraffic})," avg min"]})]})]}),e.jsxs("div",{className:"absolute right-5 top-5 z-10 hidden rounded-2xl border border-slate-700/60 bg-slate-950/85 px-4 py-3 shadow-xl shadow-black/30 backdrop-blur-sm sm:block",children:[e.jsx("div",{className:"mb-2 text-[10px] font-semibold uppercase tracking-[0.24em] text-slate-500",children:"Legend"}),e.jsxs("div",{className:"grid grid-cols-2 gap-x-3 gap-y-1.5 text-[10px] text-slate-400",children:[e.jsx(F,{color:"bg-yellow-300",label:"Depot"}),e.jsx(F,{color:"bg-orange-400",label:"Dropoff"}),e.jsx(F,{color:"bg-indigo-400",label:"Your route"}),e.jsx(F,{color:"bg-emerald-400",label:"Best route"}),e.jsx(F,{color:"bg-sky-400",label:"Scanning"}),e.jsx(F,{color:"bg-slate-500",label:"Unvisited"})]})]}),p&&e.jsxs("div",{className:"absolute bottom-5 left-5 z-10 max-w-sm rounded-2xl border border-slate-700/60 bg-slate-950/90 p-4 shadow-xl shadow-black/35 backdrop-blur-sm",children:[e.jsx("div",{className:"mb-1 text-[10px] font-semibold uppercase tracking-[0.24em] text-sky-300",children:"Dijkstra Live Scan"}),e.jsx("p",{className:"text-xs leading-relaxed text-slate-300",children:p.description}),$.length>0&&e.jsx("div",{className:"mt-3 flex flex-wrap gap-1.5",children:$.map(t=>e.jsxs("span",{className:"rounded-full bg-sky-500/10 px-2 py-1 text-[10px] font-mono font-semibold text-sky-300 ring-1 ring-sky-500/25",children:[t.id,": ",t.distance]},t.id))})]}),e.jsxs("svg",{viewBox:"0 0 820 400",className:"relative z-0 h-full w-full rounded-[1.15rem]",preserveAspectRatio:"xMidYMid meet",children:[e.jsxs("defs",{children:[e.jsx("pattern",{id:"dijkstra-grid",width:"32",height:"32",patternUnits:"userSpaceOnUse",children:e.jsx("path",{d:"M32 0H0V32",fill:"none",stroke:"#334155",strokeWidth:"0.7",opacity:"0.24"})}),e.jsxs("filter",{id:"soft-glow",x:"-40%",y:"-40%",width:"180%",height:"180%",children:[e.jsx("feGaussianBlur",{stdDeviation:"4",result:"blur"}),e.jsxs("feMerge",{children:[e.jsx("feMergeNode",{in:"blur"}),e.jsx("feMergeNode",{in:"SourceGraphic"})]})]}),e.jsx("filter",{id:"pin-shadow",x:"-60%",y:"-60%",width:"220%",height:"220%",children:e.jsx("feDropShadow",{dx:"0",dy:"7",stdDeviation:"5",floodColor:"#020617",floodOpacity:"0.65"})})]}),e.jsx("rect",{x:"0",y:"0",width:"820",height:"400",rx:"24",fill:"#020617"}),e.jsx("rect",{x:"0",y:"0",width:"820",height:"400",rx:"24",fill:"url(#dijkstra-grid)"}),[0,1,2,3,4].map(t=>e.jsx("rect",{x:30+t*155,y:t%2===0?38:238,width:112+t%2*34,height:78,rx:18,fill:Ke[t],opacity:"0.26"},t)),e.jsx("path",{d:"M612 40C690 68 760 70 800 42V132C744 154 684 146 612 118Z",fill:"#075985",opacity:"0.18"}),e.jsx("path",{d:"M38 336C96 302 150 306 206 338C154 374 91 382 38 356Z",fill:"#166534",opacity:"0.22"}),s.edges.map(t=>{const o=N[t.source],h=N[t.destination];if(!o||!h)return null;const T=S(t.source,t.destination),E=M(t.source,t.destination);return e.jsxs("g",{children:[e.jsx("line",{x1:o.x,y1:o.y,x2:h.x,y2:h.y,stroke:"#020617",strokeWidth:17,strokeLinecap:"round",opacity:.7}),e.jsx("line",{x1:o.x,y1:o.y,x2:h.x,y2:h.y,stroke:"#1e293b",strokeWidth:13,strokeLinecap:"round"}),e.jsx("line",{x1:o.x,y1:o.y,x2:h.x,y2:h.y,stroke:"#475569",strokeWidth:8,strokeLinecap:"round",opacity:.78}),e.jsx("line",{x1:o.x,y1:o.y,x2:h.x,y2:h.y,stroke:"#cbd5e1",strokeWidth:1.2,strokeLinecap:"round",strokeDasharray:"5 8",opacity:.34}),(i.has([t.source,t.destination].sort().join("-"))||m.has([t.source,t.destination].sort().join("-"))||u&&[u.from,u.to].sort().join("-")===[t.source,t.destination].sort().join("-"))&&e.jsx("line",{x1:o.x,y1:o.y,x2:h.x,y2:h.y,stroke:T,strokeWidth:E+6,strokeLinecap:"round",opacity:.34,filter:"url(#soft-glow)"})]},`${t.id}-road-base`)}),s.edges.map(t=>{const o=N[t.source],h=N[t.destination];if(!o||!h)return null;const T=S(t.source,t.destination),E=M(t.source,t.destination),k=(o.x+h.x)/2,I=(o.y+h.y)/2,b=[t.source,t.destination].sort().join("-"),R=i.has(b)||m.has(b)||u&&[u.from,u.to].sort().join("-")===b;return e.jsxs("g",{children:[e.jsx("line",{x1:o.x,y1:o.y,x2:h.x,y2:h.y,stroke:T,strokeWidth:R?E+2:1.4,strokeLinecap:"round",opacity:R?.96:.18,strokeDasharray:m.has(b)&&!i.has(b)?"9 6":void 0}),e.jsx("rect",{x:k-17,y:I-11,width:34,height:22,rx:8,fill:"#020617",fillOpacity:.92,stroke:R?T:"#475569",strokeWidth:.8,filter:"url(#pin-shadow)"}),e.jsxs("text",{x:k,y:I+.5,textAnchor:"middle",dominantBaseline:"central",fontSize:9,fontWeight:800,fontFamily:"ui-monospace, monospace",fill:R?T:"#cbd5e1",fillOpacity:.95,children:[t.weight,"m"]})]},t.id)}),s.nodes.map(t=>{const o=y(t.id),h=v(t.id),T=p?.distances[t.id],E=T!==void 0&&T!==1/0?T.toString():"",k=t.id===n,I=t.id===d,b=p&&t.id===c,R=p&&w.includes(t.id);return e.jsxs("g",{onClick:()=>a(t.id),className:"cursor-pointer",children:[e.jsx("circle",{cx:t.x,cy:t.y,r:L+12,fill:o,fillOpacity:b?.22:.08,filter:b?"url(#soft-glow)":void 0}),e.jsx("circle",{cx:t.x,cy:t.y,r:L+5,fill:"#020617",stroke:"#0f172a",strokeWidth:7,filter:"url(#pin-shadow)"}),e.jsx("circle",{cx:t.x,cy:t.y,r:L,fill:o,fillOpacity:k||I||b||R?.32:.16,stroke:h,strokeWidth:k||I?4:2.5}),e.jsx("text",{x:t.x,y:t.y+1,textAnchor:"middle",dominantBaseline:"central",fontSize:13,fontWeight:900,fontFamily:"ui-monospace, monospace",fill:o,children:t.id}),(k||I)&&e.jsxs("g",{children:[e.jsx("path",{d:`M${t.x-8} ${t.y-41}h16a7 7 0 0 1 7 7v12a7 7 0 0 1-7 7h-16a7 7 0 0 1-7-7v-12a7 7 0 0 1 7-7Z`,fill:k?"#eab308":"#f97316",opacity:"0.95",filter:"url(#pin-shadow)"}),e.jsx("text",{x:t.x,y:t.y-28,textAnchor:"middle",dominantBaseline:"central",fontSize:9,fontWeight:900,fontFamily:"ui-monospace, monospace",fill:"#020617",children:k?"START":"END"})]}),E&&e.jsxs("g",{children:[e.jsx("rect",{x:t.x-20,y:t.y+L+8,width:40,height:16,rx:8,fill:"#020617",stroke:"#334155"}),e.jsxs("text",{x:t.x,y:t.y+L+16.5,textAnchor:"middle",dominantBaseline:"central",fontSize:8,fontWeight:700,fontFamily:"ui-monospace, monospace",fill:"#94a3b8",children:["ETA ",E]})]})]},t.id)})]})]})}function F({color:s,label:n}){return e.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[e.jsx("span",{className:`h-2 w-2 rounded-full ${s}`}),n]})}const xe={explore:{name:"Free Explore",description:"Pick any route and compare your cost to the optimal Dijkstra path."},visualize:{name:"Visualizer",description:"Watch Dijkstra's algorithm run step-by-step with priority queue updates."},race:{name:"Race Mode",description:"Beat the algorithm! Find the shortest path as fast as you can."}},J={title:"Dijkstra Delivery Simulator",subtitle:"Based on Edsger W. Dijkstra's shortest-path algorithm",what:"You're a delivery driver navigating a city. Intersections are nodes, roads are edges, and traffic time is the weight. Find the shortest route from start to destination — then see how your path compares to Dijkstra's optimal solution.",skills:["Graph Theory","Shortest Path","Greedy Algorithms","Priority Queues"]},tt=["explore","visualize","race"],st=[{label:"Slow",value:800},{label:"Med",value:400},{label:"Fast",value:150}];function it(s){const n=Math.floor(s/60),d=s%60;return`${n}:${d.toString().padStart(2,"0")}`}function nt({mode:s,mapType:n,startNode:d,endNode:r,playerPath:f,playerCost:l,optimalCost:p,showOptimal:j,currentAlgoStep:a,algoStepIndex:i,algoStepsTotal:m,isAlgoRunning:w,algoSpeed:c,score:u,timer:y,isComplete:v,lastError:S,soundEnabled:M,selectingPhase:N,onChangeMode:A,onNewMap:z,onReset:$,onToggleOptimal:C,onUndoLastStep:t,onStepForward:o,onStepBack:h,onAutoPlay:T,onSetAlgoSpeed:E,onToggleSound:k}){const I=N==="start"?"Choose depot":N==="end"?"Choose destination":s==="visualize"?"Run algorithm scan":"Build delivery route";return e.jsxs("div",{className:"flex w-full shrink-0 flex-col gap-4 overflow-y-auto pr-1 xl:w-80",children:[e.jsxs("div",{className:"rounded-2xl border border-sky-500/20 bg-slate-950/75 p-4 shadow-2xl shadow-black/30 backdrop-blur-sm",children:[e.jsxs("div",{className:"mb-3 flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-bold text-sky-200",children:J.title}),e.jsx("p",{className:"text-[10px] text-slate-500 italic",children:J.subtitle})]}),e.jsx("span",{className:"rounded-full bg-sky-500/10 px-2 py-1 text-[9px] font-bold uppercase tracking-wider text-sky-300 ring-1 ring-sky-500/25",children:"Dispatch"})]}),e.jsx("p",{className:"text-xs text-slate-400 leading-relaxed",children:J.what}),e.jsx("div",{className:"mt-2 flex flex-wrap gap-1.5",children:J.skills.map(b=>e.jsx("span",{className:"inline-flex items-center rounded-full bg-violet-500/10 px-2 py-0.5 text-[10px] font-medium text-violet-400 ring-1 ring-violet-500/20",children:b},b))})]}),e.jsxs("div",{className:"rounded-2xl border border-slate-700/50 bg-slate-950/75 p-4 shadow-xl shadow-black/20 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Game Mode"}),e.jsx("div",{className:"grid gap-2",children:tt.map(b=>e.jsxs("button",{onClick:()=>A(b),className:`rounded-xl px-3 py-2 text-left transition-all duration-200 ${s===b?"bg-indigo-500/20 text-indigo-200 ring-1 ring-indigo-500/40":"bg-slate-900/70 text-slate-400 ring-1 ring-slate-800/80 hover:bg-slate-800/80 hover:text-slate-300"}`,children:[e.jsx("span",{className:"block text-xs font-bold",children:xe[b].name}),e.jsx("span",{className:"mt-0.5 block text-[10px] leading-snug opacity-70",children:xe[b].description})]},b))})]}),e.jsxs("div",{className:"rounded-2xl border border-slate-700/50 bg-slate-950/75 p-4 shadow-xl shadow-black/20 backdrop-blur-sm",children:[e.jsxs("div",{className:"mb-3 flex items-center justify-between",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400",children:"Map"}),e.jsx("span",{className:"rounded-full bg-slate-900 px-2 py-0.5 text-[9px] font-mono uppercase text-slate-400 ring-1 ring-slate-800",children:n})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsxs("button",{onClick:()=>z("predefined"),className:`flex items-center justify-center gap-1.5 rounded-xl px-3 py-2 text-xs font-medium transition-all ${n==="predefined"?"bg-sky-500/15 text-sky-300 ring-1 ring-sky-500/30":"bg-slate-900/70 text-slate-400 ring-1 ring-slate-800/80 hover:bg-slate-800/80 hover:text-slate-300"}`,children:[e.jsx(Be,{size:12})," Preset"]}),e.jsxs("button",{onClick:()=>z("random"),className:`flex items-center justify-center gap-1.5 rounded-xl px-3 py-2 text-xs font-medium transition-all ${n==="random"?"bg-sky-500/15 text-sky-300 ring-1 ring-sky-500/30":"bg-slate-900/70 text-slate-400 ring-1 ring-slate-800/80 hover:bg-slate-800/80 hover:text-slate-300"}`,children:[e.jsx(Fe,{size:12})," Random"]})]})]}),e.jsxs("div",{className:"rounded-2xl border border-emerald-500/20 bg-slate-950/75 p-4 shadow-xl shadow-black/20 backdrop-blur-sm",children:[e.jsxs("div",{className:"mb-3 flex items-center justify-between",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400",children:"Mission"}),e.jsx("span",{className:"rounded-full bg-emerald-500/10 px-2 py-0.5 text-[9px] font-bold uppercase tracking-wider text-emerald-300 ring-1 ring-emerald-500/25",children:I})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsx(fe,{label:"Depot",value:d??"unset",tone:"yellow"}),e.jsx(fe,{label:"Dropoff",value:r??"unset",tone:"orange"})]}),f.length>0&&e.jsxs("div",{className:"mt-3 rounded-xl bg-slate-900/70 p-3 ring-1 ring-slate-800/80",children:[e.jsx("p",{className:"mb-2 text-[10px] font-semibold uppercase tracking-wider text-slate-500",children:"Route manifest"}),e.jsx("div",{className:"flex flex-wrap gap-1",children:f.map((b,R)=>e.jsx("span",{className:"inline-flex items-center rounded-md bg-indigo-500/15 px-1.5 py-0.5 text-[10px] font-mono font-semibold text-indigo-300 ring-1 ring-indigo-500/20",children:b},`${b}-${R}`))})]})]}),s==="visualize"&&d&&r&&e.jsxs("div",{className:"rounded-2xl border border-slate-700/50 bg-slate-950/75 p-4 shadow-xl shadow-black/20 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Algorithm"}),e.jsxs("div",{className:"flex gap-2 mb-3",children:[e.jsxs("button",{onClick:h,disabled:i<=0,className:"flex-1 flex items-center justify-center gap-1 rounded-xl bg-slate-900/70 px-2 py-2 text-xs font-medium text-slate-400 ring-1 ring-slate-800/80 hover:bg-slate-800/80 hover:text-slate-300 disabled:opacity-30 disabled:cursor-not-allowed",children:[e.jsx(Oe,{size:14})," Prev"]}),e.jsx("button",{onClick:T,className:`flex-1 flex items-center justify-center gap-1 rounded-xl px-2 py-2 text-xs font-medium transition-all ${w?"bg-amber-500/20 text-amber-300 ring-1 ring-amber-500/30":"bg-indigo-500/20 text-indigo-300 ring-1 ring-indigo-500/30 hover:bg-indigo-500/30"}`,children:w?e.jsxs(e.Fragment,{children:[e.jsx(Le,{size:14})," Pause"]}):e.jsxs(e.Fragment,{children:[e.jsx(Pe,{size:14})," Play"]})}),e.jsxs("button",{onClick:o,disabled:i>=m-1,className:"flex-1 flex items-center justify-center gap-1 rounded-xl bg-slate-900/70 px-2 py-2 text-xs font-medium text-slate-400 ring-1 ring-slate-800/80 hover:bg-slate-800/80 hover:text-slate-300 disabled:opacity-30 disabled:cursor-not-allowed",children:["Next ",e.jsx(_e,{size:14})]})]}),e.jsx("div",{className:"flex gap-1 mb-2",children:st.map(b=>e.jsx("button",{onClick:()=>E(b.value),className:`flex-1 rounded-md px-2 py-1 text-[10px] font-medium transition-all ${c===b.value?"bg-indigo-500/20 text-indigo-300 ring-1 ring-indigo-500/30":"bg-slate-800/50 text-slate-500 hover:text-slate-400"}`,children:b.label},b.value))}),m>0&&e.jsxs("div",{className:"flex items-center justify-between text-[10px] text-slate-500",children:[e.jsx("span",{children:"Step"}),e.jsxs("span",{className:"font-mono font-semibold text-indigo-300",children:[Math.max(0,i+1)," / ",m]})]})]}),d&&r&&e.jsxs("div",{className:"rounded-2xl border border-slate-700/50 bg-slate-950/75 p-4 shadow-xl shadow-black/20 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Route Info"}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"flex items-center gap-1.5 text-xs text-slate-500",children:[e.jsx(ue,{size:11})," Your Cost"]}),e.jsx("span",{className:"text-sm font-mono font-bold text-indigo-300",children:l>0||v?l:"—"})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"flex items-center gap-1.5 text-xs text-slate-500",children:[e.jsx(ue,{size:11})," Optimal"]}),e.jsx("span",{className:`text-sm font-mono font-bold ${j?"text-emerald-300":"text-slate-600"}`,children:j?p:"???"})]}),v&&l>0&&e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-xs text-slate-500",children:"Difference"}),e.jsx("span",{className:`text-sm font-mono font-bold ${l===p?"text-emerald-400":"text-amber-400"}`,children:l===p?"Perfect!":`+${l-p}`})]}),s==="race"&&v&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"flex items-center gap-1.5 text-xs text-slate-500",children:[e.jsx(qe,{size:11})," Time"]}),e.jsx("span",{className:"text-sm font-mono font-bold text-sky-300",children:it(y)})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"flex items-center gap-1.5 text-xs text-slate-500",children:[e.jsx(We,{size:11})," Score"]}),e.jsx("span",{className:"text-sm font-mono font-bold text-amber-300",children:u})]})]})]})]}),s==="visualize"&&a&&e.jsxs("div",{className:`rounded-2xl border p-4 shadow-xl shadow-black/20 backdrop-blur-sm ${a.type==="relax"?"border-amber-500/30 bg-amber-500/5":a.type==="done"?"border-emerald-500/30 bg-emerald-500/5":"border-slate-700/50 bg-slate-950/75"}`,children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-2",children:"Current Step"}),e.jsx("p",{className:"text-xs text-slate-300 leading-relaxed",children:a.description}),a.queue.length>0&&e.jsxs("div",{className:"mt-2",children:[e.jsx("p",{className:"text-[10px] text-slate-500 mb-1",children:"Priority Queue:"}),e.jsx("div",{className:"flex flex-wrap gap-1",children:[...a.queue].sort((b,R)=>b.distance-R.distance).map(b=>e.jsxs("span",{className:"inline-flex items-center rounded-md bg-sky-500/10 px-1.5 py-0.5 text-[10px] font-mono text-sky-300 ring-1 ring-sky-500/20",children:[b.id,":",b.distance]},b.id))})]})]}),S&&e.jsx("div",{className:"rounded-xl border border-red-500/30 bg-red-500/5 px-3 py-2 text-center text-xs font-medium text-red-400 shadow-xl shadow-red-950/20 animate-pulse",children:S}),e.jsxs("div",{className:"grid grid-cols-3 gap-2",children:[e.jsxs("button",{onClick:$,className:"flex items-center justify-center gap-1.5 rounded-xl bg-slate-950/80 px-3 py-2 text-xs font-medium text-slate-400 ring-1 ring-slate-800 transition-all hover:bg-slate-800/80 hover:text-slate-300",children:[e.jsx(He,{size:12})," Reset"]}),s!=="visualize"&&e.jsxs("button",{onClick:t,disabled:f.length<=1||v,className:"flex items-center justify-center gap-1.5 rounded-xl bg-slate-950/80 px-3 py-2 text-xs font-medium text-slate-400 ring-1 ring-slate-800 transition-all hover:bg-slate-800/80 hover:text-slate-300 disabled:opacity-30 disabled:cursor-not-allowed",children:[e.jsx(Je,{size:12})," Undo"]}),s!=="visualize"&&d&&r&&e.jsxs("button",{onClick:C,className:`flex items-center justify-center gap-1.5 rounded-xl px-3 py-2 text-xs font-medium transition-all ${j?"bg-emerald-500/15 text-emerald-300 ring-1 ring-emerald-500/30":"bg-slate-950/80 text-slate-400 ring-1 ring-slate-800 hover:bg-slate-800/80 hover:text-slate-300"}`,children:[j?e.jsx(Ve,{size:12}):e.jsx(Ue,{size:12})," Best"]}),e.jsxs("button",{onClick:()=>k(!M),className:`flex items-center justify-center gap-1.5 rounded-xl px-3 py-2 text-xs font-medium transition-all ${M?"bg-indigo-500/15 text-indigo-300 ring-1 ring-indigo-500/30":"bg-slate-950/80 text-slate-400 ring-1 ring-slate-800 hover:bg-slate-800/80 hover:text-slate-300"}`,children:[M?e.jsx(Ye,{size:12}):e.jsx(Qe,{size:12})," Sound"]})]})]})}function fe({label:s,value:n,tone:d}){const r={yellow:"text-yellow-300 ring-yellow-500/25 bg-yellow-500/10",orange:"text-orange-300 ring-orange-500/25 bg-orange-500/10"};return e.jsxs("div",{className:`rounded-xl p-3 ring-1 ${r[d]}`,children:[e.jsx("div",{className:"text-[9px] font-semibold uppercase tracking-wider opacity-65",children:s}),e.jsx("div",{className:"mt-1 font-mono text-lg font-black",children:n})]})}let P=0,q=0;function at(){return String.fromCharCode(65+P++%26)}function ge(){P=0,q=0}function me(){return`e${q++}`}function re(s,n){return Math.sqrt((s.x-n.x)**2+(s.y-n.y)**2)}function pe(s){ge();const n=[rt,ot,lt];return n[s%n.length]()}function rt(){const s=[{id:"A",x:80,y:200,distance:1/0,visited:!1,previous:null},{id:"B",x:220,y:80,distance:1/0,visited:!1,previous:null},{id:"C",x:220,y:320,distance:1/0,visited:!1,previous:null},{id:"D",x:400,y:80,distance:1/0,visited:!1,previous:null},{id:"E",x:400,y:200,distance:1/0,visited:!1,previous:null},{id:"F",x:400,y:320,distance:1/0,visited:!1,previous:null},{id:"G",x:560,y:200,distance:1/0,visited:!1,previous:null},{id:"H",x:700,y:200,distance:1/0,visited:!1,previous:null}];P=8;const n=[{id:"e0",source:"A",destination:"B",weight:4},{id:"e1",source:"A",destination:"C",weight:2},{id:"e2",source:"B",destination:"D",weight:5},{id:"e3",source:"B",destination:"E",weight:10},{id:"e4",source:"C",destination:"E",weight:3},{id:"e5",source:"C",destination:"F",weight:8},{id:"e6",source:"D",destination:"G",weight:2},{id:"e7",source:"E",destination:"G",weight:6},{id:"e8",source:"F",destination:"G",weight:1},{id:"e9",source:"G",destination:"H",weight:3},{id:"e10",source:"D",destination:"E",weight:1}];return q=11,{nodes:s,edges:n}}function ot(){const s=[{id:"A",x:100,y:150,distance:1/0,visited:!1,previous:null},{id:"B",x:250,y:50,distance:1/0,visited:!1,previous:null},{id:"C",x:250,y:250,distance:1/0,visited:!1,previous:null},{id:"D",x:400,y:150,distance:1/0,visited:!1,previous:null},{id:"E",x:550,y:50,distance:1/0,visited:!1,previous:null},{id:"F",x:550,y:250,distance:1/0,visited:!1,previous:null},{id:"G",x:700,y:150,distance:1/0,visited:!1,previous:null}];P=7;const n=[{id:"e0",source:"A",destination:"B",weight:7},{id:"e1",source:"A",destination:"C",weight:3},{id:"e2",source:"B",destination:"D",weight:2},{id:"e3",source:"C",destination:"D",weight:5},{id:"e4",source:"C",destination:"F",weight:12},{id:"e5",source:"D",destination:"E",weight:4},{id:"e6",source:"D",destination:"F",weight:3},{id:"e7",source:"E",destination:"G",weight:1},{id:"e8",source:"F",destination:"G",weight:2},{id:"e9",source:"B",destination:"E",weight:9}];return q=10,{nodes:s,edges:n}}function lt(){const s=[{id:"A",x:80,y:180,distance:1/0,visited:!1,previous:null},{id:"B",x:200,y:60,distance:1/0,visited:!1,previous:null},{id:"C",x:200,y:300,distance:1/0,visited:!1,previous:null},{id:"D",x:350,y:180,distance:1/0,visited:!1,previous:null},{id:"E",x:500,y:60,distance:1/0,visited:!1,previous:null},{id:"F",x:500,y:300,distance:1/0,visited:!1,previous:null},{id:"G",x:650,y:120,distance:1/0,visited:!1,previous:null},{id:"H",x:650,y:240,distance:1/0,visited:!1,previous:null},{id:"I",x:780,y:180,distance:1/0,visited:!1,previous:null}];P=9;const n=[{id:"e0",source:"A",destination:"B",weight:3},{id:"e1",source:"A",destination:"C",weight:6},{id:"e2",source:"A",destination:"D",weight:7},{id:"e3",source:"B",destination:"D",weight:2},{id:"e4",source:"B",destination:"E",weight:8},{id:"e5",source:"C",destination:"D",weight:3},{id:"e6",source:"C",destination:"F",weight:4},{id:"e7",source:"D",destination:"E",weight:2},{id:"e8",source:"D",destination:"F",weight:5},{id:"e9",source:"E",destination:"G",weight:1},{id:"e10",source:"F",destination:"H",weight:2},{id:"e11",source:"G",destination:"I",weight:4},{id:"e12",source:"H",destination:"I",weight:3},{id:"e13",source:"G",destination:"H",weight:2}];return q=14,{nodes:s,edges:n}}function ct(s=12){ge();const n=750,d=360,r=60,f=80,l=[];let p=0;for(;l.lengthre(v,{x:c,y:u})u).filter(c=>c>0));for(;m.size>0;){let c=1/0,u=0,y=0;for(const M of i)for(const N of m){const A=re(l[M],l[N]);A0;){j.sort((c,u)=>c.distance-u.distance);const i=j.shift();if(p.has(i.id))continue;p.add(i.id);const m=[...p];if(r.push({type:"visit",currentNodeId:i.id,description:`Visit node ${i.id} (distance = ${f[i.id]})`,distances:{...f},visited:m,previous:{...l},queue:[...j]}),i.id===d)break;const w=be(s,i.id);for(const c of w){if(p.has(c.id))continue;const u=f[i.id]+c.weight,y=f[c.id];if(uS.id===c.id);v>=0?j[v].distance=u:j.push({id:c.id,distance:u}),r.push({type:"relax",currentNodeId:i.id,description:`Relax edge ${i.id} → ${c.id}: distance updated from ${y===1/0?"∞":y} to ${u}`,distances:{...f},visited:[...p],previous:{...l},queue:[...j],relaxedEdge:{from:i.id,to:c.id,oldDist:y,newDist:u}})}}}const a=je(l,n,d);return r.push({type:"done",currentNodeId:d,description:a.length>0?`Done! Shortest path: ${a.join(" → ")} (cost: ${f[d]})`:`No path found from ${n} to ${d}`,distances:{...f},visited:[...p],previous:{...l},queue:[]}),r}function je(s,n,d){const r=[];let f=d;for(;f!==null&&(r.unshift(f),f!==n);)f=s[f];return r[0]!==n?[]:r}function dt(s,n,d){const r=ye(s,n,d),f=r[r.length-1],l=je(f.previous,n,d),p=f.distances[d]??1/0;return{path:l,cost:p===1/0?-1:p}}function ut(s,n){let d=0;for(let r=0;rl.source===n[r]&&l.destination===n[r+1]||l.destination===n[r]&&l.source===n[r+1]);if(!f)return-1;d+=f.weight}return d}function xt(s,n,d){if(n<=0||s<0)return 0;const r=100,f=(s-n)*5,l=Math.floor(d/3),p=s===n?50:0;return Math.max(0,r-f-l+p)}const he=[329.63,392,440,493.88,523.25,587.33,659.25,783.99];function ft(){const s=x.useRef(!0),n=x.useCallback(()=>Ze(),[]),d=x.useCallback(a=>{s.current=a},[]),r=x.useCallback(a=>{if(!s.current)return;const i=n();if(!i)return;const m=he[a%he.length],w=i.createOscillator(),c=i.createGain();w.type="sine",w.frequency.setValueAtTime(m,i.currentTime),c.gain.setValueAtTime(.1,i.currentTime),c.gain.exponentialRampToValueAtTime(.001,i.currentTime+.25),w.connect(c),c.connect(i.destination),w.start(),w.stop(i.currentTime+.25)},[n]),f=x.useCallback(()=>{if(!s.current)return;const a=n();if(!a)return;const i=a.createOscillator(),m=a.createGain();i.type="triangle",i.frequency.setValueAtTime(600,a.currentTime),i.frequency.setValueAtTime(800,a.currentTime+.08),m.gain.setValueAtTime(.06,a.currentTime),m.gain.exponentialRampToValueAtTime(.001,a.currentTime+.15),i.connect(m),m.connect(a.destination),i.start(),i.stop(a.currentTime+.15)},[n]),l=x.useCallback(()=>{if(!s.current)return;const a=n();if(!a)return;const i=a.createOscillator(),m=a.createGain();i.type="sine",i.frequency.setValueAtTime(520,a.currentTime),m.gain.setValueAtTime(.08,a.currentTime),m.gain.exponentialRampToValueAtTime(.001,a.currentTime+.1),i.connect(m),m.connect(a.destination),i.start(),i.stop(a.currentTime+.1)},[n]),p=x.useCallback(()=>{if(!s.current)return;const a=n();if(!a)return;const i=a.createOscillator(),m=a.createGain();i.type="sawtooth",i.frequency.setValueAtTime(200,a.currentTime),i.frequency.setValueAtTime(140,a.currentTime+.12),m.gain.setValueAtTime(.07,a.currentTime),m.gain.exponentialRampToValueAtTime(.001,a.currentTime+.25),i.connect(m),m.connect(a.destination),i.start(),i.stop(a.currentTime+.25)},[n]),j=x.useCallback(a=>{if(!s.current)return;const i=n();if(!i)return;(a?[523.25,587.33,659.25,783.99,880,1046.5]:[400,350,300]).forEach((w,c)=>{const u=i.createOscillator(),y=i.createGain();u.type="sine",u.frequency.value=w,y.gain.setValueAtTime(.07,i.currentTime+c*.08),y.gain.exponentialRampToValueAtTime(.001,i.currentTime+c*.08+.18),u.connect(y),y.connect(i.destination),u.start(i.currentTime+c*.08),u.stop(i.currentTime+c*.08+.18)})},[n]);return{playVisitTone:r,playRelaxTone:f,playClickTone:l,playErrorTone:p,playCompleteSweep:j,setEnabled:d}}function mt(){const[s,n]=x.useState("explore"),[d,r]=x.useState(()=>pe(0)),[f,l]=x.useState("predefined"),[p,j]=x.useState(0),[a,i]=x.useState(null),[m,w]=x.useState(null),[c,u]=x.useState([]),[y,v]=x.useState(0),[S,M]=x.useState([]),[N,A]=x.useState(0),[z,$]=x.useState(!1),[C,t]=x.useState([]),[o,h]=x.useState(-1),[T,E]=x.useState(!1),k=x.useRef(null),[I,b]=x.useState(500),[R,W]=x.useState(0),[ee,te]=x.useState(0),[oe,se]=x.useState(!1),O=x.useRef(null),[ve,we]=x.useState(!0),[ke,V]=x.useState(null),[ie,le]=x.useState(!1),[H,U]=x.useState("start"),{playVisitTone:Y,playRelaxTone:Q,playClickTone:Z,playErrorTone:ne,playCompleteSweep:G,setEnabled:ce}=ft(),Ne=x.useCallback(g=>{we(g),ce(g)},[ce]);x.useEffect(()=>(oe&&(O.current=window.setInterval(()=>te(g=>g+1),1e3)),()=>{O.current&&clearInterval(O.current)}),[oe]);const Ce=o>=0&&o{if(V(null),H==="start"){i(g),U("end"),Z();return}if(H==="end"){if(g===a){V("Destination must be different from start"),ne();return}w(g),Z();const B=dt(d,a,g);if(M(B.path),A(B.cost),s==="visualize"){const ze=ye(d,a,g);t(ze),h(-1),U("path")}else u([a]),v(0),U("path"),s==="race"&&(se(!0),te(0));return}if(s==="visualize"||c.length===0)return;const D=c[c.length-1];if(g===D)return;const de=be(d,D).find(B=>B.id===g);if(!de){V(`${g} is not adjacent to ${D}`),ne(),setTimeout(()=>V(null),1500);return}Z();const $e=[...c,g],ae=y+de.weight;if(u($e),v(ae),g===m)if(le(!0),se(!1),$(!0),s==="race"){const B=xt(ae,N,ee);W(B),G(ae===N)}else G(!0)},[H,a,m,d,s,c,y,N,ee,Z,ne,G]),Se=x.useCallback(()=>{if(c.length<=1||ie)return;const g=c.slice(0,-1);u(g),v(ut(d,g)),V(null)},[c,d,ie]),Me=x.useCallback(()=>{C.length!==0&&h(g=>{const D=Math.min(g+1,C.length-1),X=C[D];return X.type==="visit"&&Y(D),X.type==="relax"&&Q(),X.type==="done"&&G(!0),D})},[C,Y,Q,G]),De=x.useCallback(()=>{h(g=>Math.max(g-1,0))},[]),Ee=x.useCallback(()=>{if(T){k.current&&clearInterval(k.current),E(!1);return}E(!0);let g=o<0?0:o;k.current=window.setInterval(()=>{if(g>=C.length-1){k.current&&clearInterval(k.current),E(!1);return}g++,h(g);const D=C[g];D.type==="visit"&&Y(g),D.type==="relax"&&Q(),D.type==="done"&&G(!0)},I)},[T,o,C,I,Y,Q,G]),_=x.useCallback(()=>{i(null),w(null),u([]),v(0),M([]),A(0),$(!1),t([]),h(-1),E(!1),W(0),te(0),se(!1),le(!1),V(null),U("start"),k.current&&clearInterval(k.current),O.current&&clearInterval(O.current),r(g=>({...g,nodes:g.nodes.map(D=>({...D,distance:1/0,visited:!1,previous:null}))}))},[]),Ie=x.useCallback(g=>{n(g),_()},[_]),Re=x.useCallback(g=>{if(l(g),g==="predefined"){const D=(p+1)%3;j(D),r(pe(D))}else r(ct(12));_()},[p,_]),Ae=x.useCallback(()=>{!a||!m||$(g=>!g)},[a,m]);return{mode:s,graph:d,mapType:f,startNode:a,endNode:m,playerPath:c,playerCost:y,optimalPath:S,optimalCost:N,showOptimal:z,algoSteps:C,algoStepIndex:o,currentAlgoStep:Ce,isAlgoRunning:T,algoSpeed:I,setAlgoSpeed:b,score:R,timer:ee,isComplete:ie,lastError:ke,soundEnabled:ve,selectingPhase:H,clickNode:Te,undoLastStep:Se,stepAlgoForward:Me,stepAlgoBack:De,autoPlayAlgo:Ee,resetGame:_,changeMode:Ie,newMap:Re,toggleOptimal:Ae,toggleSound:Ne}}function Mt(){const{mode:s,graph:n,mapType:d,startNode:r,endNode:f,playerPath:l,playerCost:p,optimalPath:j,optimalCost:a,showOptimal:i,algoSteps:m,algoStepIndex:w,currentAlgoStep:c,isAlgoRunning:u,algoSpeed:y,setAlgoSpeed:v,score:S,timer:M,isComplete:N,lastError:A,soundEnabled:z,selectingPhase:$,clickNode:C,undoLastStep:t,stepAlgoForward:o,stepAlgoBack:h,autoPlayAlgo:T,resetGame:E,changeMode:k,newMap:I,toggleOptimal:b,toggleSound:R}=mt(),W=r&&f?`${r} -> ${f}`:"Select depot and destination";return e.jsxs("div",{className:"flex flex-1 flex-col overflow-hidden bg-[radial-gradient(circle_at_top_left,rgba(14,165,233,0.16),transparent_30%),radial-gradient(circle_at_bottom_right,rgba(34,197,94,0.12),transparent_28%)]",children:[e.jsx("div",{className:"border-b border-slate-800/70 bg-slate-950/75 px-4 py-3 shadow-lg shadow-black/20 backdrop-blur-sm md:px-6",children:e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-[0.24em] text-sky-400",children:"Shortest Path Command Center"}),e.jsx("h2",{className:"text-lg font-bold text-white",children:"Dijkstra Delivery Simulator"})]}),e.jsxs("div",{className:"ml-auto flex flex-wrap items-center gap-2",children:[e.jsx(K,{label:"Mode",value:s,tone:"indigo"}),e.jsx(K,{label:"Map",value:d,tone:"sky"}),e.jsx(K,{label:"Route",value:W,tone:"emerald"}),N&&e.jsx(K,{label:"Result",value:p===a?"optimal":`+${p-a} min`,tone:p===a?"emerald":"amber"})]})]})}),e.jsxs("div",{className:"flex flex-1 flex-col gap-4 overflow-auto p-4 md:p-6 xl:flex-row",children:[e.jsx("div",{className:"order-last flex min-h-[620px] flex-1 flex-col gap-4 xl:order-first xl:min-h-0",children:e.jsx(et,{graph:n,startNode:r,endNode:f,playerPath:l,optimalPath:j,showOptimal:i,currentAlgoStep:c,selectingPhase:$,onClickNode:C})}),e.jsx(nt,{mode:s,mapType:d,startNode:r,endNode:f,playerPath:l,playerCost:p,optimalCost:a,showOptimal:i,currentAlgoStep:c,algoStepIndex:w,algoStepsTotal:m.length,isAlgoRunning:u,algoSpeed:y,score:S,timer:M,isComplete:N,lastError:A,soundEnabled:z,selectingPhase:$,onChangeMode:k,onNewMap:I,onReset:E,onToggleOptimal:b,onUndoLastStep:t,onStepForward:o,onStepBack:h,onAutoPlay:T,onSetAlgoSpeed:v,onToggleSound:R})]})]})}function K({label:s,value:n,tone:d}){const r={indigo:"bg-indigo-500/10 text-indigo-200 ring-indigo-500/25",sky:"bg-sky-500/10 text-sky-200 ring-sky-500/25",emerald:"bg-emerald-500/10 text-emerald-200 ring-emerald-500/25",amber:"bg-amber-500/10 text-amber-200 ring-amber-500/25"};return e.jsxs("div",{className:`rounded-full px-3 py-1.5 text-[10px] ring-1 ${r[d]}`,children:[e.jsx("span",{className:"mr-1 uppercase tracking-wider opacity-60",children:s}),e.jsx("span",{className:"font-mono font-bold",children:n})]})}export{Mt as default}; diff --git a/docs/assets/EvolutionSimulatorPage-ClEOzQ75.js b/docs/assets/EvolutionSimulatorPage-ClEOzQ75.js new file mode 100644 index 0000000..95af5a4 --- /dev/null +++ b/docs/assets/EvolutionSimulatorPage-ClEOzQ75.js @@ -0,0 +1 @@ +import{j as e,r as i}from"./index-BfWfBQOp.js";import{g as de}from"./audioContext-NbgqvQGz.js";import{S as ue}from"./shuffle-Ri9xSsK2.js";import{P as B}from"./play-WRQgdyAG.js";import{P as xe}from"./pause-Bg-8t1oj.js";import{R as me}from"./rotate-ccw-EKzY5q_W.js";import{V as ge,a as he}from"./volume-x-ChIHiT28.js";function U(t,n,s,a){return t.length===0?"":t.length===1?`0,${s}`:t.map((r,l)=>{const o=l/(t.length-1)*n,c=s-Math.max(0,r)/Math.max(1,a)*s;return`${o},${c}`}).join(" ")}function pe({best:t,avg:n,targetLength:s}){const l=Math.max(s,...t,...n,1);return e.jsxs("div",{className:"rounded-2xl border border-slate-700/50 bg-slate-900/70 p-4 shadow-xl shadow-black/20 backdrop-blur-sm",children:[e.jsxs("div",{className:"mb-3",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-300",children:"Fitness Monitor"}),e.jsx("p",{className:"mt-0.5 text-[10px] text-slate-500",children:"Lab readout for best and average population health"})]}),e.jsx("div",{className:"w-full overflow-x-auto",children:e.jsxs("svg",{viewBox:"0 0 640 220",className:"w-full min-w-[560px] h-56 rounded-xl bg-slate-950/80 ring-1 ring-slate-700/50",children:[e.jsx("defs",{children:e.jsxs("linearGradient",{id:"fitnessGlow",x1:"0",x2:"1",y1:"0",y2:"0",children:[e.jsx("stop",{offset:"0%",stopColor:"rgb(244 63 94)"}),e.jsx("stop",{offset:"100%",stopColor:"rgb(52 211 153)"})]})}),e.jsx("line",{x1:"0",y1:220,x2:640,y2:220,stroke:"rgb(71 85 105 / 0.7)",strokeWidth:"1"}),e.jsx("line",{x1:"0",y1:"0",x2:"0",y2:220,stroke:"rgb(71 85 105 / 0.7)",strokeWidth:"1"}),s>0&&e.jsx("line",{x1:"0",y1:220-s/l*220,x2:640,y2:220-s/l*220,stroke:"rgb(74 222 128 / 0.35)",strokeDasharray:"4 4",strokeWidth:"1"}),e.jsx("polyline",{fill:"none",stroke:"url(#fitnessGlow)",strokeWidth:"3",points:U(t,640,220,l)}),e.jsx("polyline",{fill:"none",stroke:"rgb(56 189 248)",strokeWidth:"2",points:U(n,640,220,l)})]})}),e.jsxs("div",{className:"mt-2 flex items-center gap-4 text-[10px] text-slate-400",children:[e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx("span",{className:"h-2 w-2 rounded-full bg-rose-500"})," Best Fitness"]}),e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx("span",{className:"h-2 w-2 rounded-full bg-sky-400"})," Average Fitness"]})]})]})}function be({population:t,target:n}){return e.jsxs("div",{className:"rounded-2xl border border-slate-700/50 bg-slate-900/70 p-4 shadow-xl shadow-black/20 backdrop-blur-sm",children:[e.jsxs("div",{className:"mb-3 flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-300",children:"Candidate Profiles"}),e.jsx("p",{className:"mt-0.5 text-[10px] text-slate-500",children:"The strongest survivors in this generation"})]}),e.jsxs("span",{className:"rounded-full bg-emerald-500/10 px-2 py-0.5 text-[10px] font-semibold text-emerald-300 ring-1 ring-emerald-500/25",children:["Top ",t.length||0]})]}),e.jsx("div",{className:"space-y-1.5 max-h-72 overflow-auto pr-1",children:t.map((s,a)=>e.jsxs("div",{className:`rounded-xl px-3 py-2 ring-1 transition-all ${a===0?"bg-emerald-500/10 ring-emerald-500/30 shadow-lg shadow-emerald-950/20":"bg-slate-800/50 ring-slate-700/40"}`,children:[e.jsxs("div",{className:"flex items-center justify-between text-[10px] text-slate-500",children:[e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx("span",{className:`h-2 w-2 rounded-full ${a===0?"bg-emerald-400":"bg-slate-600"}`}),"Subject #",a+1]}),e.jsxs("span",{className:"font-mono",children:[s.fitness," / ",n.length]})]}),e.jsx("div",{className:"mt-1 font-mono text-xs text-slate-200 tracking-wide break-all",children:s.genes}),e.jsx("div",{className:"mt-2 h-1 overflow-hidden rounded-full bg-slate-950/70",children:e.jsx("div",{className:"h-full rounded-full bg-gradient-to-r from-emerald-400 to-cyan-300",style:{width:`${s.fitness/Math.max(1,n.length)*100}%`}})})]},`${s.genes}-${a}`))})]})}function fe({target:t,bestGenes:n}){return e.jsxs("div",{className:"rounded-2xl border border-slate-700/50 bg-slate-900/70 p-4 shadow-xl shadow-black/20 backdrop-blur-sm",children:[e.jsxs("div",{className:"mb-3",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-300",children:"DNA Match Board"}),e.jsx("p",{className:"mt-0.5 text-[10px] text-slate-500",children:"Green cells already match the target phrase"})]}),e.jsxs("div",{className:"space-y-3 font-mono text-sm",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[10px] text-slate-500 mb-1",children:"Target"}),e.jsx("div",{className:"rounded-xl bg-slate-950/70 ring-1 ring-slate-700/40 px-3 py-2 break-all tracking-wide text-slate-200",children:t||"(empty)"})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-[10px] text-slate-500 mb-1",children:"Best Individual"}),e.jsxs("div",{className:"rounded-xl bg-slate-950/70 ring-1 ring-slate-700/40 px-3 py-2 break-all tracking-wide",children:[(n||"").split("").map((s,a)=>{const r=t[a]===s;return e.jsx("span",{className:`mx-0.5 inline-flex min-w-5 justify-center rounded px-1 py-0.5 ${r?"bg-emerald-500/20 text-emerald-200 ring-1 ring-emerald-500/30":"bg-slate-800/60 text-slate-300 ring-1 ring-slate-700/40"}`,children:s},`${s}-${a}`)}),!n&&e.jsx("span",{className:"text-slate-500",children:"Start the simulator to see candidate DNA."})]})]})]})]})}const q=["#f8c9a5","#d99b6c","#8d5524","#f1b982","#c68642"],K=["#22c55e","#38bdf8","#a78bfa","#fb7185","#facc15","#2dd4bf"];function ve({population:t,target:n,generation:s,convergence:a,status:r}){const l=t.length>0?t.slice(0,12):Array.from({length:12},(c,d)=>({genes:"????",fitness:Math.max(0,12-d)})),o=Math.max(1,n.length);return e.jsxs("section",{className:"relative overflow-hidden rounded-2xl border border-emerald-700/30 bg-[radial-gradient(circle_at_top_left,rgba(16,185,129,0.18),transparent_34%),linear-gradient(135deg,rgba(15,23,42,0.96),rgba(6,78,59,0.42))] p-4 shadow-2xl shadow-black/30 md:p-5",children:[e.jsx("div",{className:"pointer-events-none absolute inset-x-0 bottom-0 h-28 bg-gradient-to-t from-emerald-950/50 to-transparent"}),e.jsxs("div",{className:"relative z-10 flex flex-col gap-3 md:flex-row md:items-start md:justify-between",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-base font-bold text-white md:text-lg",children:"Population Habitat"}),e.jsx("p",{className:"mt-1 text-xs leading-relaxed text-emerald-100/65",children:"Each person is a candidate solution. Brighter badges mean more matching genes survived selection."})]}),e.jsxs("div",{className:"grid grid-cols-3 gap-2 text-center",children:[e.jsx(_,{label:"Gen",value:s}),e.jsx(_,{label:"Fit",value:`${a.toFixed(0)}%`}),e.jsx(_,{label:"State",value:r})]})]}),e.jsxs("div",{className:"relative z-10 mt-5 rounded-2xl border border-emerald-950/50 bg-emerald-950/25 p-4 shadow-inner",children:[e.jsx("div",{className:"absolute inset-x-6 bottom-3 h-10 rounded-[50%] bg-black/20 blur-xl"}),e.jsx("div",{className:"relative grid grid-cols-3 gap-x-3 gap-y-5 sm:grid-cols-4 lg:grid-cols-6",children:l.map((c,d)=>{const p=c.fitness/o,m=d===0&&t.length>0;return e.jsx(je,{rank:d+1,genes:c.genes,fitnessRatio:p,isElite:m,skin:q[d%q.length],shirt:K[d%K.length]},`${c.genes}-${d}`)})})]})]})}function je({rank:t,genes:n,fitnessRatio:s,isElite:a,skin:r,shirt:l}){const o=Math.max(0,Math.min(1,s)),c=a?"shadow-[0_0_26px_rgba(52,211,153,0.45)]":"",d=.4+o*.6;return e.jsxs("div",{className:`group relative flex flex-col items-center rounded-2xl border px-2 py-3 transition-all hover:-translate-y-1 ${a?"border-emerald-300/50 bg-emerald-400/10":"border-emerald-900/30 bg-slate-950/25"} ${c}`,children:[e.jsxs("div",{className:"absolute right-1.5 top-1.5 rounded-full bg-slate-950/70 px-1.5 py-0.5 text-[9px] font-bold text-slate-400 ring-1 ring-slate-700/50",children:["#",t]}),e.jsxs("div",{className:"relative mt-2",children:[e.jsxs("div",{className:"h-9 w-9 rounded-full border border-black/15 shadow-inner",style:{backgroundColor:r,opacity:d},children:[e.jsxs("div",{className:"mx-auto mt-3 flex w-4 justify-between",children:[e.jsx("span",{className:"h-1 w-1 rounded-full bg-slate-950/70"}),e.jsx("span",{className:"h-1 w-1 rounded-full bg-slate-950/70"})]}),e.jsx("div",{className:"mx-auto mt-1 h-1 w-3 rounded-full bg-slate-950/40"})]}),e.jsx("div",{className:"mx-auto -mt-1 h-10 w-12 rounded-t-2xl rounded-b-lg border border-black/15 shadow-lg",style:{backgroundColor:l,opacity:d}})]}),e.jsx("div",{className:"mt-2 h-1.5 w-full overflow-hidden rounded-full bg-slate-950/70",children:e.jsx("div",{className:"h-full rounded-full bg-gradient-to-r from-emerald-400 to-cyan-300 transition-all",style:{width:`${o*100}%`}})}),e.jsx("div",{className:"mt-1 max-w-full truncate font-mono text-[9px] text-emerald-100/70",children:n||"waiting"})]})}function _({label:t,value:n}){return e.jsxs("div",{className:"rounded-xl bg-slate-950/45 px-3 py-2 ring-1 ring-emerald-500/20",children:[e.jsx("div",{className:"text-[9px] uppercase tracking-wider text-emerald-100/45",children:t}),e.jsx("div",{className:"mt-0.5 text-xs font-bold capitalize text-emerald-100",children:n})]})}const J="ABCDEFGHIJKLMNOPQRSTUVWXYZ .,!?-",$={target:"HELLO WORLD",populationSize:300,mutationRate:.03,crossoverRate:.75,maxGenerations:500,selectionStrategy:"roulette"},X=["HELLO WORLD","GENETIC ALGORITHM","EVOLUTION IN ACTION","SURVIVAL OF THE FITTEST","OPTIMIZE THE GENES"];function Q(t){let n=t>>>0;const s=()=>(n=1664525*n+1013904223>>>0,n/4294967296);return{next:s,int:(r,l)=>l<=r?r:Math.floor(s()*(l-r+1))+r}}function Ne(t,n,s){let a="";for(let r=0;r({...s,fitness:we(s.genes,n)}))}function ee(t){return t.length===0?0:t.reduce((s,a)=>s+a.fitness,0)/t.length}function Se(t,n){const s=t.reduce((l,o)=>l+o.fitness,0);if(s<=0)return t[n.int(0,t.length-1)];const a=n.next()*s;let r=0;for(let l=0;l=a)return t[l];return t[t.length-1]}function ke(t,n,s){let a=t[s.int(0,t.length-1)];const r=Math.max(1,n);for(let l=1;la.fitness&&(a=o)}return a}function Y(t,n,s,a){return n==="tournament"?ke(t,s,a):Se(t,a)}function Ce(t,n,s,a){const r=t.genes.length;if(r<=1||a.next()>s)return t.genes;const l=a.int(1,r-1);return t.genes.slice(0,l)+n.genes.slice(l)}function Te(t,n,s,a){if(t.length===0)return t;let r="";for(let l=0;ls.fitness-n.fitness)}function te(t,n,s,a){return n===0?"Target is empty. Enter a target to evolve.":t>=n?`Solution found in ${s} generations`:s>=a?"Max generations reached without full match":"Evolving..."}function Re(t,n){const s=t.target.length,a=Q(n),r=ye(t.populationSize,s,t.allowedChars,a),l=V(D(r,t.target)),o=l[0]??{genes:"",fitness:0},c=ee(l),d=s===0||o.fitness>=s;return{generation:0,population:l,bestIndividual:W(o),averageFitness:c,bestFitnessHistory:[o.fitness],averageFitnessHistory:[c],rngSeed:n,done:d,message:te(o.fitness,s,0,t.maxGenerations)}}function Me(t,n){if(n.done)return n;const s=t.target.length,a=Q(n.rngSeed+n.generation+1),r=V(D(n.population,t.target)),l=r[0]?W(r[0]):{genes:"",fitness:0},o=[l];for(;o.length=s||d>=t.maxGenerations;return{generation:d,population:c,bestIndividual:W(p),averageFitness:m,bestFitnessHistory:[...n.bestFitnessHistory,p.fitness],averageFitnessHistory:[...n.averageFitnessHistory,m],rngSeed:n.rngSeed,done:x,message:te(p.fitness,s,d,t.maxGenerations)}}const H=[220,261.63,293.66,329.63,392,440,523.25,659.25,783.99];function Ee(){const t=i.useRef(!0),n=i.useCallback(()=>de(),[]),s=i.useCallback(c=>{t.current=c},[]),a=i.useCallback((c,d,p,m=.05)=>{if(!t.current)return;const x=n();if(!x)return;const h=x.createOscillator(),v=x.createGain();h.type=d,h.frequency.setValueAtTime(c,x.currentTime),v.gain.setValueAtTime(m,x.currentTime),v.gain.exponentialRampToValueAtTime(.001,x.currentTime+p),h.connect(v),v.connect(x.destination),h.start(x.currentTime),h.stop(x.currentTime+p)},[n]),r=i.useCallback((c,d)=>{const p=d>0?c/d:0,m=Math.max(0,Math.min(H.length-1,Math.floor(p*(H.length-1))));a(H[m],"sine",.06,.03)},[a]),l=i.useCallback(()=>{a(523.25,"triangle",.08,.05)},[a]),o=i.useCallback(()=>{if(!t.current)return;const c=n();c&&[523.25,659.25,783.99].forEach((d,p)=>{const m=c.createOscillator(),x=c.createGain(),h=c.currentTime+p*.1;m.type="sine",m.frequency.setValueAtTime(d,h),x.gain.setValueAtTime(.06,h),x.gain.exponentialRampToValueAtTime(.001,h+.16),m.connect(x),x.connect(c.destination),m.start(h),m.stop(h+.16)})},[n]);return{setEnabled:s,playGenerationTick:r,playImprove:l,playComplete:o}}function Z(t){const n=t.toUpperCase();let s="";for(let a=0;a{n(g),g==="guided"&&(a("HELLO WORLD"),l(300),c(3),p(75),x(500),v("roulette"),M(35))},[]);i.useEffect(()=>{O(S)},[S,O]);const C=i.useCallback(()=>{k.current&&(clearTimeout(k.current),k.current=null)},[]),z=i.useCallback(()=>({target:Z(s),populationSize:Math.max(1,r),mutationRate:Math.min(1,Math.max(0,o/100)),crossoverRate:Math.min(1,Math.max(0,d/100)),maxGenerations:Math.max(1,m),selectionStrategy:h,tournamentSize:5,allowedChars:J}),[s,r,o,d,m,h]),u=i.useCallback(()=>{N(g=>{if(!g||!E.current)return g;const T=Me(E.current,g),R=E.current.target.length;return G(T.bestIndividual.fitness,R),T.bestIndividual.fitness>F.current&&P(),F.current=T.bestIndividual.fitness,T.done&&(f(),y("finished")),T})},[G,P,f]);i.useEffect(()=>{if(j!=="running"){C();return}const g=()=>{u(),k.current=setTimeout(g,w)};return k.current=setTimeout(g,w),C},[j,w,u,C]);const se=i.useCallback(()=>{const g=z();E.current=g;const R=Re(g,1337);F.current=R.bestIndividual.fitness,N(R),R.bestIndividual.fitness>0&&G(R.bestIndividual.fitness,g.target.length),y(R.done?"finished":"running")},[z,G]),ne=i.useCallback(()=>{j==="running"&&y("paused")},[j]),ae=i.useCallback(()=>{j==="paused"&&y("running")},[j]),re=i.useCallback(()=>{C(),N(null),y("idle"),F.current=0},[C]),le=i.useCallback(g=>{A(g)},[]),ie=i.useCallback(()=>{const g=Math.floor(Math.random()*X.length);a(X[g])},[]),oe=i.useMemo(()=>b?.population?b.population.slice(0,10):[],[b]),ce=i.useMemo(()=>{const g=Math.max(1,Z(s).length);return(b?.bestIndividual.fitness??0)/g*100},[b,s]);return{mode:t,setMode:L,target:s,setTarget:a,populationSize:r,setPopulationSize:l,mutationRatePercent:o,setMutationRatePercent:c,crossoverRatePercent:d,setCrossoverRatePercent:p,maxGenerations:m,setMaxGenerations:x,selectionStrategy:h,setSelectionStrategy:v,speedMs:w,setSpeedMs:M,soundEnabled:S,toggleSound:le,state:b,status:j,topIndividuals:oe,convergence:ce,start:se,pause:ne,resume:ae,reset:re,randomTarget:ie}}const Ge=[{label:"Slow",value:120},{label:"Med",value:35},{label:"Fast",value:8}];function He(){const{mode:t,setMode:n,target:s,setTarget:a,populationSize:r,setPopulationSize:l,mutationRatePercent:o,setMutationRatePercent:c,crossoverRatePercent:d,setCrossoverRatePercent:p,maxGenerations:m,setMaxGenerations:x,selectionStrategy:h,setSelectionStrategy:v,speedMs:w,setSpeedMs:M,soundEnabled:S,toggleSound:A,state:b,status:N,topIndividuals:j,convergence:y,start:k,pause:E,resume:F,reset:O,randomTarget:G}=Fe(),P=N==="running",f=t==="guided",L=b?.bestIndividual,C=b?.averageFitness??0,z=Pe({status:N,generation:b?.generation??0,bestFitness:L?.fitness??0,targetLength:s.length,convergence:y});return e.jsx("div",{className:"flex-1 overflow-y-auto bg-[radial-gradient(circle_at_top,rgba(16,185,129,0.12),transparent_34%),linear-gradient(180deg,rgba(15,23,42,0),rgba(6,78,59,0.16))] p-4 md:p-6",children:e.jsxs("div",{className:"mx-auto max-w-6xl space-y-4",children:[e.jsxs("section",{className:"relative overflow-hidden rounded-2xl border border-emerald-700/30 bg-[radial-gradient(circle_at_top_left,rgba(34,197,94,0.18),transparent_34%),linear-gradient(135deg,rgba(15,23,42,0.96),rgba(6,78,59,0.36))] p-4 shadow-2xl shadow-black/30 backdrop-blur-sm md:p-5",children:[e.jsx("div",{className:"pointer-events-none absolute right-6 top-4 text-7xl opacity-10",children:"🧬"}),e.jsx("h2",{className:"text-lg md:text-xl font-bold text-white",children:"Evolution Lab — Genetic Algorithm"}),e.jsx("p",{className:"text-xs text-emerald-100/65 mt-1",children:"Evolve a population of digital people toward a target phrase using selection, crossover, and mutation."}),e.jsx("div",{className:"mt-3 rounded-xl bg-emerald-500/10 ring-1 ring-emerald-500/20 px-3 py-2",children:e.jsx("p",{className:"text-[11px] text-emerald-50/80 leading-relaxed",children:"Each generation is a lab cycle: evaluate every person → select stronger parents → combine DNA → mutate a few genes → keep the elite survivor."})}),e.jsxs("div",{className:"mt-3 grid grid-cols-2 gap-2 md:max-w-sm",children:[e.jsx("button",{onClick:()=>n("guided"),className:`rounded-lg px-3 py-2 text-xs font-semibold ring-1 transition-all ${f?"bg-amber-500/20 text-amber-300 ring-amber-500/40":"bg-slate-800/60 text-slate-400 ring-slate-700/40 hover:bg-slate-700/60"}`,children:"Guided Mode"}),e.jsx("button",{onClick:()=>n("free-play"),className:`rounded-lg px-3 py-2 text-xs font-semibold ring-1 transition-all ${f?"bg-slate-800/60 text-slate-400 ring-slate-700/40 hover:bg-slate-700/60":"bg-cyan-500/20 text-cyan-300 ring-cyan-500/40"}`,children:"Free-play Mode"})]}),f&&e.jsx("p",{className:"mt-2 text-[10px] text-amber-300/80",children:"Guided mode uses recommended settings (HELLO WORLD, pop 300, mutation 3%, crossover 75%) for stable learning."}),f&&e.jsxs("div",{className:"mt-3 rounded-xl border border-amber-500/20 bg-amber-500/5 p-3",children:[e.jsx("h4",{className:"text-[10px] font-semibold uppercase tracking-wider text-amber-300",children:"Guided Walkthrough"}),e.jsx("p",{className:"mt-1 text-xs text-slate-300 leading-relaxed",children:z.main}),e.jsx("ul",{className:"mt-2 space-y-1 text-[11px] text-slate-400 list-disc pl-4",children:z.points.map(u=>e.jsx("li",{children:u},u))})]}),e.jsxs("div",{className:"mt-4 grid grid-cols-1 md:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-[11px] text-slate-400",children:"Target String"}),e.jsxs("div",{className:"mt-1 flex gap-2",children:[e.jsx("input",{value:s,onChange:u=>a(u.target.value),placeholder:"HELLO WORLD",disabled:f,className:"flex-1 rounded-lg bg-slate-950/70 px-3 py-2 text-sm text-slate-200 ring-1 ring-slate-700/50 outline-none focus:ring-cyan-500/50"}),e.jsx("button",{onClick:G,disabled:f,className:"rounded-lg bg-slate-800/70 px-3 py-2 text-xs text-slate-300 ring-1 ring-slate-700/50 hover:bg-slate-700/70",children:e.jsx(ue,{size:14})})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-[11px] text-slate-400",children:"Population Size"}),e.jsx("input",{type:"number",min:1,max:2e3,value:r,disabled:f,onChange:u=>l(Number(u.target.value)||1),className:"mt-1 w-full rounded-lg bg-slate-950/70 px-3 py-2 text-sm text-slate-200 ring-1 ring-slate-700/50"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-[11px] text-slate-400",children:"Max Generations"}),e.jsx("input",{type:"number",min:1,max:2e4,value:m,disabled:f,onChange:u=>x(Number(u.target.value)||1),className:"mt-1 w-full rounded-lg bg-slate-950/70 px-3 py-2 text-sm text-slate-200 ring-1 ring-slate-700/50"})]})]})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between text-[11px] text-slate-400 mb-1",children:[e.jsx("span",{children:"Mutation Rate"}),e.jsxs("span",{children:[o,"%"]})]}),e.jsx("input",{type:"range",min:0,max:100,value:o,disabled:f,onChange:u=>c(Number(u.target.value)),className:"w-full accent-rose-500"})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between text-[11px] text-slate-400 mb-1",children:[e.jsx("span",{children:"Crossover Rate"}),e.jsxs("span",{children:[d,"%"]})]}),e.jsx("input",{type:"range",min:0,max:100,value:d,disabled:f,onChange:u=>p(Number(u.target.value)),className:"w-full accent-sky-500"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-[11px] text-slate-400",children:"Selection Strategy"}),e.jsx("div",{className:"mt-1 grid grid-cols-2 gap-2",children:["roulette","tournament"].map(u=>e.jsx("button",{disabled:f,onClick:()=>v(u),className:`rounded-lg px-3 py-2 text-xs font-medium ring-1 transition-all ${h===u?"bg-emerald-500/20 text-emerald-300 ring-emerald-500/40":"bg-slate-800/60 text-slate-400 ring-slate-700/40 hover:bg-slate-700/60"}`,children:u==="roulette"?"Roulette Wheel":"Tournament"},u))})]})]})]}),e.jsxs("div",{className:"mt-4 flex flex-wrap items-center gap-2",children:[e.jsxs("button",{onClick:k,className:"inline-flex items-center gap-1.5 rounded-lg bg-cyan-500/20 px-3 py-2 text-xs font-semibold text-cyan-300 ring-1 ring-cyan-500/40 hover:bg-cyan-500/30",children:[e.jsx(B,{size:14})," Start"]}),e.jsxs("button",{onClick:P?E:F,disabled:N==="idle"||N==="finished",className:"inline-flex items-center gap-1.5 rounded-lg bg-slate-800/70 px-3 py-2 text-xs font-semibold text-slate-300 ring-1 ring-slate-700/50 hover:bg-slate-700/70 disabled:opacity-40",children:[P?e.jsx(xe,{size:14}):e.jsx(B,{size:14}),P?"Pause":"Resume"]}),e.jsxs("button",{onClick:O,className:"inline-flex items-center gap-1.5 rounded-lg bg-slate-800/70 px-3 py-2 text-xs font-semibold text-slate-300 ring-1 ring-slate-700/50 hover:bg-slate-700/70",children:[e.jsx(me,{size:14})," Reset"]}),e.jsxs("button",{onClick:()=>A(!S),className:`inline-flex items-center gap-1.5 rounded-lg px-3 py-2 text-xs font-semibold ring-1 ${S?"bg-indigo-500/15 text-indigo-300 ring-indigo-500/30":"bg-slate-800/70 text-slate-400 ring-slate-700/40"}`,children:[S?e.jsx(ge,{size:14}):e.jsx(he,{size:14}),S?"Sound On":"Sound Off"]}),e.jsxs("div",{className:"ml-auto inline-flex items-center gap-2",children:[e.jsx("span",{className:"text-[11px] text-slate-500",children:"Speed"}),Ge.map(u=>e.jsx("button",{onClick:()=>M(u.value),className:`rounded px-2 py-1 text-[10px] font-medium ${w===u.value?"bg-emerald-500/20 text-emerald-300 ring-1 ring-emerald-500/40":"bg-slate-800/60 text-slate-400 ring-1 ring-slate-700/40"}`,children:u.label},u.value))]})]})]}),e.jsx(ve,{population:j,target:s.toUpperCase(),generation:b?.generation??0,convergence:y,status:N}),e.jsxs("section",{className:"grid grid-cols-1 lg:grid-cols-3 gap-4",children:[e.jsxs("div",{className:"rounded-2xl border border-slate-700/50 bg-slate-900/70 p-4 shadow-xl shadow-black/20 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Statistics"}),e.jsxs("div",{className:"grid grid-cols-2 gap-2 text-xs",children:[e.jsx(I,{label:"Generation",value:b?.generation??0}),e.jsx(I,{label:"Best Fitness",value:`${L?.fitness??0} / ${s.length}`}),e.jsx(I,{label:"Avg Fitness",value:C.toFixed(2)}),e.jsx(I,{label:"Convergence",value:`${y.toFixed(1)}%`}),e.jsx(I,{label:"Mutation",value:`${o}%`}),e.jsx(I,{label:"Population",value:r})]}),e.jsx("p",{className:"mt-3 text-[11px] text-slate-400",children:b?.message??"Ready to evolve."})]}),e.jsx("div",{className:"lg:col-span-2",children:e.jsx(fe,{target:s.toUpperCase(),bestGenes:L?.genes??""})})]}),e.jsxs("section",{className:"grid grid-cols-1 lg:grid-cols-3 gap-4",children:[e.jsx("div",{className:"lg:col-span-2",children:e.jsx(pe,{best:b?.bestFitnessHistory??[],avg:b?.averageFitnessHistory??[],targetLength:s.length})}),e.jsx(be,{population:j,target:s.toUpperCase()})]})]})})}function I({label:t,value:n}){return e.jsxs("div",{className:"rounded-lg bg-slate-800/50 px-2.5 py-2 ring-1 ring-slate-700/40",children:[e.jsx("div",{className:"text-[10px] text-slate-500",children:t}),e.jsx("div",{className:"text-sm font-mono text-slate-100",children:n})]})}function Pe({status:t,generation:n,bestFitness:s,targetLength:a,convergence:r}){if(t==="idle")return{main:"Start the simulator to create the initial random population. Every individual has the same length as the target string.",points:["Fitness = number of correct characters in correct positions.","Roulette selection gives fitter strings higher chance to reproduce.","Elitism keeps the best individual every generation."]};if(t==="paused")return{main:"Simulation is paused. Compare the best and average fitness lines before continuing.",points:[`Current convergence is ${r.toFixed(1)}%.`,"If average fitness is catching best fitness, population is stabilizing.","Resume to observe further crossover + mutation effects."]};if(t==="finished"){const l=a>0&&s>=a;return{main:l?`Solved in ${n} generations. The best individual now exactly matches the target.`:`Reached max generations at ${r.toFixed(1)}% convergence without full match.`,points:l?["Notice how best fitness rose in steps when useful mutations appeared.","Average fitness should trend upward as good genes spread.","Try Free-play to test lower mutation or alternate selection strategy."]:["Try increasing max generations or population size.","Slightly higher mutation can help escape local plateaus.","Free-play mode lets you experiment with these trade-offs."]}}return n<10?{main:"Early phase: selection pressure is starting to amplify better character matches.",points:["Watch the best-fitness line jump when a useful mutation appears.","Average fitness may rise slowly at first—this is normal.","Crossover recombines partial matches from different parents."]}:r<60?{main:"Middle phase: the population is accumulating correct characters in more positions.",points:["Best fitness reflects the strongest candidate so far.","Average fitness indicates overall population quality.","Gap between best and average shows remaining diversity."]}:{main:"Late phase: convergence is high; progress often comes from rare beneficial mutations.",points:["Near the end, single-character improvements become more important.","If progress stalls, Free-play can help you tune mutation and generation budget.","Use Gene Comparison to see exactly which positions remain incorrect."]}}export{He as default}; diff --git a/docs/assets/FibonacciGamePage-yra_MIZ2.js b/docs/assets/FibonacciGamePage-yra_MIZ2.js new file mode 100644 index 0000000..c24ae88 --- /dev/null +++ b/docs/assets/FibonacciGamePage-yra_MIZ2.js @@ -0,0 +1,19 @@ +import{c as re,r as x,j as e}from"./index-BfWfBQOp.js";import{T as le}from"./trophy-CUioHXrM.js";import{F as oe,L as ce}from"./lightbulb-D7RWgS3V.js";import{T as de}from"./timer-t0ca9c1j.js";import{R as xe}from"./rotate-ccw-EKzY5q_W.js";import{V as me,a as ue}from"./volume-x-ChIHiT28.js";import{g as fe}from"./audioContext-NbgqvQGz.js";const he=[["path",{d:"M16.8 11.2c.8-.9 1.2-2 1.2-3.2a6 6 0 0 0-9.3-5",key:"1fkcox"}],["path",{d:"m2 2 20 20",key:"1ooewy"}],["path",{d:"M6.3 6.3a4.67 4.67 0 0 0 1.2 5.2c.7.7 1.3 1.5 1.5 2.5",key:"10m8kw"}],["path",{d:"M9 18h6",key:"x1upvd"}],["path",{d:"M10 22h4",key:"ceow96"}]],ge=re("lightbulb-off",he),pe=["right","up","left","down"],D={guided:{name:"Guided",description:"Learn step-by-step with hints and formula guidance."},challenge:{name:"Challenge",description:"Race against time! Pick the right block from multiple choices."},sandbox:{name:"Sandbox",description:"Explore freely with no scoring or time pressure."}},C={title:"Fibonacci Spiral Builder",subtitle:"Inspired by Leonardo Fibonacci",what:"Build a golden spiral by placing squares in the Fibonacci sequence. Each square's side length equals the sum of the two before it (1, 1, 2, 3, 5, 8, 13...). As you place them, a beautiful spiral emerges — the same pattern found in sunflowers, seashells, and galaxies.",skills:["Pattern Recognition","Mathematical Sequences","Spatial Reasoning","Golden Ratio Intuition"]};function W(t){if(t.length===0)return{minX:0,minY:0,maxX:0,maxY:0};let s=1/0,a=1/0,o=-1/0,n=-1/0;for(const l of t)s=Math.min(s,l.x),a=Math.min(a,l.y),o=Math.max(o,l.x+l.size),n=Math.max(n,l.y+l.size);return{minX:s,minY:a,maxX:o,maxY:n}}function be(t,s,a){if(t.length===0)return{x:0,y:0,direction:"right"};if(t.length===1){const i=t[0];return{x:i.x+i.size,y:i.y,direction:"right"}}const o=W(t),n=pe[a%4];let l=0,d=0;switch(n){case"right":l=o.maxX,d=o.maxY-s;break;case"up":l=o.maxX-s,d=o.minY-s;break;case"left":l=o.minX-s,d=o.minY;break;case"down":l=o.minX,d=o.maxY;break}return{x:l,y:d,direction:n}}function je(t){const{x:s,y:a,size:o,direction:n}=t,l=o;switch(n){case"right":return`M ${s} ${a+o} A ${l} ${l} 0 0 1 ${s+o} ${a}`;case"up":return`M ${s+o} ${a+o} A ${l} ${l} 0 0 1 ${s} ${a}`;case"left":return`M ${s+o} ${a} A ${l} ${l} 0 0 1 ${s} ${a+o}`;case"down":return`M ${s} ${a} A ${l} ${l} 0 0 1 ${s+o} ${a+o}`;default:return""}}function B(){return[{id:0,size:1,x:0,y:0,direction:"right",fibIndex:0},{id:1,size:1,x:1,y:0,direction:"right",fibIndex:1}]}const I=["#818cf8","#a78bfa","#c084fc","#e879f9","#f472b6","#fb7185","#f97316","#facc15","#4ade80","#34d399","#2dd4bf","#22d3ee","#38bdf8","#60a5fa","#818cf8","#a78bfa"];function Ne({placedSquares:t,lastPlacedId:s}){const{viewBox:a,squares:o}=x.useMemo(()=>{if(t.length===0)return{viewBox:"-5 -5 10 10",squares:[]};const n=W(t),l=Math.max((n.maxX-n.minX)*.15,2);return{viewBox:`${n.minX-l} ${n.minY-l} ${n.maxX-n.minX+l*2} ${n.maxY-n.minY+l*2}`,squares:t}},[t]);return t.length===0?e.jsx("div",{className:"flex flex-1 w-full min-h-[200px] h-full items-center justify-center rounded-xl border border-slate-700/50 bg-slate-950/80 text-slate-500",children:"Place the first block to begin"}):e.jsx("div",{className:"flex-1 w-full min-h-[200px] rounded-xl border border-slate-700/50 bg-slate-950/80 p-2 shadow-2xl backdrop-blur-sm overflow-hidden",children:e.jsxs("svg",{viewBox:a,className:"w-full h-full",preserveAspectRatio:"xMidYMid meet",children:[e.jsx("defs",{children:e.jsxs("filter",{id:"glow",children:[e.jsx("feGaussianBlur",{stdDeviation:"0.5",result:"coloredBlur"}),e.jsxs("feMerge",{children:[e.jsx("feMergeNode",{in:"coloredBlur"}),e.jsx("feMergeNode",{in:"SourceGraphic"})]})]})}),o.map((n,l)=>{const d=I[l%I.length],i=n.id===s;return e.jsxs("g",{children:[e.jsx("rect",{x:n.x,y:n.y,width:n.size,height:n.size,fill:d,fillOpacity:.12,stroke:d,strokeWidth:Math.max(n.size*.02,.15),strokeOpacity:.6,rx:n.size*.02,className:i?"animate-pulse":"",filter:i?"url(#glow)":void 0}),e.jsx("text",{x:n.x+n.size/2,y:n.y+n.size/2,textAnchor:"middle",dominantBaseline:"central",fill:d,fillOpacity:.7,fontSize:Math.max(n.size*.35,.6),fontWeight:700,fontFamily:"ui-monospace, monospace",children:n.size})]},n.id)}),o.map((n,l)=>{const d=I[l%I.length],i=je(n);return e.jsx("path",{d:i,fill:"none",stroke:d,strokeWidth:Math.max(n.size*.03,.15),strokeOpacity:.8,strokeLinecap:"round"},`arc-${n.id}`)})]})})}function ye({blocks:t,mode:s,lastError:a,shakeBlockId:o,isComplete:n,onPlaceBlock:l}){const[d,i]=x.useState("");if(n)return e.jsxs("div",{className:"rounded-xl border border-emerald-500/30 bg-emerald-500/5 p-6 text-center",children:[e.jsx("div",{className:"text-3xl mb-2",children:"🎉"}),e.jsx("p",{className:"text-emerald-300 font-semibold text-sm",children:"Spiral Complete!"}),e.jsx("p",{className:"text-emerald-400/60 text-xs mt-1",children:"Beautiful golden spiral achieved"})]});const r=()=>{const c=parseInt(d,10);isNaN(c)||c<=0||(l(c),i(""))},u=s==="sandbox";return e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Place Next Block"}),u?e.jsxs("div",{className:"flex gap-2",children:[e.jsx("input",{type:"number",inputMode:"numeric",value:d,onChange:c=>i(c.target.value),onKeyDown:c=>c.key==="Enter"&&r(),placeholder:"Enter next number...",className:"flex-1 rounded-lg bg-slate-800/60 px-3 py-3 text-center text-lg font-mono font-bold text-white placeholder-slate-500 outline-none ring-1 ring-slate-700/50 focus:ring-indigo-500/50"}),e.jsx("button",{onClick:r,disabled:!d.trim(),className:"rounded-lg bg-gradient-to-br from-indigo-500/20 to-violet-500/20 px-5 py-3 text-sm font-semibold text-indigo-200 ring-1 ring-indigo-500/30 transition-all hover:from-indigo-500/30 hover:to-violet-500/30 active:scale-95 disabled:opacity-40 disabled:cursor-not-allowed",children:"Place"})]}):e.jsx("div",{className:"flex flex-wrap gap-2 justify-center",children:t.map(c=>{const m=o===c.size;return e.jsx("button",{onClick:()=>l(c.size),className:` + relative flex items-center justify-center rounded-lg font-mono font-bold + transition-all duration-200 active:scale-95 + min-w-[56px] min-h-[56px] px-4 py-3 text-lg + bg-gradient-to-br from-indigo-500/20 to-violet-500/20 + text-indigo-200 ring-1 ring-indigo-500/30 + hover:from-indigo-500/30 hover:to-violet-500/30 hover:ring-indigo-400/50 + hover:shadow-lg hover:shadow-indigo-500/10 + ${m?"animate-[shake_0.3s_ease-in-out_2] ring-red-500/60 from-red-500/20 to-rose-500/20 text-red-300":""} + `,children:c.size},`${c.id}-${c.size}`)})}),a&&e.jsx("p",{className:"mt-3 text-center text-xs font-medium text-red-400 animate-pulse",children:a})]})}const ve=["guided","challenge","sandbox"];function ke(t){const s=Math.floor(t/60),a=t%60;return`${s}:${a.toString().padStart(2,"0")}`}function we({mode:t,score:s,streak:a,timer:o,isComplete:n,showHint:l,sequence:d,expectedNext:i,soundEnabled:r,onChangeMode:u,onReset:c,onToggleHint:m,onToggleSound:h}){return e.jsxs("div",{className:"flex flex-col gap-4 w-full md:w-72 md:shrink-0 md:overflow-y-auto md:max-h-full pr-1",children:[e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-sm font-bold text-indigo-300 mb-1",children:C.title}),e.jsx("p",{className:"text-[10px] text-slate-500 italic mb-2",children:C.subtitle}),e.jsx("p",{className:"text-xs text-slate-400 leading-relaxed",children:C.what}),e.jsx("div",{className:"mt-2 flex flex-wrap gap-1.5",children:C.skills.map(f=>e.jsx("span",{className:"inline-flex items-center rounded-full bg-violet-500/10 px-2 py-0.5 text-[10px] font-medium text-violet-400 ring-1 ring-violet-500/20",children:f},f))})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Game Mode"}),e.jsx("div",{className:"flex gap-1",children:ve.map(f=>e.jsx("button",{onClick:()=>u(f),className:` + flex-1 rounded-lg px-2 py-2 text-xs font-medium transition-all duration-200 + ${t===f?"bg-indigo-500/20 text-indigo-300 ring-1 ring-indigo-500/40 shadow-lg shadow-indigo-500/10":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50 hover:text-slate-300"} + `,children:D[f].name},f))}),e.jsx("p",{className:"mt-2 text-[10px] text-slate-500 leading-relaxed",children:D[t].description})]}),t==="challenge"&&e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Stats"}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"flex items-center gap-1.5 text-xs text-slate-500",children:[e.jsx(le,{size:12})," Score"]}),e.jsx("span",{className:"text-sm font-mono font-bold text-amber-300",children:s})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"flex items-center gap-1.5 text-xs text-slate-500",children:[e.jsx(oe,{size:12})," Streak"]}),e.jsx("span",{className:"text-sm font-mono font-bold text-orange-400",children:a})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"flex items-center gap-1.5 text-xs text-slate-500",children:[e.jsx(de,{size:12})," Time"]}),e.jsx("span",{className:"text-sm font-mono font-bold text-sky-300",children:ke(o)})]})]})]}),(t==="guided"||l)&&!n&&e.jsxs("div",{className:"rounded-xl border border-amber-500/20 bg-amber-500/5 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-amber-400/80 mb-2",children:"Hint"}),e.jsxs("p",{className:"text-xs text-amber-300/70 font-mono leading-relaxed",children:["F(",d.length,") = F(",d.length-1,") + F(",d.length-2,")"]}),e.jsxs("p",{className:"text-xs text-amber-300/70 font-mono",children:["= ",d[d.length-1]," + ",d[d.length-2]," = ",e.jsx("span",{className:"font-bold text-amber-200",children:i})]})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Sequence"}),e.jsxs("div",{className:"flex flex-wrap gap-1.5",children:[d.map((f,p)=>e.jsx("span",{className:"inline-flex items-center justify-center rounded-md bg-indigo-500/15 px-2 py-1 text-xs font-mono font-semibold text-indigo-300 ring-1 ring-indigo-500/20",children:f},p)),!n&&e.jsx("span",{className:"inline-flex items-center justify-center rounded-md bg-slate-800/50 px-2 py-1 text-xs font-mono text-slate-600 ring-1 ring-slate-700/30",children:"?"})]})]}),e.jsxs("div",{className:"grid grid-cols-3 gap-2",children:[e.jsxs("button",{onClick:c,className:"flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300",children:[e.jsx(xe,{size:12}),"Reset"]}),e.jsxs("button",{onClick:m,className:` + flex items-center justify-center gap-1.5 rounded-lg px-3 py-2 text-xs font-medium transition-all + ${l?"bg-amber-500/15 text-amber-300 ring-1 ring-amber-500/30":"bg-slate-800/60 text-slate-400 hover:bg-slate-700/60 hover:text-slate-300"} + `,children:[l?e.jsx(ce,{size:12}):e.jsx(ge,{size:12}),"Hints"]}),e.jsxs("button",{onClick:()=>h(!r),className:` + flex items-center justify-center gap-1.5 rounded-lg px-3 py-2 text-xs font-medium transition-all + ${r?"bg-indigo-500/15 text-indigo-300 ring-1 ring-indigo-500/30":"bg-slate-800/60 text-slate-400 hover:bg-slate-700/60 hover:text-slate-300"} + `,children:[r?e.jsx(me,{size:12}):e.jsx(ue,{size:12}),"Sound"]})]})]})}function V(t){return t.length<2?1:t[t.length-1]+t[t.length-2]}function Te(t,s){const a=V(t);return s===a}function Se(t,s){return s===0?0:t/s}function Me(t){const s=[];for(let a=2;an>0&&n!==t);for(const n of o){if(a.size>=s+1)break;a.add(n)}for(;a.sizeMath.random()-.5)}const E=1.6180339887;function Ce({sequence:t}){const s=x.useMemo(()=>Me(t),[t]),a=s.length>0?s[s.length-1].ratio:0,o=60;return e.jsxs("div",{className:"flex gap-4 w-full",children:[e.jsxs("div",{className:"flex-1 rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-2",children:"Golden Ratio Convergence"}),e.jsxs("div",{className:"flex items-end gap-1.5 h-16 mb-2",children:[s.map((n,l)=>{const d=Math.abs(n.ratio-E),i=Math.max(0,1-d*4),r=Math.max(4,i*o),u=l===s.length-1;return e.jsx("div",{className:"flex-1 rounded-t-sm transition-all duration-300",style:{height:`${r}px`,backgroundColor:u?"#818cf8":`rgba(129, 140, 248, ${.3+i*.5})`},title:`F(${n.index})/F(${n.index-1}) = ${n.ratio.toFixed(6)}`},n.index)}),s.length===0&&e.jsx("p",{className:"text-[10px] text-slate-600",children:"Place more blocks to see convergence"})]}),e.jsxs("div",{className:"flex items-center justify-between text-[10px]",children:[e.jsx("span",{className:"text-slate-500",children:"F(n)/F(n-1)"}),e.jsx("span",{className:"font-mono text-indigo-300",children:a>0?a.toFixed(6):"—"})]}),e.jsxs("div",{className:"flex items-center justify-between text-[10px] mt-0.5",children:[e.jsx("span",{className:"text-slate-500",children:"Golden Ratio φ"}),e.jsx("span",{className:"font-mono text-amber-300",children:E.toFixed(6)})]}),a>0&&e.jsx("div",{className:"mt-2 h-1.5 rounded-full bg-slate-800 overflow-hidden",children:e.jsx("div",{className:"h-full rounded-full bg-gradient-to-r from-indigo-500 to-amber-400 transition-all duration-500",style:{width:`${Math.min(100,(1-Math.abs(a-E))*100)}%`}})})]}),e.jsxs("div",{className:"w-64 rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-2",children:"Formula"}),e.jsxs("div",{className:"rounded-lg bg-slate-800/40 p-3 font-mono text-xs text-slate-300 space-y-1",children:[e.jsx("p",{className:"text-indigo-300",children:"F(n) = F(n-1) + F(n-2)"}),e.jsx("p",{className:"text-slate-500",children:"F(0) = 1, F(1) = 1"})]}),e.jsxs("div",{className:"mt-3 space-y-1 text-[10px] text-slate-500",children:[e.jsx("p",{children:"The Fibonacci sequence appears throughout nature:"}),e.jsx("div",{className:"flex flex-wrap gap-1 mt-1",children:["🌻 Sunflowers","🐚 Shells","🌀 Galaxies","🌿 Leaf patterns"].map(n=>e.jsx("span",{className:"inline-flex rounded-full bg-slate-800/60 px-2 py-0.5 text-[10px] text-slate-400",children:n},n))})]})]})]})}const H=[261.63,293.66,329.63,392,440,523.25,587.33,659.25,783.99,880];function Ie(){const t=x.useRef(!0),s=x.useCallback(()=>fe(),[]),a=x.useCallback(i=>{t.current=i},[]),o=x.useCallback(i=>{if(!t.current)return;const r=s();if(!r)return;const u=i%H.length,c=H[u],m=r.createOscillator(),h=r.createGain();m.type="sine",m.frequency.setValueAtTime(c,r.currentTime),h.gain.setValueAtTime(.12,r.currentTime),h.gain.exponentialRampToValueAtTime(.001,r.currentTime+.35),m.connect(h),h.connect(r.destination),m.start(),m.stop(r.currentTime+.35);const f=r.createOscillator(),p=r.createGain();f.type="triangle",f.frequency.setValueAtTime(c*1.5,r.currentTime),p.gain.setValueAtTime(.04,r.currentTime),p.gain.exponentialRampToValueAtTime(.001,r.currentTime+.25),f.connect(p),p.connect(r.destination),f.start(r.currentTime+.05),f.stop(r.currentTime+.3)},[s]),n=x.useCallback(()=>{if(!t.current)return;const i=s();if(!i)return;const r=i.createOscillator(),u=i.createGain();r.type="sawtooth",r.frequency.setValueAtTime(180,i.currentTime),r.frequency.setValueAtTime(120,i.currentTime+.15),u.gain.setValueAtTime(.08,i.currentTime),u.gain.exponentialRampToValueAtTime(.001,i.currentTime+.3),r.connect(u),u.connect(i.destination),r.start(),r.stop(i.currentTime+.3)},[s]),l=x.useCallback(()=>{if(!t.current)return;const i=s();if(!i)return;[523.25,587.33,659.25,783.99,880,1046.5].forEach((u,c)=>{const m=i.createOscillator(),h=i.createGain();m.type="sine",m.frequency.value=u,h.gain.setValueAtTime(.08,i.currentTime+c*.08),h.gain.exponentialRampToValueAtTime(.001,i.currentTime+c*.08+.2),m.connect(h),h.connect(i.destination),m.start(i.currentTime+c*.08),m.stop(i.currentTime+c*.08+.2)})},[s]),d=x.useCallback(i=>{if(!t.current||i<3)return;const r=s();if(!r)return;const u=600+i*40,c=r.createOscillator(),m=r.createGain();c.type="sine",c.frequency.setValueAtTime(u,r.currentTime),c.frequency.setValueAtTime(u*1.25,r.currentTime+.1),m.gain.setValueAtTime(.06,r.currentTime),m.gain.exponentialRampToValueAtTime(.001,r.currentTime+.2),c.connect(m),m.connect(r.destination),c.start(r.currentTime+.15),c.stop(r.currentTime+.35)},[s]);return{playPlacementTone:o,playErrorTone:n,playCompleteSweep:l,playStreakTone:d,setEnabled:a}}const Re=15;function Ae(){const[t,s]=x.useState("guided"),[a,o]=x.useState([1,1]),[n,l]=x.useState(()=>B()),[d,i]=x.useState(2),[r,u]=x.useState(0),[c,m]=x.useState(0),[h,f]=x.useState(0),[p,N]=x.useState(!1),[S,y]=x.useState(!1),[R,v]=x.useState(null),[K,A]=x.useState(!0),[Q,M]=x.useState(null),[U,k]=x.useState(null),b=x.useRef(null),[J,Z]=x.useState(!0),{playPlacementTone:P,playErrorTone:G,playCompleteSweep:O,playStreakTone:X,setEnabled:L}=Ie(),q=x.useCallback(g=>{Z(g),L(g)},[L]),$=V(a),ee=S?[]:t==="guided"||t==="sandbox"?[{id:0,size:$,isCorrect:!0}]:$e($,3).map((F,w)=>({id:w,size:F,isCorrect:F===$}));x.useEffect(()=>(p&&(b.current=window.setInterval(()=>{f(g=>g+1)},1e3)),()=>{b.current&&clearInterval(b.current)}),[p]);const te=x.useCallback(g=>{if(v(null),k(null),!Te(a,g)){const j=V(a);v(`Incorrect! Expected ${j}`),k(g),G(),setTimeout(()=>{k(null),v(null)},1500),t==="challenge"&&(u(T=>T+_(!1,0,0)),m(0));return}const w=be(n,g,d),z={id:n.length,size:g,x:w.x,y:w.y,direction:w.direction,fibIndex:a.length},Y=[...a,g];if(o(Y),l(j=>[...j,z]),i(j=>j+1),M(z.id),P(z.fibIndex),setTimeout(()=>M(null),600),t==="challenge"){const j=Math.max(0,10-Math.floor(h/5)),T=c+1;m(T),u(ie=>ie+_(!0,T,j)),X(T)}Y.length>=Re&&(y(!0),N(!1),O())},[a,n,d,t,c,h,P,G,O,X]),ne=x.useCallback(()=>{o([1,1]),l(B()),i(2),u(0),m(0),f(0),y(!1),v(null),A(t==="guided"),M(null),k(null),b.current&&clearInterval(b.current),N(t==="challenge")},[t]),se=x.useCallback(g=>{s(g),o([1,1]),l(B()),i(2),u(0),m(0),f(0),y(!1),v(null),A(g==="guided"),M(null),k(null),b.current&&clearInterval(b.current),N(g==="challenge")},[]),ae=x.useCallback(()=>{A(g=>!g)},[]);return{mode:t,sequence:a,placedSquares:n,score:r,streak:c,timer:h,isComplete:S,lastError:R,showHint:K,expectedNext:$,availableBlocks:ee,lastPlacedId:Q,shakeBlockId:U,soundEnabled:J,changeMode:se,placeBlock:te,resetGame:ne,toggleHint:ae,toggleSound:q}}function Oe(){const{mode:t,sequence:s,placedSquares:a,score:o,streak:n,timer:l,isComplete:d,lastError:i,showHint:r,expectedNext:u,availableBlocks:c,lastPlacedId:m,shakeBlockId:h,soundEnabled:f,changeMode:p,placeBlock:N,resetGame:S,toggleHint:y,toggleSound:R}=Ae();return e.jsxs("div",{className:"flex flex-1 flex-col md:flex-row gap-4 md:gap-6 overflow-auto p-4 md:p-6",children:[e.jsx(we,{mode:t,score:o,streak:n,timer:l,isComplete:d,showHint:r,sequence:s,expectedNext:u,soundEnabled:f,onChangeMode:p,onReset:S,onToggleHint:y,onToggleSound:R}),e.jsxs("div",{className:"order-last md:order-first flex md:flex-1 flex-col gap-4 min-h-0 md:min-h-0 md:overflow-auto",children:[e.jsx("div",{className:"min-h-[200px] md:flex-1 flex flex-col",children:e.jsx(Ne,{placedSquares:a,lastPlacedId:m})}),e.jsx(ye,{blocks:c,mode:t,lastError:i,shakeBlockId:h,isComplete:d,onPlaceBlock:N}),e.jsx(Ce,{sequence:s})]})]})}export{Oe as default}; diff --git a/docs/assets/GitPage-2cA3c4jf.js b/docs/assets/GitPage-2cA3c4jf.js new file mode 100644 index 0000000..aec1f9e --- /dev/null +++ b/docs/assets/GitPage-2cA3c4jf.js @@ -0,0 +1,129 @@ +import{r as w,j as i}from"./index-BfWfBQOp.js";import{g as je}from"./audioContext-NbgqvQGz.js";const V=["#818cf8","#34d399","#fb923c","#f472b6","#38bdf8","#a78bfa","#fbbf24","#2dd4bf","#f87171","#c084fc"],H=16,ne=64,ie=40,re=50,oe=50,Ce=28;function ve({state:e}){const{commits:t,branches:s,tags:o,head:n,detachedHead:r,commitOrder:c}=e,a=w.useMemo(()=>{if(c.length===0)return{nodes:[],edges:[],labels:[],width:400,height:300};const m=new Map;s.forEach((k,C)=>{m.set(k.name,V[C%V.length])});const l=new Map;let g=0;const u=[...c].reverse(),x=new Map;for(const k of u){const C=t[k];if(!C)continue;const v=C.branch;l.has(v)||l.set(v,g++),x.set(k,l.get(v))}const b=u.map((k,C)=>{const v=t[k],E=x.get(k)??0;return{id:k,x:re+E*ie,y:oe+C*ne,commit:v,color:m.get(v.branch)??V[0],col:E}}),p=new Map(b.map(k=>[k.id,k])),h=[];for(const k of b)for(let C=0;C0})}const y=r?n:s.find(k=>k.name===n)?.commitId,$=r?null:n,N=[];for(const k of s){const C=p.get(k.commitId);if(!C)continue;const v=k.name===$,E=N.filter(_=>_.commitId===k.commitId).length;N.push({text:k.name,commitId:k.commitId,x:C.x+H+12,y:C.y-6+E*22,color:m.get(k.name)??V[0],isHead:v,isTag:!1})}for(const k of o){const C=p.get(k.commitId);if(!C)continue;const v=N.filter(E=>E.commitId===k.commitId).length;N.push({text:k.name,commitId:k.commitId,x:C.x+H+12,y:C.y-6+v*22,color:"#fbbf24",isHead:!1,isTag:!0})}const O=g,P=Math.max(400,re*2+O*ie+200),M=Math.max(300,oe*2+u.length*ne);return{nodes:b,edges:h,labels:N,width:P,height:M,headCommitId:y}},[t,s,o,n,r,c]);return c.length===0?i.jsx("div",{className:"flex flex-1 items-center justify-center rounded-2xl border border-slate-700/50 bg-slate-950/70 shadow-2xl shadow-black/30 backdrop-blur-sm",children:i.jsxs("div",{className:"text-center px-6",children:[i.jsx("div",{className:"mb-3 text-4xl opacity-40",children:i.jsxs("svg",{width:"48",height:"48",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",className:"mx-auto text-slate-500",children:[i.jsx("circle",{cx:"12",cy:"12",r:"3"}),i.jsx("line",{x1:"12",y1:"3",x2:"12",y2:"9"}),i.jsx("line",{x1:"12",y1:"15",x2:"12",y2:"21"})]})}),i.jsx("p",{className:"text-sm text-slate-400",children:"No commits yet"}),i.jsxs("p",{className:"text-xs text-slate-600 mt-1",children:["Run ",i.jsx("code",{className:"text-indigo-400",children:"git init"}),", then create and commit files"]})]})}):i.jsxs("div",{className:"flex flex-1 flex-col overflow-hidden rounded-2xl border border-slate-700/50 bg-slate-950/70 shadow-2xl shadow-black/30 backdrop-blur-sm",children:[i.jsxs("div",{className:"flex items-center gap-2 border-b border-slate-700/50 bg-slate-900/80 px-4 py-2.5",children:[i.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"text-indigo-400",children:[i.jsx("circle",{cx:"18",cy:"18",r:"3"}),i.jsx("circle",{cx:"6",cy:"6",r:"3"}),i.jsx("path",{d:"M6 21V9a9 9 0 0 0 9 9"})]}),i.jsx("span",{className:"text-xs font-semibold text-slate-300",children:"Commit Graph"}),i.jsx("span",{className:"rounded bg-indigo-500/10 px-2 py-0.5 text-[9px] font-semibold uppercase tracking-wide text-indigo-300 ring-1 ring-indigo-500/20",children:"live history"}),i.jsxs("span",{className:"ml-auto text-[10px] text-slate-500",children:[c.length," commit",c.length!==1?"s":""]})]}),i.jsx("div",{className:"flex-1 overflow-auto bg-[radial-gradient(circle_at_1px_1px,rgba(148,163,184,0.12)_1px,transparent_0)] bg-[length:24px_24px] p-2",children:i.jsxs("svg",{width:a.width,height:a.height,className:"block",style:{minWidth:a.width,minHeight:a.height},children:[a.edges.map((m,l)=>{if(m.from.x===m.to.x)return i.jsx("line",{x1:m.from.x,y1:m.from.y,x2:m.to.x,y2:m.to.y,stroke:m.color,strokeWidth:3,opacity:m.isMerge?.5:.7,strokeDasharray:m.isMerge?"6,3":void 0},`e${l}`);const g=(m.from.y+m.to.y)/2;return i.jsx("path",{d:`M${m.from.x},${m.from.y} C${m.from.x},${g} ${m.to.x},${g} ${m.to.x},${m.to.y}`,stroke:m.color,strokeWidth:3,fill:"none",opacity:m.isMerge?.5:.7,strokeDasharray:m.isMerge?"6,3":void 0},`e${l}`)}),a.nodes.map(m=>{const l=m.id===a.headCommitId;return i.jsxs("g",{children:[l&&i.jsxs("circle",{cx:m.x,cy:m.y,r:H+4,fill:"none",stroke:m.color,strokeWidth:2,opacity:.4,children:[i.jsx("animate",{attributeName:"r",values:`${H+3};${H+6};${H+3}`,dur:"2s",repeatCount:"indefinite"}),i.jsx("animate",{attributeName:"opacity",values:"0.4;0.15;0.4",dur:"2s",repeatCount:"indefinite"})]}),i.jsx("circle",{cx:m.x,cy:m.y,r:H,fill:l?m.color:`${m.color}33`,stroke:m.color,strokeWidth:l?3:2,filter:"drop-shadow(0 6px 8px rgba(0,0,0,0.35))",className:"transition-all duration-300"}),i.jsx("text",{x:m.x,y:m.y+1,textAnchor:"middle",dominantBaseline:"central",className:"select-none pointer-events-none",fill:l?"#0f172a":m.color,fontSize:8,fontWeight:700,fontFamily:"monospace",children:m.id.slice(0,4)}),i.jsx("text",{x:m.x,y:m.y+Ce,textAnchor:"middle",fill:"#94a3b8",fontSize:9,className:"select-none pointer-events-none",children:m.commit.message.length>22?m.commit.message.slice(0,20)+"...":m.commit.message})]},m.id)}),a.labels.map((m,l)=>i.jsxs("g",{children:[i.jsx("rect",{x:m.x-2,y:m.y-8,width:m.text.length*7.5+(m.isHead?40:8)+(m.isTag?10:0),height:18,rx:4,fill:`${m.color}22`,stroke:m.color,strokeWidth:1,opacity:.8}),m.isTag&&i.jsx("text",{x:m.x+4,y:m.y+4,fill:m.color,fontSize:8,children:"tag"}),m.isHead&&i.jsx("text",{x:m.x+4,y:m.y+4,fill:"#fbbf24",fontSize:9,fontWeight:700,fontFamily:"monospace",children:"HEAD→"}),i.jsx("text",{x:m.x+(m.isHead?44:m.isTag?18:4),y:m.y+4,fill:m.color,fontSize:10,fontWeight:600,fontFamily:"monospace",children:m.text})]},`l${l}`))]})})]})}const $e=w.memo(ve);function Ne({history:e,commandHistory:t,onExecute:s,disabled:o,promptBranch:n="main"}){const[r,c]=w.useState(""),[a,m]=w.useState(-1),l=w.useRef(null),g=w.useRef(null);w.useEffect(()=>{l.current?.scrollIntoView({behavior:"smooth"})},[e]),w.useEffect(()=>{o||g.current?.focus()},[o]);const u=w.useCallback(p=>{p.preventDefault(),!(!r.trim()||o)&&(s(r),c(""),m(-1))},[r,o,s]),x=w.useCallback(p=>{if(p.key==="ArrowUp"){if(p.preventDefault(),t.length===0)return;const h=a===-1?t.length-1:Math.max(0,a-1);m(h),c(t[h])}else if(p.key==="ArrowDown"){if(p.preventDefault(),a===-1)return;const h=a+1;h>=t.length?(m(-1),c("")):(m(h),c(t[h]))}},[t,a]),b=p=>{switch(p){case"input":return"text-emerald-400";case"error":return"text-red-400";case"info":return"text-indigo-400";case"hint":return"text-amber-400/90";default:return"text-slate-300"}};return i.jsxs("div",{className:"flex flex-col overflow-hidden rounded-2xl border border-slate-700/50 bg-slate-950/90 font-mono text-xs shadow-2xl shadow-black/30 backdrop-blur-sm",onClick:()=>g.current?.focus(),children:[i.jsxs("div",{className:"flex items-center gap-2 border-b border-slate-700/50 bg-slate-900/80 px-4 py-2.5",children:[i.jsxs("div",{className:"flex gap-1.5",children:[i.jsx("div",{className:"h-2.5 w-2.5 rounded-full bg-red-500/70"}),i.jsx("div",{className:"h-2.5 w-2.5 rounded-full bg-yellow-500/70"}),i.jsx("div",{className:"h-2.5 w-2.5 rounded-full bg-green-500/70"})]}),i.jsx("span",{className:"ml-2 text-[10px] font-semibold text-slate-400",children:"Git Terminal"}),i.jsx("span",{className:"ml-auto rounded bg-slate-950/80 px-2 py-0.5 text-[9px] text-slate-500 ring-1 ring-slate-800",children:"~/visual-repo"})]}),i.jsxs("div",{className:"min-h-[240px] flex-1 space-y-0.5 overflow-y-auto bg-[linear-gradient(rgba(148,163,184,0.03)_1px,transparent_1px)] bg-[length:100%_22px] p-3",children:[e.map((p,h)=>i.jsx("div",{className:`whitespace-pre-wrap leading-relaxed ${b(p.type)}`,children:p.text},h)),i.jsx("div",{ref:l})]}),i.jsxs("form",{onSubmit:u,className:"flex items-center gap-2 border-t border-slate-800/60 bg-slate-900/70 px-3 py-2",children:[i.jsx("span",{className:"select-none text-sky-400",children:"visual-repo"}),i.jsxs("span",{className:"select-none text-slate-600",children:["git:(",n,")"]}),i.jsx("span",{className:"select-none font-bold text-emerald-500",children:"$"}),i.jsx("input",{ref:g,type:"text",value:r,onChange:p=>c(p.target.value),onKeyDown:x,disabled:o,placeholder:o?"Demo running...":"Type a git command...",className:"flex-1 bg-transparent text-slate-200 placeholder-slate-600 outline-none caret-emerald-400",autoComplete:"off",spellCheck:!1})]})]})}const De=w.memo(Ne);function Se({state:e}){const{workingDirectory:t,stagingArea:s,commits:o,head:n,detachedHead:r,branches:c}=e,a=r?n:c.find(h=>h.name===n)?.commitId??null,l=(a?o[a]:null)?.files??{},g=Object.keys(t),u=Object.keys(s),x=h=>h in s?"staged":h in l?t[h]!==l[h]?"modified":"clean":"untracked",b=h=>{switch(h){case"staged":return"text-emerald-400 bg-emerald-500/10";case"modified":return"text-amber-400 bg-amber-500/10";case"untracked":return"text-red-400 bg-red-500/10";default:return"text-slate-500 bg-slate-500/10"}},p=h=>{switch(h){case"staged":return"S";case"modified":return"M";case"untracked":return"U";default:return"✓"}};return i.jsxs("div",{className:"grid grid-cols-1 gap-3 sm:grid-cols-3",children:[i.jsxs("div",{className:"rounded-2xl border border-amber-500/20 bg-slate-950/70 p-3 shadow-xl shadow-black/20 backdrop-blur-sm",children:[i.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[i.jsx("div",{className:"flex h-7 w-7 items-center justify-center rounded-lg bg-amber-500/10 text-amber-300 ring-1 ring-amber-500/20",children:i.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[i.jsx("path",{d:"M3 7h5l2 3h11v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2Z"}),i.jsx("path",{d:"M3 7V5a2 2 0 0 1 2-2h4l2 3h5"})]})}),i.jsx("span",{className:"text-[10px] font-semibold text-slate-300 uppercase tracking-wider",children:"Working Dir"}),i.jsx("span",{className:"ml-auto text-[10px] text-slate-600",children:g.length})]}),i.jsx("div",{className:"space-y-1 max-h-32 overflow-y-auto",children:g.length===0?i.jsx("p",{className:"text-[10px] text-slate-600 italic",children:"empty"}):g.map(h=>{const y=x(h);return i.jsxs("div",{className:"flex items-center gap-1.5 rounded-lg bg-slate-900/50 px-1.5 py-1 ring-1 ring-slate-800/50",children:[i.jsx("span",{className:`inline-flex h-4 w-4 items-center justify-center rounded text-[8px] font-bold ${b(y)}`,children:p(y)}),i.jsx("span",{className:"text-[10px] text-slate-400 truncate",children:h})]},h)})})]}),i.jsxs("div",{className:"rounded-2xl border border-emerald-500/20 bg-slate-950/70 p-3 shadow-xl shadow-black/20 backdrop-blur-sm",children:[i.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[i.jsx("div",{className:"flex h-7 w-7 items-center justify-center rounded-lg bg-emerald-500/10 text-emerald-300 ring-1 ring-emerald-500/20",children:i.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[i.jsx("path",{d:"M12 5v14"}),i.jsx("path",{d:"M5 12h14"})]})}),i.jsx("span",{className:"text-[10px] font-semibold text-slate-300 uppercase tracking-wider",children:"Staging"}),i.jsx("span",{className:"ml-auto text-[10px] text-slate-600",children:u.length})]}),i.jsx("div",{className:"space-y-1 max-h-32 overflow-y-auto",children:u.length===0?i.jsx("p",{className:"text-[10px] text-slate-600 italic",children:"empty"}):u.map(h=>i.jsxs("div",{className:"flex items-center gap-1.5 rounded-lg bg-slate-900/50 px-1.5 py-1 ring-1 ring-slate-800/50",children:[i.jsx("span",{className:"inline-flex h-4 w-4 items-center justify-center rounded text-[8px] font-bold text-emerald-400 bg-emerald-500/10",children:"+"}),i.jsx("span",{className:"text-[10px] text-slate-400 truncate",children:h})]},h))})]}),i.jsxs("div",{className:"rounded-2xl border border-indigo-500/20 bg-slate-950/70 p-3 shadow-xl shadow-black/20 backdrop-blur-sm",children:[i.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[i.jsx("div",{className:"flex h-7 w-7 items-center justify-center rounded-lg bg-indigo-500/10 text-indigo-300 ring-1 ring-indigo-500/20",children:i.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[i.jsx("path",{d:"M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"}),i.jsx("path",{d:"m3.3 7 8.7 5 8.7-5"}),i.jsx("path",{d:"M12 22V12"})]})}),i.jsx("span",{className:"text-[10px] font-semibold text-slate-300 uppercase tracking-wider",children:"Repository"}),i.jsx("span",{className:"ml-auto text-[10px] text-slate-600",children:Object.keys(l).length})]}),i.jsx("div",{className:"space-y-1 max-h-32 overflow-y-auto",children:Object.keys(l).length===0?i.jsx("p",{className:"text-[10px] text-slate-600 italic",children:"no commits"}):Object.keys(l).map(h=>i.jsxs("div",{className:"flex items-center gap-1.5 rounded-lg bg-slate-900/50 px-1.5 py-1 ring-1 ring-slate-800/50",children:[i.jsx("span",{className:"inline-flex h-4 w-4 items-center justify-center rounded text-[8px] font-bold text-indigo-400 bg-indigo-500/10",children:"✓"}),i.jsx("span",{className:"text-[10px] text-slate-400 truncate",children:h})]},h))})]})]})}const Ie=w.memo(Se),Ae=[{title:"Setup",commands:[{cmd:"git init",desc:"Initialize a new repository"},{cmd:"git clone ",desc:"Clone a remote repository"}]},{title:"File Ops",commands:[{cmd:"touch [content]",desc:"Create a new file"},{cmd:"edit ",desc:"Modify a file"},{cmd:"cat ",desc:"View file content"},{cmd:"mv ",desc:"Move/rename a file"},{cmd:"rm ",desc:"Delete a file"},{cmd:"ls",desc:"List files"}]},{title:"Staging & Committing",commands:[{cmd:"git add ",desc:"Stage changes"},{cmd:'git commit -m "msg"',desc:"Create a commit"},{cmd:'git commit -am "msg"',desc:"Stage tracked & commit"},{cmd:"git status",desc:"Show status"},{cmd:"git diff",desc:"Show unstaged changes"},{cmd:"git diff --staged",desc:"Show staged changes"},{cmd:"git status --short",desc:"Compact porcelain view"},{cmd:"git log --oneline --all",desc:"View history"},{cmd:"git show HEAD",desc:"Inspect a commit"},{cmd:"git blame ",desc:"Line attribution"}]},{title:"Branching",commands:[{cmd:"git branch ",desc:"Create branch"},{cmd:"git branch",desc:"List branches"},{cmd:"git branch -r",desc:"List remote branches"},{cmd:"git branch -d ",desc:"Delete a branch"},{cmd:"git checkout ",desc:"Switch branches"},{cmd:"git checkout -b ",desc:"Create & switch"},{cmd:"git switch ",desc:"Modern branch switch"},{cmd:"git switch -c ",desc:"Create & switch"}]},{title:"Merging & Rebasing",commands:[{cmd:"git merge ",desc:"Merge a branch"},{cmd:"git rebase ",desc:"Rebase onto branch"},{cmd:"git cherry-pick ",desc:"Apply a commit"}]},{title:"Remote Sync",commands:[{cmd:"git remote add ",desc:"Add a remote"},{cmd:"git remote -v",desc:"List remotes"},{cmd:"git remote rename ",desc:"Rename a remote"},{cmd:"git remote set-url ",desc:"Change remote URL"},{cmd:"git push -u ",desc:"Push & set upstream"},{cmd:"git push",desc:"Push to tracked remote"},{cmd:"git pull",desc:"Fetch & merge"},{cmd:"git fetch",desc:"Download remote changes"}]},{title:"Undo & Stash",commands:[{cmd:"git reset --soft HEAD~1",desc:"Soft reset (keep staged)"},{cmd:"git reset --mixed HEAD~1",desc:"Mixed reset (unstage)"},{cmd:"git reset --hard HEAD~1",desc:"Hard reset (discard)"},{cmd:"git restore ",desc:"Discard worktree changes"},{cmd:"git restore --staged ",desc:"Unstage a file"},{cmd:"git clean -n",desc:"Preview untracked cleanup"},{cmd:"git clean -f",desc:"Remove untracked files"},{cmd:"git revert HEAD",desc:"Revert last commit"},{cmd:"git stash",desc:"Stash changes"},{cmd:"git stash pop",desc:"Restore stash"},{cmd:"git stash list",desc:"List stashes"}]},{title:"Inspect & Utilities",commands:[{cmd:"git tag ",desc:"Create a tag"},{cmd:"git tag",desc:"List tags"},{cmd:"git tag -d ",desc:"Delete a tag"},{cmd:"git describe HEAD",desc:"Show closest tag/name"},{cmd:"git reflog",desc:"Show HEAD history"},{cmd:"git config --list",desc:"Show Git config"},{cmd:"git rm ",desc:"Remove and stage deletion"},{cmd:"git mv ",desc:"Rename and stage change"}]}];function Re({onRunCommand:e,disabled:t}){const[s,o]=w.useState(null);return i.jsxs("div",{className:"rounded-2xl border border-slate-700/50 bg-slate-950/70 p-3 shadow-2xl shadow-black/20 backdrop-blur-sm",children:[i.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[i.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"text-violet-400",children:i.jsx("path",{d:"M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H20v20H6.5a2.5 2.5 0 0 1 0-5H20"})}),i.jsx("span",{className:"text-xs font-semibold text-slate-300",children:"Command Reference"})]}),i.jsx("div",{className:"space-y-1",children:Ae.map(n=>i.jsxs("div",{children:[i.jsxs("button",{onClick:()=>o(s===n.title?null:n.title),className:"flex w-full items-center justify-between rounded-lg px-2 py-1.5 text-[10px] font-semibold text-slate-400 uppercase tracking-wider transition-colors hover:bg-slate-800/70",children:[n.title,i.jsx("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:`transition-transform ${s===n.title?"rotate-180":""}`,children:i.jsx("path",{d:"m6 9 6 6 6-6"})})]}),s===n.title&&i.jsx("div",{className:"ml-2 space-y-0.5 pb-1",children:n.commands.map(({cmd:r,desc:c})=>{const a=!r.includes("<")&&!r.includes("[");return i.jsxs("button",{onClick:()=>a&&!t&&e(r),disabled:t||!a,className:` + flex w-full items-start gap-2 rounded px-2 py-1 text-left transition-colors + ${a&&!t?"hover:bg-indigo-500/10 hover:ring-1 hover:ring-indigo-500/20 cursor-pointer":"cursor-default opacity-75"} + `,children:[i.jsx("code",{className:"text-[10px] text-emerald-400 font-mono whitespace-nowrap",children:r}),i.jsx("span",{className:"text-[9px] text-slate-500 mt-px",children:c})]},r)})})]},n.title))})]})}const Ee=w.memo(Re);function Te({state:e}){const t=e.detachedHead?null:e.head,s=e.detachedHead?e.head:e.branches.find(a=>a.name===e.head)?.commitId??"",o=s?e.commits[s]?.files??{}:{},n=Object.keys(e.stagingArea).length,r=Object.keys(e.workingDirectory).filter(a=>a in o&&e.workingDirectory[a]!==o[a]&&!(a in e.stagingArea)).length,c=Object.keys(e.workingDirectory).filter(a=>!(a in o)).length;return i.jsxs("aside",{className:"flex flex-col gap-3 rounded-2xl border border-slate-700/50 bg-slate-950/70 p-3 shadow-2xl shadow-black/30 backdrop-blur-sm lg:w-64 lg:shrink-0",children:[i.jsxs("div",{className:"rounded-xl border border-slate-700/40 bg-[radial-gradient(circle_at_top_left,rgba(249,115,22,0.18),transparent_38%),rgba(15,23,42,0.8)] p-3",children:[i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx("div",{className:"flex h-9 w-9 items-center justify-center rounded-xl bg-orange-500/15 text-orange-300 ring-1 ring-orange-500/30",children:i.jsxs("svg",{width:"17",height:"17",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[i.jsx("circle",{cx:"18",cy:"18",r:"3"}),i.jsx("circle",{cx:"6",cy:"6",r:"3"}),i.jsx("path",{d:"M6 21V9a9 9 0 0 0 9 9"})]})}),i.jsxs("div",{className:"min-w-0",children:[i.jsx("div",{className:"truncate text-sm font-bold text-white",children:"visual-repo"}),i.jsx("div",{className:"text-[10px] text-slate-500",children:e.initialized?"Git repository":"No repository"})]})]}),i.jsxs("div",{className:"mt-3 grid grid-cols-3 gap-1.5",children:[i.jsx(Z,{label:"Commits",value:e.commitOrder.length}),i.jsx(Z,{label:"Files",value:Object.keys(e.workingDirectory).length}),i.jsx(Z,{label:"Stash",value:e.stash.length})]})]}),i.jsxs(Y,{title:"Working Tree",children:[i.jsx(Q,{label:"Staged",value:n,color:"emerald"}),i.jsx(Q,{label:"Modified",value:r,color:"amber"}),i.jsx(Q,{label:"Untracked",value:c,color:"rose"})]}),i.jsx(Y,{title:"Branches",children:e.branches.length===0?i.jsx(X,{children:"No branches"}):i.jsx("div",{className:"space-y-1",children:e.branches.map(a=>i.jsxs("div",{className:`flex items-center gap-2 rounded-lg px-2 py-1.5 text-[11px] ${a.name===t?"bg-indigo-500/15 text-indigo-200 ring-1 ring-indigo-500/25":"text-slate-400 hover:bg-slate-800/50"}`,children:[i.jsx("span",{className:`h-2 w-2 rounded-full ${a.name===t?"bg-indigo-400":"bg-slate-600"}`}),i.jsx("span",{className:"truncate font-mono",children:a.name}),i.jsx("span",{className:"ml-auto font-mono text-[9px] text-slate-600",children:a.commitId.slice(0,4)||"-"})]},a.name))})}),i.jsx(Y,{title:"Remotes",children:e.remotes.length===0?i.jsx(X,{children:"No remotes configured"}):i.jsx("div",{className:"space-y-1",children:e.remotes.map(a=>i.jsxs("div",{className:"rounded-lg bg-slate-900/60 px-2 py-1.5 ring-1 ring-slate-800/70",children:[i.jsx("div",{className:"font-mono text-[11px] text-sky-300",children:a.name}),i.jsx("div",{className:"truncate text-[9px] text-slate-600",children:a.url})]},a.name))})}),i.jsx(Y,{title:"Tags & Stash",children:i.jsxs("div",{className:"space-y-1.5",children:[e.tags.length===0?i.jsx(X,{children:"No tags"}):e.tags.map(a=>i.jsxs("div",{className:"rounded-lg bg-amber-500/10 px-2 py-1 text-[11px] font-mono text-amber-300 ring-1 ring-amber-500/20",children:["tag: ",a.name]},a.name)),e.stash.length>0&&e.stash.map((a,m)=>i.jsxs("div",{className:"rounded-lg bg-violet-500/10 px-2 py-1 text-[11px] text-violet-300 ring-1 ring-violet-500/20",children:["stash@","{",m,"}"," ",a.message]},a.id))]})})]})}function Y({title:e,children:t}){return i.jsxs("section",{className:"rounded-xl border border-slate-800/80 bg-slate-900/55 p-3",children:[i.jsx("h3",{className:"mb-2 text-[10px] font-semibold uppercase tracking-wider text-slate-500",children:e}),t]})}function Z({label:e,value:t}){return i.jsxs("div",{className:"rounded-lg bg-slate-950/55 px-2 py-1.5 text-center ring-1 ring-slate-800/80",children:[i.jsx("div",{className:"text-[9px] text-slate-600",children:e}),i.jsx("div",{className:"font-mono text-xs font-bold text-slate-200",children:t})]})}function Q({label:e,value:t,color:s}){const o={emerald:"bg-emerald-500/10 text-emerald-300 ring-emerald-500/25",amber:"bg-amber-500/10 text-amber-300 ring-amber-500/25",rose:"bg-rose-500/10 text-rose-300 ring-rose-500/25"};return i.jsxs("div",{className:`mb-1 flex items-center justify-between rounded-lg px-2 py-1.5 text-[11px] ring-1 ${o[s]}`,children:[i.jsx("span",{children:e}),i.jsx("span",{className:"font-mono font-bold",children:t})]})}function X({children:e}){return i.jsx("p",{className:"text-[11px] italic text-slate-600",children:e})}const Ue=w.memo(Te);function Oe({lessons:e,completedLessons:t,activeLessonId:s,onSelect:o}){const n=r=>{switch(r){case"beginner":return"text-emerald-400 bg-emerald-500/10 ring-emerald-500/30";case"intermediate":return"text-amber-400 bg-amber-500/10 ring-amber-500/30";case"advanced":return"text-rose-400 bg-rose-500/10 ring-rose-500/30"}};return i.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-3 backdrop-blur-sm",children:[i.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[i.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"text-amber-400",children:[i.jsx("path",{d:"M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"}),i.jsx("path",{d:"M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"})]}),i.jsx("span",{className:"text-xs font-semibold text-slate-300",children:"Guided Lessons"}),i.jsxs("span",{className:"ml-auto text-[10px] text-slate-500",children:[t.size,"/",e.length]})]}),i.jsx("div",{className:"space-y-1.5",children:e.map(r=>{const c=t.has(r.id),a=r.id===s;return i.jsxs("button",{onClick:()=>o(r.id),className:` + flex w-full items-start gap-2.5 rounded-lg px-2.5 py-2 text-left transition-all + ${a?"bg-indigo-500/15 ring-1 ring-indigo-500/30":"hover:bg-slate-800/40"} + `,children:[i.jsx("div",{className:` + flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-[10px] font-bold + ${c?"bg-emerald-500/20 text-emerald-400":a?"bg-indigo-500/20 text-indigo-400":"bg-slate-800/60 text-slate-500"} + `,children:c?"✓":r.icon}),i.jsxs("div",{className:"flex-1 min-w-0",children:[i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx("span",{className:`text-[11px] font-semibold truncate ${a?"text-white":"text-slate-300"}`,children:r.title}),i.jsx("span",{className:`shrink-0 rounded-full px-1.5 py-0.5 text-[8px] font-medium ring-1 ${n(r.difficulty)}`,children:r.difficulty})]}),i.jsx("p",{className:"text-[9px] text-slate-500 leading-relaxed mt-0.5 line-clamp-2",children:r.description})]})]},r.id)})})]})}const Me=w.memo(Oe);function Fe({lesson:e,currentStep:t,onRestart:s}){const o=e.steps.length,n=t>=o,r=n?100:t/o*100;return i.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-3 backdrop-blur-sm",children:[i.jsxs("div",{className:"flex items-center justify-between mb-2",children:[i.jsx("span",{className:"text-[10px] font-semibold text-slate-300",children:e.title}),i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx("span",{className:"text-[10px] text-slate-500",children:n?"Complete!":`Step ${t+1}/${o}`}),i.jsx("button",{onClick:s,className:"text-[9px] text-slate-500 hover:text-slate-300 transition-colors",title:"Restart lesson",children:i.jsxs("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[i.jsx("path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"}),i.jsx("path",{d:"M3 3v5h5"})]})})]})]}),i.jsx("div",{className:"h-1.5 w-full rounded-full bg-slate-800/60 overflow-hidden",children:i.jsx("div",{className:`h-full rounded-full transition-all duration-500 ${n?"bg-emerald-500":"bg-indigo-500"}`,style:{width:`${r}%`}})}),!n&&i.jsxs("div",{className:"mt-2.5 rounded-lg bg-slate-800/40 px-2.5 py-2",children:[i.jsx("p",{className:"text-[10px] text-indigo-300 font-medium",children:e.steps[t].instruction}),i.jsxs("p",{className:"text-[9px] text-slate-500 mt-1",children:["💡 ",e.steps[t].hint]})]})]})}const _e=w.memo(Fe);let se=0;function B(){se++;const e=se.toString(16).padStart(7,"0"),t=Math.random().toString(16).slice(2,5);return`${e}${t}`.slice(0,7)}function G(){return{initialized:!1,commits:{},branches:[],tags:[],head:"main",detachedHead:!1,workingDirectory:{},stagingArea:{},stash:[],commitOrder:[],remotes:[],remoteState:{branches:[],commits:{},commitOrder:[]},trackingBranches:{}}}function j(e){return JSON.parse(JSON.stringify(e))}function T(e){return e.detachedHead?null:e.head}function S(e){return e.detachedHead?e.head:e.branches.find(s=>s.name===e.head)?.commitId??null}function L(e){const t=S(e);return t?e.commits[t]??null:null}function le(e,t){if(t==="HEAD")return S(e);if(e.commits[t])return t;const s=e.branches.find(n=>n.name===t);if(s?.commitId)return s.commitId;const o=e.tags.find(n=>n.name===t);if(o?.commitId)return o.commitId;if(t.startsWith("HEAD~")){const n=parseInt(t.slice(5))||1;let r=S(e);for(let c=0;c0;){const n=o.pop();if(s.has(n))continue;s.add(n);const r=e.commits[n];r&&o.push(...r.parentIds)}return s}function de(e,t,s){return te(e,s).has(t)}function f(e,t,s,o){return{success:e,output:t,state:s,action:o}}function d(e,t){return f(!1,e,t,"error")}function He(e){if(e.initialized)return d("Reinitialized existing Git repository",e);const t=j(e);return t.initialized=!0,t.head="main",t.branches=[{name:"main",commitId:""}],f(!0,"Initialized empty Git repository",t,"init")}function Be(e,t){if(!e.initialized)return d("fatal: not a git repository",e);if(t.length===0)return d("Nothing specified, nothing added.",e);const s=j(e),o=L(s),n=o?.files??{};if(t[0]==="."||t[0]==="-A"||t[0]==="--all"){const c=Object.keys(s.workingDirectory);if(c.length===0&&Object.keys(n).length===0)return d("nothing to add",s);let a=0;for(const m of c){const l=s.workingDirectory[m],g=n[m];(l!==g||!g)&&(s.stagingArea[m]=l,a++)}for(const m of Object.keys(n))m in s.workingDirectory||(s.stagingArea[m]="__DELETED__",a++);return a===0?f(!0,"nothing to add (working tree clean)",s,"add"):f(!0,`Added ${a} file(s) to staging area`,s,"add")}const r=t[0];if(!(r in s.workingDirectory)){const c=o?.files??{};return r in c?(s.stagingArea[r]="__DELETED__",f(!0,`Staged deletion of '${r}'`,s,"add")):d(`fatal: pathspec '${r}' did not match any files`,s)}return s.stagingArea[r]=s.workingDirectory[r],f(!0,`Added '${r}' to staging area`,s,"add")}function Le(e,t){if(!e.initialized)return d("fatal: not a git repository",e);let s="";const o=t.includes("-a")||t.includes("--all")||t.includes("-am"),n=t.indexOf("-m");if(n!==-1&&t[n+1])s=t[n+1].replace(/^["']|["']$/g,"");else if(t.includes("-am")){const p=t.indexOf("-am");if(t[p+1])s=t[p+1].replace(/^["']|["']$/g,"");else return d("error: switch `m` requires a value",e)}else return d("error: switch `m` requires a value",e);const r=j(e),c=S(r),m=(c?r.commits[c]:null)?.files??{};if(o){for(const p of Object.keys(r.workingDirectory))p in m&&r.workingDirectory[p]!==m[p]&&(r.stagingArea[p]=r.workingDirectory[p]);for(const p of Object.keys(m))p in r.workingDirectory||(r.stagingArea[p]="__DELETED__")}if(Object.keys(r.stagingArea).length===0)return d('nothing to commit (create/copy files and use "git add" to track)',e);const l={...m};for(const[p,h]of Object.entries(r.stagingArea))h==="__DELETED__"?delete l[p]:l[p]=h;const g=T(r)??"main",u=B(),x={id:u,message:s,parentIds:c&&c!==""?[c]:[],timestamp:Date.now(),files:l,branch:g};if(r.commits[u]=x,r.commitOrder.push(u),r.detachedHead)r.head=u;else{const p=r.branches.find(h=>h.name===r.head);p&&(p.commitId=u)}const b=Object.keys(r.stagingArea).length;return r.stagingArea={},r.workingDirectory={...l},f(!0,`[${g} ${u}] ${s} + ${b} file(s) changed`,r,"commit")}function ze(e,t){if(!e.initialized)return d("fatal: not a git repository",e);const s=t.includes("-r")||t.includes("--remotes"),o=t.includes("-a")||t.includes("--all");if(t.length===0||t[0]==="-l"||t[0]==="--list"||s||o){const a=T(e),m=[];if(!s)for(const l of e.branches)m.push(l.name===a?`* ${l.name}`:` ${l.name}`);if(s||o)for(const l of e.remoteState.branches){const g=e.remotes[0]?.name??"origin";m.push(` remotes/${g}/${l.name}`)}return m.length===0?f(!0,"No branches yet",e,"branch-list"):f(!0,m.join(` +`),e,"branch-list")}if(t[0]==="-d"||t[0]==="-D"||t[0]==="--delete"){const a=t[1];if(!a)return d("fatal: branch name required",e);if(a===T(e))return d(`error: Cannot delete branch '${a}' checked out`,e);const m=j(e),l=m.branches.findIndex(g=>g.name===a);return l===-1?d(`error: branch '${a}' not found`,e):(m.branches.splice(l,1),f(!0,`Deleted branch ${a}`,m,"branch-create"))}const n=t[0];if(e.branches.some(a=>a.name===n))return d(`fatal: A branch named '${n}' already exists`,e);const r=S(e);if(!r||r==="")return d("fatal: Not a valid object name: no commits yet",e);const c=j(e);return c.branches.push({name:n,commitId:r}),f(!0,`Created branch '${n}' at ${r}`,c,"branch-create")}function ae(e,t){if(!e.initialized)return d("fatal: not a git repository",e);if(t.length===0)return d("error: you must specify a branch or commit",e);const s=t[0]==="-b"||t[0]==="-c"||t[0]==="--create",o=s?t[1]:t[0];if(!o)return d("error: switch `b` requires a value",e);const n=j(e);if(s){if(n.branches.some(m=>m.name===o))return d(`fatal: A branch named '${o}' already exists`,e);const c=S(n);if(!c||c==="")return n.branches.push({name:o,commitId:""}),n.head=o,n.detachedHead=!1,f(!0,`Switched to a new branch '${o}'`,n,"checkout");n.branches.push({name:o,commitId:c}),n.head=o,n.detachedHead=!1;const a=n.commits[c];return a&&(n.workingDirectory={...a.files},n.stagingArea={}),f(!0,`Switched to a new branch '${o}'`,n,"checkout")}const r=n.branches.find(c=>c.name===o);return r?(n.head=o,n.detachedHead=!1,r.commitId&&n.commits[r.commitId]&&(n.workingDirectory={...n.commits[r.commitId].files},n.stagingArea={}),f(!0,`Switched to branch '${o}'`,n,"checkout")):n.commits[o]?(n.head=o,n.detachedHead=!0,n.workingDirectory={...n.commits[o].files},n.stagingArea={},f(!0,`HEAD is now at ${o} (detached HEAD state)`,n,"checkout")):d(`error: pathspec '${o}' did not match any branch or commit`,e)}function Ge(e,t){if(!e.initialized)return d("fatal: not a git repository",e);if(t.length===0)return d("error: specify a branch to merge",e);const s=t[0],o=e.branches.find(p=>p.name===s);if(!o)return d(`merge: '${s}' - not something we can merge`,e);const n=S(e);if(!n||n==="")return d("fatal: no commits on current branch",e);const r=o.commitId;if(!r||r==="")return d(`fatal: branch '${s}' has no commits`,e);if(n===r)return f(!0,"Already up to date.",e,"merge");const c=j(e);if(de(c,n,r)){const p=c.branches.find(y=>y.name===c.head);p&&(p.commitId=r);const h=c.commits[r];return h&&(c.workingDirectory={...h.files},c.stagingArea={}),f(!0,`Fast-forward merge: ${c.head} -> ${r}`,c,"merge-fast-forward")}const a=c.commits[n],m=c.commits[r],l={...a.files,...m.files},g=B(),u=T(c)??"main",x={id:g,message:`Merge branch '${s}' into ${u}`,parentIds:[n,r],timestamp:Date.now(),files:l,branch:u};c.commits[g]=x,c.commitOrder.push(g);const b=c.branches.find(p=>p.name===c.head);return b&&(b.commitId=g),c.workingDirectory={...l},c.stagingArea={},f(!0,`Merge made by the 'ort' strategy. +Merge branch '${s}' into ${u}`,c,"merge")}function Pe(e,t){if(!e.initialized)return d("fatal: not a git repository",e);if(t.length===0)return d("error: specify a branch to rebase onto",e);const s=t[0],o=e.branches.find(p=>p.name===s);if(!o)return d(`fatal: invalid upstream '${s}'`,e);const n=S(e);if(!n)return d("fatal: no commits on current branch",e);const r=o.commitId;if(!r)return d(`fatal: branch '${s}' has no commits`,e);if(n===r)return f(!0,`Current branch is up to date with '${s}'.`,e,"rebase");const c=j(e),a=T(c)??"main",m=[];let l=n;const g=te(c,r);for(;l&&!g.has(l);)m.unshift(l),l=c.commits[l]?.parentIds[0]??"";let u=r;for(const p of m){const h=c.commits[p],y=B(),$={id:y,message:h.message,parentIds:[u],timestamp:Date.now(),files:{...h.files},branch:a};c.commits[y]=$,c.commitOrder.push(y),u=y}const x=c.branches.find(p=>p.name===c.head);x&&(x.commitId=u);const b=c.commits[u];return b&&(c.workingDirectory={...b.files},c.stagingArea={}),f(!0,`Successfully rebased ${a} onto ${s}. +Replayed ${m.length} commit(s).`,c,"rebase")}function We(e,t){if(!e.initialized)return d("fatal: not a git repository",e);let s="mixed",o="";for(const m of t)m==="--soft"?s="soft":m==="--mixed"?s="mixed":m==="--hard"?s="hard":o=m;const n=j(e);if(o===""||o==="HEAD"){if(s==="hard"){const m=L(n);return n.stagingArea={},m&&(n.workingDirectory={...m.files}),f(!0,`HEAD is now at ${S(n)}`,n,"reset-hard")}return s==="mixed"?(n.stagingArea={},f(!0,"Unstaged changes after reset",n,"reset-mixed")):f(!0,"Nothing to reset",n,"reset-soft")}let r=o;if(o.startsWith("HEAD~")){const m=parseInt(o.slice(5))||1;let l=S(n);for(let g=0;gl.name===n.head);m&&(m.commitId=r)}const a={soft:"reset-soft",mixed:"reset-mixed",hard:"reset-hard"};return s==="soft"?f(!0,`HEAD is now at ${r}`,n,a[s]):s==="mixed"?(n.stagingArea={},f(!0,`Unstaged changes after reset to ${r}`,n,a[s])):(n.stagingArea={},n.workingDirectory={...c.files},f(!0,`HEAD is now at ${r}`,n,a[s]))}function Ve(e,t){if(!e.initialized)return d("fatal: not a git repository",e);if(t.length===0)return d("usage: git revert ",e);let s=t[0];if(s==="HEAD")s=S(e)??"";else if(s.startsWith("HEAD~")){const h=parseInt(s.slice(5))||1;let y=S(e);for(let $=0;$y.name===a.head);h&&(h.commitId=b)}return a.workingDirectory={...u},a.stagingArea={},f(!0,`[${x} ${b}] Revert "${o.message}"`,a,"revert")}function Ye(e,t){if(!e.initialized)return d("fatal: not a git repository",e);const s=t[0]??"push";if(s==="push"||s==="save"){const o=L(e),n=o?.files??{},r=Object.keys(e.workingDirectory).some(l=>e.workingDirectory[l]!==n[l])||Object.keys(n).some(l=>!(l in e.workingDirectory)),c=Object.keys(e.stagingArea).length>0;if(!r&&!c)return d("No local changes to save",e);const a=j(e),m={id:a.stash.length,message:`WIP on ${T(a)??"HEAD"}`,files:{...a.workingDirectory},stagedFiles:{...a.stagingArea},branch:T(a)??""};return a.stash.unshift(m),a.stagingArea={},a.workingDirectory=o?{...o.files}:{},f(!0,`Saved working directory and index state "${m.message}"`,a,"stash-push")}if(s==="pop"){if(e.stash.length===0)return d("error: no stash entries found",e);const o=j(e),n=o.stash.shift();return o.workingDirectory={...n.files},o.stagingArea={...n.stagedFiles},f(!0,`Restored stash@{0}: ${n.message} +Dropped stash@{0}`,o,"stash-pop")}if(s==="list"){if(e.stash.length===0)return f(!0,"No stash entries",e,"stash-push");const o=e.stash.map((n,r)=>`stash@{${r}}: ${n.message}`);return f(!0,o.join(` +`),e,"stash-push")}if(s==="drop"){if(e.stash.length===0)return d("error: no stash entries found",e);const o=j(e);return o.stash.shift(),f(!0,"Dropped stash@{0}",o,"stash-pop")}return d(`error: unknown stash subcommand '${s}'`,e)}function qe(e,t){if(!e.initialized)return d("fatal: not a git repository",e);if(t.length===0)return d("error: specify a commit to cherry-pick",e);const s=t[0],o=e.commits[s];if(!o)return d(`fatal: bad object ${s}`,e);const n=j(e),r=S(n),m={...(r?n.commits[r]:null)?.files??{},...o.files},l=T(n)??"HEAD",g=B(),u={id:g,message:o.message,parentIds:r?[r]:[],timestamp:Date.now(),files:m,branch:l};if(n.commits[g]=u,n.commitOrder.push(g),n.detachedHead)n.head=g;else{const x=n.branches.find(b=>b.name===n.head);x&&(x.commitId=g)}return n.workingDirectory={...m},n.stagingArea={},f(!0,`[${l} ${g}] ${o.message}`,n,"cherry-pick")}function Je(e,t){if(!e.initialized)return d("fatal: not a git repository",e);if(t.length===0)return e.tags.length===0?f(!0,"No tags",e,"tag"):f(!0,e.tags.map(r=>r.name).join(` +`),e,"tag");if(t[0]==="-d"||t[0]==="--delete"){const r=t[1];if(!r)return d("fatal: tag name required",e);const c=j(e),a=c.tags.findIndex(m=>m.name===r);return a===-1?d(`error: tag '${r}' not found`,e):(c.tags.splice(a,1),f(!0,`Deleted tag '${r}'`,c,"tag"))}const s=t[0];if(e.tags.some(r=>r.name===s))return d(`fatal: tag '${s}' already exists`,e);const o=t[1]??S(e);if(!o)return d("fatal: no commits yet",e);const n=j(e);return n.tags.push({name:s,commitId:o}),f(!0,`Created tag '${s}' at ${o}`,n,"tag")}function Ke(e,t){if(!e.initialized)return d("fatal: not a git repository",e);if(t.length===0||t[0]==="-v"){if(e.remotes.length===0)return f(!0,"No remotes configured",e,"remote");const s=t[0]==="-v",o=e.remotes.map(n=>s?`${n.name} ${n.url} (fetch) +${n.name} ${n.url} (push)`:n.name);return f(!0,o.join(` +`),e,"remote")}if(t[0]==="add"){const s=t[1],o=t[2];if(!s||!o)return d("usage: git remote add ",e);if(e.remotes.some(r=>r.name===s))return d(`error: remote ${s} already exists`,e);const n=j(e);return n.remotes.push({name:s,url:o}),f(!0,`Added remote '${s}' -> ${o}`,n,"remote")}if(t[0]==="remove"||t[0]==="rm"){const s=t[1];if(!s)return d("usage: git remote remove ",e);const o=j(e),n=o.remotes.findIndex(r=>r.name===s);return n===-1?d(`fatal: No such remote: '${s}'`,e):(o.remotes.splice(n,1),f(!0,`Removed remote '${s}'`,o,"remote"))}if(t[0]==="rename"){const s=t[1],o=t[2];if(!s||!o)return d("usage: git remote rename ",e);if(e.remotes.some(c=>c.name===o))return d(`error: remote ${o} already exists`,e);const n=j(e),r=n.remotes.find(c=>c.name===s);if(!r)return d(`fatal: No such remote: '${s}'`,e);r.name=o;for(const[c,a]of Object.entries(n.trackingBranches))a.startsWith(`${s}/`)&&(n.trackingBranches[c]=a.replace(`${s}/`,`${o}/`));return f(!0,`Renamed remote '${s}' to '${o}'`,n,"remote")}if(t[0]==="set-url"){const s=t[1],o=t[2];if(!s||!o)return d("usage: git remote set-url ",e);const n=j(e),r=n.remotes.find(c=>c.name===s);return r?(r.url=o,f(!0,`Updated remote '${s}' -> ${o}`,n,"remote")):d(`fatal: No such remote: '${s}'`,e)}return d(`error: unknown subcommand '${t[0]}'`,e)}function Ze(e,t){if(!e.initialized)return d("fatal: not a git repository",e);const s=t.includes("-u")||t.includes("--set-upstream"),o=t.filter(x=>x!=="-u"&&x!=="--set-upstream"),n=o[0]??e.remotes[0]?.name,r=o[1]??T(e);if(!n)return d("fatal: No configured push destination.\nRun `git remote add origin ` first.",e);if(!r)return d("fatal: not on a branch, cannot push",e);const c=e.remotes.find(x=>x.name===n);if(!c)return d(`fatal: '${n}' does not appear to be a git repository`,e);const a=e.branches.find(x=>x.name===r);if(!a)return d(`error: src refspec '${r}' does not match any`,e);if(!a.commitId||a.commitId==="")return d("error: no commits on branch, nothing to push",e);const m=j(e),l=te(m,a.commitId);for(const x of l)m.remoteState.commits[x]||(m.remoteState.commits[x]={...m.commits[x]},m.remoteState.commitOrder.includes(x)||m.remoteState.commitOrder.push(x));const g=m.remoteState.branches.find(x=>x.name===r);g?g.commitId=a.commitId:m.remoteState.branches.push({name:r,commitId:a.commitId}),s&&(m.trackingBranches[r]=`${n}/${r}`);const u=l.size;return f(!0,`Enumerating objects: ${u}, done. +Counting objects: 100% (${u}/${u}), done. +To ${c.url} + ${a.commitId.slice(0,7)} ${r} -> ${r}`,m,"push")}function Qe(e,t){if(!e.initialized)return d("fatal: not a git repository",e);const s=t[0]??e.remotes[0]?.name;if(!s)return d("fatal: No remote repository specified.",e);const o=e.remotes.find(a=>a.name===s);if(!o)return d(`fatal: '${s}' does not appear to be a git repository`,e);const n=j(e);let r=0;for(const[a,m]of Object.entries(n.remoteState.commits))n.commits[a]||(n.commits[a]={...m},n.commitOrder.includes(a)||n.commitOrder.push(a),r++);const c=[`From ${o.url}`];for(const a of n.remoteState.branches)c.push(` * [${r>0?"new branch":"up to date"}] ${a.name} -> ${s}/${a.name}`);return f(!0,c.join(` +`),n,"fetch")}function Xe(e,t){if(!e.initialized)return d("fatal: not a git repository",e);const s=t[0]??e.remotes[0]?.name,o=t[1]??T(e);if(!s)return d("fatal: No remote repository specified.",e);if(!o)return d("fatal: not on a branch, cannot pull",e);const n=e.remotes.find(h=>h.name===s);if(!n)return d(`fatal: '${s}' does not appear to be a git repository`,e);const r=e.remoteState.branches.find(h=>h.name===o);if(!r)return d(`fatal: couldn't find remote ref '${o}'`,e);const c=j(e);for(const[h,y]of Object.entries(c.remoteState.commits))c.commits[h]||(c.commits[h]={...y},c.commitOrder.includes(h)||c.commitOrder.push(h));const a=c.branches.find(h=>h.name===o),m=a?.commitId,l=r.commitId;if(m===l)return f(!0,"Already up to date.",c,"pull");if(!m||m===""){a&&(a.commitId=l);const h=c.commits[l];return h&&(c.workingDirectory={...h.files},c.stagingArea={}),f(!0,`From ${n.url} +Fast-forward to ${l}`,c,"pull")}if(de(c,m,l)){a&&(a.commitId=l);const h=c.commits[l];return h&&(c.workingDirectory={...h.files},c.stagingArea={}),f(!0,`From ${n.url} +Updating ${m.slice(0,7)}..${l.slice(0,7)} +Fast-forward`,c,"pull")}const g=c.commits[m],u=c.commits[l];if(!g||!u)return d("fatal: unable to merge histories",e);const x={...g.files,...u.files},b=B(),p={id:b,message:`Merge remote-tracking branch '${s}/${o}'`,parentIds:[m,l],timestamp:Date.now(),files:x,branch:o};return c.commits[b]=p,c.commitOrder.push(b),a&&(a.commitId=b),c.workingDirectory={...x},c.stagingArea={},f(!0,`From ${n.url} +Merge made by the 'ort' strategy.`,c,"pull")}function et(e,t){if(e.initialized)return d("fatal: destination path already exists and is not empty",e);if(t.length===0)return d("usage: git clone ",e);const s=t[0],o=j(e);o.initialized=!0,o.head="main",o.branches=[{name:"main",commitId:""}],o.remotes=[{name:"origin",url:s}],o.trackingBranches={main:"origin/main"};const n=B(),r={id:n,message:"Initial commit (cloned)",parentIds:[],timestamp:Date.now(),files:{"README.md":`# Cloned from ${s}`},branch:"main"};return o.commits[n]=r,o.commitOrder.push(n),o.branches[0].commitId=n,o.workingDirectory={...r.files},o.remoteState.commits[n]={...r},o.remoteState.commitOrder.push(n),o.remoteState.branches.push({name:"main",commitId:n}),f(!0,`Cloning into '${s.split("/").pop()??"repo"}'... +remote: Enumerating objects: 1, done. +Receiving objects: 100% (1/1), done.`,o,"clone")}function tt(e,t){if(!e.initialized)return d("fatal: not a git repository",e);const s=S(e);if(!s||s==="")return f(!0,"No commits yet",e,"log");const o=t.includes("--oneline"),n=t.includes("--all"),r=t.includes("--graph");let c;if(n)c=[...e.commitOrder].reverse();else{c=[];const l=new Set,g=[s];for(;g.length>0;){const u=g.pop();if(l.has(u))continue;l.add(u),c.push(u);const x=e.commits[u];x&&g.push(...x.parentIds)}}const a=T(e),m=[];for(const l of c){const g=e.commits[l];if(!g)continue;const u=e.branches.filter(y=>y.commitId===l).map(y=>y.name),x=e.tags.filter(y=>y.commitId===l).map(y=>`tag: ${y.name}`),b=[...u.map(y=>y===a?`HEAD -> ${y}`:y),...x],p=b.length>0?` (${b.join(", ")})`:"",h=r?"* ":"";o?m.push(`${h}${l} ${p}${g.message}`):(m.push(`${h}commit ${l}${p}`),m.push(` ${g.message}`),m.push(""))}return f(!0,m.join(` +`)||"No commits",e,"log")}function nt(e,t=[]){if(!e.initialized)return d("fatal: not a git repository",e);const s=T(e),o=[],n=t.includes("-s")||t.includes("--short"),r=L(e),c=r?.files??{},a=[],m=[];for(const[u,x]of Object.entries(e.stagingArea))x==="__DELETED__"?(a.push(` deleted: ${u}`),m.push(`D ${u}`)):u in c?(a.push(` modified: ${u}`),m.push(`M ${u}`)):(a.push(` new file: ${u}`),m.push(`A ${u}`));const l=[],g=[];for(const u of Object.keys(e.workingDirectory))u in e.stagingArea||(u in c?e.workingDirectory[u]!==c[u]&&(l.push(` modified: ${u}`),m.push(` M ${u}`)):(g.push(` ${u}`),m.push(`?? ${u}`)));if(n)return f(!0,m.join(` +`)||"",e,"status");if(s){o.push(`On branch ${s}`);const u=e.trackingBranches[s];u&&o.push(`Your branch is tracking '${u}'`)}else o.push(`HEAD detached at ${e.head}`);return a.length>0&&(o.push(""),o.push("Changes to be committed:"),o.push(...a)),l.length>0&&(o.push(""),o.push("Changes not staged for commit:"),o.push(...l)),g.length>0&&(o.push(""),o.push("Untracked files:"),o.push(...g)),a.length===0&&l.length===0&&g.length===0&&(r?(o.push(""),o.push("nothing to commit, working tree clean")):(o.push(""),o.push("No commits yet"))),f(!0,o.join(` +`),e,"status")}function it(e,t){if(!e.initialized)return d("fatal: not a git repository",e);const s=t.includes("--staged")||t.includes("--cached"),n=L(e)?.files??{},r=[];if(s){for(const[a,m]of Object.entries(e.stagingArea)){const l=n[a];r.push(`diff --git a/${a} b/${a}`),m==="__DELETED__"?(r.push(`--- a/${a}`),r.push("+++ /dev/null"),r.push(`- ${l}`)):l?(r.push(`--- a/${a}`),r.push(`+++ b/${a}`),r.push(`- ${l}`),r.push(`+ ${m}`)):(r.push("--- /dev/null"),r.push(`+++ b/${a}`),r.push(`+ ${m}`)),r.push("")}return f(!0,r.join(` +`)||"No staged differences",e,"diff")}const c=new Set([...Object.keys(e.workingDirectory),...Object.keys(n)]);for(const a of c){if(a in e.stagingArea)continue;const m=e.workingDirectory[a],l=n[a];m!==l&&(r.push(`diff --git a/${a} b/${a}`),l?m?(r.push(`--- a/${a}`),r.push(`+++ b/${a}`),r.push(`- ${l}`),r.push(`+ ${m}`)):(r.push(`--- a/${a}`),r.push("+++ /dev/null"),r.push(`- ${l}`)):(r.push("--- /dev/null"),r.push(`+++ b/${a}`),r.push(`+ ${m}`)),r.push(""))}return f(!0,r.join(` +`)||"No differences",e,"diff")}function rt(e,t){if(!e.initialized)return d("fatal: not a git repository",e);const s=t.includes("--staged"),o=t.includes("--worktree")||!s,r=t.filter(g=>g!=="--staged"&&g!=="--worktree"&&g!=="--source")[0]??".",c=j(e),a=L(c)?.files??{},m=r==="."?Array.from(new Set([...Object.keys(c.workingDirectory),...Object.keys(c.stagingArea),...Object.keys(a)])):[r];let l=0;for(const g of m)s&&g in c.stagingArea&&(delete c.stagingArea[g],l++),o&&(g in a?(c.workingDirectory[g]=a[g],l++):g in c.workingDirectory&&!(g in c.stagingArea)&&(delete c.workingDirectory[g],l++));return l===0?f(!0,"nothing to restore",c,"restore"):f(!0,`Restored ${l} path${l===1?"":"s"}`,c,"restore")}function ot(e,t){if(!e.initialized)return d("fatal: not a git repository",e);const s=t.includes("-f")||t.includes("--force"),o=t.includes("-n")||t.includes("--dry-run"),n=L(e)?.files??{},r=Object.keys(e.workingDirectory).filter(a=>!(a in n)&&!(a in e.stagingArea));if(r.length===0)return f(!0,"Nothing to clean",e,"clean");if(!s&&!o)return d("fatal: clean.requireForce defaults to true and neither -i, -n, nor -f given",e);if(o)return f(!0,r.map(a=>`Would remove ${a}`).join(` +`),e,"clean");const c=j(e);for(const a of r)delete c.workingDirectory[a];return f(!0,r.map(a=>`Removing ${a}`).join(` +`),c,"clean")}function st(e,t){if(!e.initialized)return d("fatal: not a git repository",e);const s=t[0]??"HEAD",o=le(e,s);if(!o)return d(`fatal: ambiguous argument '${s}'`,e);const n=e.commits[o];if(!n)return d(`fatal: bad object ${s}`,e);const c=(n.parentIds[0]?e.commits[n.parentIds[0]]:null)?.files??{},a=Object.keys(n.files).filter(u=>n.files[u]!==c[u]),m=Object.keys(c).filter(u=>!(u in n.files)),l=[...a,...m],g=[`commit ${n.id}`,"Author: Visual Git User ",`Date: ${new Date(n.timestamp).toLocaleString()}`,"",` ${n.message}`,"",l.length>0?l.map(u=>`diff --git a/${u} b/${u}`).join(` +`):"No file changes"].join(` +`);return f(!0,g,e,"show")}function at(e){if(!e.initialized)return d("fatal: not a git repository",e);const t=[...e.commitOrder].reverse();if(t.length===0)return f(!0,"No reflog entries yet",e,"reflog");const s=t.map((o,n)=>{const r=e.commits[o];return`${o} HEAD@{${n}}: commit: ${r?.message??"unknown"}`});return f(!0,s.join(` +`),e,"reflog")}function ct(e,t){if(!e.initialized)return d("fatal: not a git repository",e);const s=t[0]??"HEAD",o=le(e,s);if(!o)return d("fatal: No names found, cannot describe anything.",e);const n=e.tags.find(r=>r.commitId===o);return n?f(!0,n.name,e,"show"):f(!0,o,e,"show")}function mt(e,t){if(!e.initialized)return d("fatal: not a git repository",e);const s=t[0];if(!s)return d("usage: git blame ",e);const o=e.workingDirectory[s];if(o===void 0)return d(`fatal: no such path '${s}' in HEAD`,e);const n=S(e)??"0000000",r=o.split(` +`);return f(!0,r.map((c,a)=>`${n.slice(0,7)} (Visual User ${a+1}) ${c}`).join(` +`),e,"show")}function lt(e,t){return t.length===0||t.includes("--list")?f(!0,["user.name=Visual Git User","user.email=learner@example.com","init.defaultBranch=main","core.editor=cursor","pull.rebase=false"].join(` +`),e,"config"):t.length>=2?f(!0,`Set ${t[0]}=${t.slice(1).join(" ")}`,e,"config"):f(!0,`${t[0]}=Visual Git User`,e,"config")}function dt(e,t){if(!e.initialized)return d("fatal: not a git repository",e);const s=t.find(n=>!n.startsWith("-"));if(!s)return d("usage: git rm ",e);if(!(s in e.workingDirectory))return d(`fatal: pathspec '${s}' did not match any files`,e);const o=j(e);return delete o.workingDirectory[s],o.stagingArea[s]="__DELETED__",f(!0,`rm '${s}'`,o,"add")}function ut(e,t){return e.initialized?ue(e,t):d("fatal: not a git repository",e)}function ht(e,t){if(t.length===0)return d("usage: touch [content]",e);const s=j(e),o=t[0],n=t.slice(1).join(" ")||`content of ${o}`;return s.workingDirectory[o]=n,f(!0,`Created file '${o}'`,s,"add")}function gt(e,t){if(t.length<2)return d("usage: edit ",e);const s=t[0];if(!(s in e.workingDirectory))return d(`error: file '${s}' does not exist`,e);const o=j(e);return o.workingDirectory[s]=t.slice(1).join(" "),f(!0,`Modified '${s}'`,o,"add")}function ft(e,t){if(t.length===0)return d("usage: rm ",e);const s=t[0];if(!(s in e.workingDirectory))return d(`fatal: pathspec '${s}' did not match any files`,e);const o=j(e);return delete o.workingDirectory[s],f(!0,`Removed '${s}'`,o,"add")}function ue(e,t){if(t.length<2)return d("usage: mv ",e);const s=t[0],o=t[1];if(!(s in e.workingDirectory))return d(`fatal: bad source, source='${s}', destination='${o}'`,e);const n=j(e);return n.workingDirectory[o]=n.workingDirectory[s],delete n.workingDirectory[s],n.stagingArea[o]=n.workingDirectory[o],n.stagingArea[s]="__DELETED__",f(!0,`Renamed '${s}' -> '${o}'`,n,"add")}function pt(e,t){if(t.length===0)return d("usage: cat ",e);const s=t[0],o=e.workingDirectory[s];return o===void 0?d(`cat: ${s}: No such file or directory`,e):f(!0,o,e,"status")}function xt(e){const t=Object.keys(e.workingDirectory);return t.length===0?f(!0,"(empty working directory)",e,"status"):f(!0,t.join(` +`),e,"status")}function bt(e,t){const s=t.indexOf(">"),o=t.indexOf(">>");if(o!==-1){const n=t.slice(0,o).join(" "),r=t[o+1];if(!r)return d("usage: echo >> ",e);const c=j(e),a=c.workingDirectory[r]??"";return c.workingDirectory[r]=a+(a?` +`:"")+n,f(!0,"",c,"add")}if(s!==-1){const n=t.slice(0,s).join(" "),r=t[s+1];if(!r)return d("usage: echo > ",e);const c=j(e);return c.workingDirectory[r]=n,f(!0,"",c,"add")}return f(!0,t.join(" "),e,"status")}function yt(){return{success:!0,output:`Available commands: + + Shell commands: + touch [content] Create a new file + edit Modify file content + rm Remove a file + mv Move/rename a file + cat Show file content + echo > Write text to file + echo >> Append text to file + ls List working directory files + + Repository setup: + git init Initialize a new repository + git clone Clone a remote repository + git remote add Add a remote + git remote -v List remotes + git remote remove Remove a remote + git remote rename + Rename a remote + git remote set-url + Update a remote URL + + Staging & committing: + git add Stage changes + git commit -m "msg" Create a commit + git commit -am "msg" Stage tracked files and commit + git status Show working tree status + git status --short Compact status output + git diff [--staged] Show working tree changes + git log [--oneline] [--all] [--graph] + Show commit history + git show [commit] Show commit details + git blame Show line attribution + + Branching: + git branch [name] List or create branches + git branch -d Delete a branch + git branch -r List remote branches + git checkout Switch branches + git checkout -b Create & switch to new branch + git switch Switch branches + git switch -c Create & switch to new branch + + Merging & rebasing: + git merge Merge a branch + git rebase Rebase onto a branch + git cherry-pick Apply a commit + + Remote sync: + git push [-u] [remote] [branch] + Push commits to remote + git pull [remote] [branch] + Fetch & merge from remote + git fetch [remote] Download remote changes + + Undo: + git reset [--soft|--mixed|--hard] [target] + Reset current HEAD + git restore [--staged] + Restore worktree or unstage files + git clean -n|-f Preview or remove untracked files + git revert Revert a commit (creates new commit) + git stash [push|pop|list|drop] + Stash working changes + git tag [name] [commit] Create or list tags + git tag -d Delete a tag + git describe [commit] Show nearest tag or commit id + git reflog Show HEAD movement history + git config --list Show simulated Git config + git rm Remove and stage deletion + git mv Rename and stage change + + help Show this help message + clear Clear the terminal`,state:G(),action:"log"}}function ce(e,t){const s=e.trim();if(!s)return f(!0,"",t);const o=wt(s),n=o[0],r=o.slice(1);if(n==="help"){const m=yt();return m.state=t,m}if(n==="clear")return f(!0,"__CLEAR__",t);if(n==="touch")return ht(t,r);if(n==="edit")return gt(t,r);if(n==="rm")return ft(t,r);if(n==="mv")return ue(t,r);if(n==="cat")return pt(t,r);if(n==="ls")return xt(t);if(n==="echo")return bt(t,r);if(n==="mkdir")return f(!0,`Created directory '${r[0]??""}'`,t);if(n==="pwd")return f(!0,"/home/user/project",t);if(n!=="git")return d(`command not found: ${n}. Type 'help' for available commands.`,t);const c=r[0],a=r.slice(1);switch(c){case"init":return He(t);case"clone":return et(t,a);case"add":return Be(t,a);case"commit":return Le(t,a);case"branch":return ze(t,a);case"checkout":return ae(t,a);case"switch":return ae(t,a);case"merge":return Ge(t,a);case"rebase":return Pe(t,a);case"reset":return We(t,a);case"restore":return rt(t,a);case"clean":return ot(t,a);case"revert":return Ve(t,a);case"stash":return Ye(t,a);case"cherry-pick":return qe(t,a);case"tag":return Je(t,a);case"log":return tt(t,a);case"show":return st(t,a);case"reflog":return at(t);case"describe":return ct(t,a);case"blame":return mt(t,a);case"config":return lt(t,a);case"rm":return dt(t,a);case"mv":return ut(t,a);case"status":return nt(t,a);case"diff":return it(t,a);case"remote":return Ke(t,a);case"push":return Ze(t,a);case"pull":return Xe(t,a);case"fetch":return Qe(t,a);default:return d(`git: '${c}' is not a git command. See 'help'.`,t)}}function wt(e){const t=[];let s="",o=null;for(let n=0;nje(),[]),n=w.useCallback((l,g,u,x=.06)=>{if(!e.current)return;const b=o();if(!b)return;const p=b.createOscillator(),h=b.createGain();p.type=g,p.frequency.setValueAtTime(l,b.currentTime),h.gain.setValueAtTime(x,b.currentTime),h.gain.exponentialRampToValueAtTime(.001,b.currentTime+u),p.connect(h),h.connect(b.destination),p.start(b.currentTime),p.stop(b.currentTime+u)},[o]),r=w.useCallback((l,g,u,x=.04)=>{if(e.current)for(const b of l)n(b,g,u,x)},[n]),c=w.useCallback((l,g,u,x=.05)=>{if(!e.current)return;const b=o();b&&l.forEach((p,h)=>{const y=b.createOscillator(),$=b.createGain(),N=b.currentTime+h*u*.7;y.type=g,y.frequency.setValueAtTime(p,N),$.gain.setValueAtTime(x,N),$.gain.exponentialRampToValueAtTime(.001,N+u),y.connect($),$.connect(b.destination),y.start(N),y.stop(N+u)})},[o]),a=w.useCallback(l=>{switch(l){case"init":c([261.63,329.63,392,523.25],"sine",.15);break;case"add":n(440,"sine",.1);break;case"commit":c([523.25,659.25,783.99],"sine",.12);break;case"branch-create":case"tag":n(587.33,"triangle",.18);break;case"branch-list":case"log":case"status":case"diff":case"remote":case"show":case"reflog":case"config":n(523.25,"sine",.06,.03);break;case"checkout":c([392,493.88],"triangle",.1);break;case"merge":case"merge-fast-forward":r([523.25,659.25,783.99],"sine",.3);break;case"rebase":c([329.63,392,493.88,587.33],"triangle",.1);break;case"reset-soft":case"reset-mixed":case"reset-hard":case"restore":case"clean":c([493.88,392,329.63],"sawtooth",.1,.03);break;case"revert":c([440,349.23,293.66],"triangle",.1,.04);break;case"stash-push":case"stash-pop":n(349.23,"triangle",.15);break;case"cherry-pick":c([523.25,659.25,783.99],"sine",.12);break;case"push":c([392,493.88,587.33,659.25],"sine",.1);break;case"pull":case"fetch":c([659.25,587.33,493.88,392],"sine",.1);break;case"clone":c([261.63,329.63,392,493.88,523.25],"sine",.12);break;case"error":n(196,"sawtooth",.2,.04);break}},[n,r,c]),m=w.useCallback(l=>{e.current=l,s(l)},[]);return{soundEnabled:t,toggleSound:m,playForAction:a}}const me=[{id:"basics",title:"Getting Started",description:"Learn to initialize a repo, create files, stage changes, and make your first commit.",icon:"1",difficulty:"beginner",steps:[{instruction:"Initialize a new Git repository.",expectedCommand:"git init",hint:"Use `git init` to create a new repository.",explanation:'You created a .git directory. Git is now tracking this folder. The default branch is "main".'},{instruction:"Create a file called `index.html` with some content.",expectedCommand:/^touch index\.html/,hint:"Use `touch index.html Hello World` to create a file.",explanation:`The file now exists in your working directory but Git doesn't know about it yet — it's "untracked".`},{instruction:"Check the repository status to see untracked files.",expectedCommand:"git status",hint:"Use `git status` to see the current state.",explanation:"Git shows index.html as an untracked file. It won't be included in commits until you stage it."},{instruction:"Stage the file for commit.",expectedCommand:/^git add/,hint:"Use `git add index.html` or `git add .` to stage all files.",explanation:`The file moved from Working Directory to the Staging Area (also called the "index"). It's ready to be committed.`},{instruction:"Commit the staged changes with a message.",expectedCommand:/^git commit -m/,hint:'Use `git commit -m "Initial commit"` to save a snapshot.',explanation:"You created your first commit! A commit is a permanent snapshot of your staged files. It has a unique hash ID."},{instruction:"View the commit log.",expectedCommand:/^git log/,hint:"Use `git log` or `git log --oneline` to see commit history.",explanation:"The log shows your commit with its hash, branch pointer (HEAD -> main), and message. This is your project's history."}]},{id:"branching",title:"Branching Basics",description:"Create branches to work on features without affecting the main codebase.",icon:"2",difficulty:"beginner",steps:[{instruction:"First, initialize a repo, create a file, and make a commit. Run: `git init`",expectedCommand:"git init",hint:"Type `git init`",explanation:"Repository initialized. Let's set up a base commit to branch from."},{instruction:"Create and commit a file: `touch app.js`",expectedCommand:/^touch app\.js/,hint:"Type `touch app.js`",explanation:"File created in working directory."},{instruction:'Stage and commit: `git add .` then `git commit -m "Initial commit"`',expectedCommand:/^git add/,hint:"Use `git add .`",explanation:"Files staged. Now commit them."},{instruction:"Now commit the changes.",expectedCommand:/^git commit -m/,hint:'Use `git commit -m "Initial commit"`',explanation:"Base commit created on main. Now we have something to branch from."},{instruction:"Create a new branch called `feature`.",expectedCommand:/^git branch feature$/,hint:"Use `git branch feature` to create a new branch pointer.",explanation:`A new branch pointer "feature" was created, pointing at the same commit as main. But you're still ON main.`},{instruction:"List all branches to see where you are.",expectedCommand:/^git branch$/,hint:"Use `git branch` with no arguments.",explanation:"The asterisk (*) shows your current branch. You're on main, but feature also exists."},{instruction:"Switch to the feature branch.",expectedCommand:/^git (checkout|switch) feature$/,hint:"Use `git checkout feature` or `git switch feature`.",explanation:'HEAD now points to "feature". Any new commits will advance the feature branch, leaving main behind.'},{instruction:"Create a new file on this branch and commit it.",expectedCommand:/^touch/,hint:"Try `touch feature.js new feature code`",explanation:"File created. Stage and commit it to make the branches diverge."},{instruction:"Stage and commit the new file.",expectedCommand:/^git add/,hint:"Use `git add .`",explanation:"Staged. Now commit."},{instruction:"Commit with a message.",expectedCommand:/^git commit -m/,hint:'Use `git commit -m "Add feature"`',explanation:"The feature branch is now one commit ahead of main. Look at the graph — the branches have diverged!"},{instruction:"Switch back to main and see how the working directory changes.",expectedCommand:/^git (checkout|switch) main$/,hint:"Use `git checkout main`",explanation:"Back on main. Notice that the feature file is gone from the working directory — each branch has its own snapshot."}]},{id:"merging",title:"Merging Branches",description:"Combine work from different branches using merge.",icon:"3",difficulty:"intermediate",steps:[{instruction:"Let's set up. Run: `git init`",expectedCommand:"git init",hint:"Type `git init`",explanation:"Repository ready."},{instruction:"Create a file and make the initial commit.",expectedCommand:/^touch/,hint:'Try `touch main.js console.log("hello")`',explanation:"File created."},{instruction:"Stage everything.",expectedCommand:/^git add/,hint:"Use `git add .`",explanation:"Staged."},{instruction:"Commit.",expectedCommand:/^git commit -m/,hint:'Use `git commit -m "Initial commit"`',explanation:"Initial commit on main."},{instruction:"Create and switch to a new branch in one step.",expectedCommand:/^git checkout -b/,hint:"Use `git checkout -b feature` — the `-b` flag creates AND switches.",explanation:"Shortcut! You created the branch and switched to it in one command."},{instruction:"Add a new file on the feature branch.",expectedCommand:/^touch/,hint:"Try `touch feature.js`",explanation:"New file on feature branch."},{instruction:"Stage and commit it.",expectedCommand:/^git add/,hint:"Use `git add .`",explanation:"Staged."},{instruction:"Commit the feature work.",expectedCommand:/^git commit -m/,hint:'Use `git commit -m "Add feature"`',explanation:"Feature branch has a new commit. Now let's merge it into main."},{instruction:"Switch back to main to prepare for the merge.",expectedCommand:/^git (checkout|switch) main$/,hint:"Use `git checkout main`",explanation:"On main again. We'll merge feature INTO main."},{instruction:"Merge the feature branch into main.",expectedCommand:/^git merge feature/,hint:"Use `git merge feature` while on main.",explanation:'Since main had no new commits, Git did a "fast-forward" merge — it just moved the main pointer forward. In the graph you can see both branches point to the same commit now.'}]},{id:"remotes",title:"Remote Repositories",description:"Push and pull changes to and from a remote repository.",icon:"4",difficulty:"intermediate",steps:[{instruction:"Initialize a repository.",expectedCommand:"git init",hint:"Type `git init`",explanation:"Local repository created."},{instruction:'Add a remote called "origin".',expectedCommand:/^git remote add origin/,hint:"Use `git remote add origin https://github.com/user/repo.git`",explanation:`You linked a remote repository named "origin". This is where you'll push and pull code.`},{instruction:"Verify the remote was added.",expectedCommand:/^git remote/,hint:"Use `git remote -v` to see remotes with URLs.",explanation:"The remote is configured with fetch and push URLs."},{instruction:"Create a file and make a commit.",expectedCommand:/^touch/,hint:"Try `touch README.md # My Project`",explanation:"File created."},{instruction:"Stage the file.",expectedCommand:/^git add/,hint:"Use `git add .`",explanation:"Staged."},{instruction:"Commit it.",expectedCommand:/^git commit -m/,hint:'Use `git commit -m "First commit"`',explanation:"Commit created locally. Now let's push it to the remote."},{instruction:"Push to the remote and set up tracking with `-u`.",expectedCommand:/^git push/,hint:"Use `git push -u origin main` to push and set the upstream branch.",explanation:"Your commit is now on the remote! The `-u` flag sets up tracking so future `git push` and `git pull` know where to go."},{instruction:"Try fetching from the remote.",expectedCommand:/^git fetch/,hint:"Use `git fetch origin` to download remote changes without merging.",explanation:"Fetch downloads new commits from the remote but doesn't change your working directory. It's a safe way to check for updates."},{instruction:"Now try pulling (fetch + merge in one step).",expectedCommand:/^git pull/,hint:"Use `git pull origin main` to fetch and merge.",explanation:"Pull = fetch + merge. Since we just pushed, everything is up to date. In a real workflow, pull brings down teammates' changes."}]},{id:"rebasing",title:"Rebasing",description:"Rewrite history by replaying commits on top of another branch.",icon:"5",difficulty:"advanced",steps:[{instruction:"Initialize and create a base commit. Run: `git init`",expectedCommand:"git init",hint:"Type `git init`",explanation:"Repository ready."},{instruction:"Create a file: `touch base.js`",expectedCommand:/^touch base/,hint:"Type `touch base.js`",explanation:"File created."},{instruction:"Stage and commit.",expectedCommand:/^git add/,hint:"Use `git add .`",explanation:"Staged."},{instruction:"Commit.",expectedCommand:/^git commit -m/,hint:'Use `git commit -m "Base commit"`',explanation:"Base commit on main."},{instruction:"Create and switch to a feature branch: `git checkout -b feature`",expectedCommand:/^git checkout -b feature/,hint:"Type `git checkout -b feature`",explanation:"On feature branch."},{instruction:"Create a file and commit on feature.",expectedCommand:/^touch/,hint:"Try `touch feat.js`",explanation:"Feature file created."},{instruction:"Stage it.",expectedCommand:/^git add/,hint:"Use `git add .`",explanation:"Staged."},{instruction:"Commit.",expectedCommand:/^git commit -m/,hint:'Use `git commit -m "Feature work"`',explanation:"Feature has a commit. Now let's add a commit to main so the branches diverge."},{instruction:"Switch to main: `git checkout main`",expectedCommand:/^git (checkout|switch) main$/,hint:"Type `git checkout main`",explanation:"On main."},{instruction:"Add a new commit on main.",expectedCommand:/^touch/,hint:"Try `touch hotfix.js`",explanation:"File created on main."},{instruction:"Stage and commit on main.",expectedCommand:/^git add/,hint:"Use `git add .`",explanation:"Staged."},{instruction:"Commit.",expectedCommand:/^git commit -m/,hint:'Use `git commit -m "Hotfix on main"`',explanation:"Now main and feature have diverged. Look at the graph — they branched apart."},{instruction:"Switch to feature: `git checkout feature`",expectedCommand:/^git (checkout|switch) feature$/,hint:"Type `git checkout feature`",explanation:"On feature. Now we'll rebase onto main."},{instruction:"Rebase feature onto main.",expectedCommand:/^git rebase main/,hint:"Use `git rebase main` to replay your feature commits on top of main.",explanation:`Rebase "replayed" your feature commits on top of main's latest. The result is a linear history — as if you started the feature after the hotfix. Notice the feature commit got a new hash.`}]},{id:"undoing",title:"Undoing Changes",description:"Learn reset, revert, and stash to undo and save work.",icon:"6",difficulty:"intermediate",steps:[{instruction:"Initialize and create a base. Run: `git init`",expectedCommand:"git init",hint:"Type `git init`",explanation:"Repository ready."},{instruction:"Create a file: `touch app.js version 1`",expectedCommand:/^touch/,hint:"Try `touch app.js version 1`",explanation:"File created."},{instruction:"Stage and commit.",expectedCommand:/^git add/,hint:"Use `git add .`",explanation:"Staged."},{instruction:"Commit.",expectedCommand:/^git commit -m/,hint:'Use `git commit -m "Version 1"`',explanation:"First commit."},{instruction:"Edit the file: `edit app.js version 2`",expectedCommand:/^edit app\.js/,hint:"Use `edit app.js version 2`",explanation:"File modified in working directory."},{instruction:"Stage and commit the change.",expectedCommand:/^git add/,hint:"Use `git add .`",explanation:"Staged."},{instruction:"Commit version 2.",expectedCommand:/^git commit -m/,hint:'Use `git commit -m "Version 2"`',explanation:"Two commits now. Let's try reverting the last one."},{instruction:"Revert the last commit (creates a NEW commit that undoes it).",expectedCommand:/^git revert/,hint:"Use `git revert HEAD` to create a new commit that undoes the last one.",explanation:"Revert is safe — it doesn't erase history. It creates a NEW commit that undoes the changes. The original commit still exists."},{instruction:"Now make another change: `edit app.js version 3`",expectedCommand:/^edit/,hint:"Use `edit app.js version 3`",explanation:"Working directory changed."},{instruction:"Stash the changes instead of committing.",expectedCommand:/^git stash/,hint:"Use `git stash` to save your changes temporarily.",explanation:"Changes saved to the stash stack. Your working directory is clean again. Useful when you need to switch branches quickly."},{instruction:"Restore the stashed changes.",expectedCommand:/^git stash pop/,hint:"Use `git stash pop` to restore and remove from stash.",explanation:"Your changes are back! Stash is a temporary shelf for uncommitted work."}]},{id:"tagging",title:"Tags & Cherry-pick",description:"Mark important commits with tags and selectively apply commits.",icon:"7",difficulty:"advanced",steps:[{instruction:"Initialize: `git init`",expectedCommand:"git init",hint:"Type `git init`",explanation:"Ready."},{instruction:"Create and commit a file.",expectedCommand:/^touch/,hint:"Try `touch v1.js`",explanation:"File created."},{instruction:"Stage.",expectedCommand:/^git add/,hint:"Use `git add .`",explanation:"Staged."},{instruction:"Commit.",expectedCommand:/^git commit -m/,hint:'Use `git commit -m "Release v1.0"`',explanation:"First commit."},{instruction:"Tag this commit as v1.0.",expectedCommand:/^git tag v1\.0/,hint:"Use `git tag v1.0` to mark this commit.",explanation:"Tags are permanent bookmarks. Unlike branches, they don't move when you make new commits. Great for marking releases."},{instruction:"Create a feature branch and add a commit.",expectedCommand:/^git checkout -b/,hint:"Use `git checkout -b feature`",explanation:"On feature branch."},{instruction:"Add a feature file.",expectedCommand:/^touch/,hint:"Try `touch feature.js`",explanation:"File created."},{instruction:"Stage and commit.",expectedCommand:/^git add/,hint:"Use `git add .`",explanation:"Staged."},{instruction:"Commit.",expectedCommand:/^git commit -m/,hint:'Use `git commit -m "Cool feature"`',explanation:"Feature committed. Now let's cherry-pick it onto main without merging the whole branch."},{instruction:"Check the log to find the commit hash.",expectedCommand:/^git log/,hint:"Use `git log --oneline` to see commit IDs.",explanation:`Note the hash of the "Cool feature" commit. You'll need it for cherry-pick.`},{instruction:"Switch to main.",expectedCommand:/^git (checkout|switch) main$/,hint:"Use `git checkout main`",explanation:"On main."},{instruction:"Cherry-pick the feature commit by its hash (copy from the log above).",expectedCommand:/^git cherry-pick/,hint:"Use `git cherry-pick ` with the commit ID from the log.",explanation:"Cherry-pick copies a single commit to your current branch. The new commit has different hash but the same changes. Useful for applying hotfixes across branches."}]},{id:"workflow",title:"Full Workflow",description:"Practice a complete feature development workflow from start to finish.",icon:"8",difficulty:"advanced",steps:[{instruction:"Clone a remote repository.",expectedCommand:/^git clone/,hint:"Use `git clone https://github.com/user/project.git`",explanation:'You cloned a remote repo. This automatically sets up "origin" as a remote and creates a local main branch.'},{instruction:"Create a feature branch from main.",expectedCommand:/^git checkout -b/,hint:"Use `git checkout -b feature/login`",explanation:"Working on a feature branch keeps main stable."},{instruction:"Create the feature file.",expectedCommand:/^touch/,hint:"Try `touch login.js`",explanation:"Feature development starts."},{instruction:"Stage your work.",expectedCommand:/^git add/,hint:"Use `git add .`",explanation:"Changes staged."},{instruction:"Commit with a descriptive message.",expectedCommand:/^git commit -m/,hint:'Use `git commit -m "Implement login feature"`',explanation:"Feature committed locally."},{instruction:"Push your feature branch to the remote.",expectedCommand:/^git push/,hint:"Use `git push -u origin feature/login` (or whatever you named your branch).",explanation:"Your feature branch is now on the remote. In a real workflow, you'd open a Pull Request here."},{instruction:"Switch back to main.",expectedCommand:/^git (checkout|switch) main$/,hint:"Use `git checkout main`",explanation:"Back on main."},{instruction:"Pull latest changes from remote.",expectedCommand:/^git pull/,hint:"Use `git pull origin main`",explanation:"You're up to date with the remote."},{instruction:"Merge the feature branch into main.",expectedCommand:/^git merge/,hint:"Use `git merge feature/login` (or whatever you named it).",explanation:"Feature merged into main!"},{instruction:"Tag this as a release.",expectedCommand:/^git tag/,hint:"Use `git tag v1.0`",explanation:"Release tagged."},{instruction:"Push everything to the remote.",expectedCommand:/^git push/,hint:"Use `git push origin main`",explanation:"All done! You completed a full Git workflow: clone -> branch -> develop -> push -> merge -> tag -> push. This is the foundation of modern collaborative development."}]}],ee=["git init","touch index.html ","touch style.css body { margin: 0; }","git add .",'git commit -m "Initial commit"',"git status --short","git tag v1.0","git checkout -b feature/login","touch auth.js function login() {}","git add auth.js",'git commit -m "Add login feature"',"git show HEAD","git checkout main","touch README.md # My Project","git add README.md",'git commit -m "Add README"',"git merge feature/login","git remote add origin https://github.com/user/repo.git","git push -u origin main","git checkout -b feature/dashboard","touch dashboard.js function render() {}","git add .",'git commit -m "Add dashboard"',"git push -u origin feature/dashboard","git checkout main","git describe v1.0","git reflog","git log --oneline --all"],jt={slow:1800,normal:1e3,fast:400};function Ct(){const[e,t]=w.useState("freeplay"),[s,o]=w.useState(G()),[n,r]=w.useState([{type:"info",text:'Welcome to Git Visualizer! Type commands or click "Run Demo" to start.'},{type:"info",text:`Type "help" for available commands. +`}]),[c,a]=w.useState([]),[m,l]=w.useState(!1),[g,u]=w.useState(!1),[x,b]=w.useState("normal"),[p,h]=w.useState(0),y=w.useRef(!1),$=w.useRef(!1),N=w.useRef("normal"),{soundEnabled:O,toggleSound:P,playForAction:M}=kt(),[k,C]=w.useState(null),[v,E]=w.useState(0),[_,q]=w.useState(new Set),he=w.useCallback(I=>{const A=I.trim();if(!A)return;a(R=>[...R,A]);const D=ce(A,s),U=[{type:"input",text:`$ ${A}`}];if(D.output==="__CLEAR__"){r([]);return}if(D.output&&U.push({type:D.success?"output":"error",text:D.output}),e==="guided"&&k){const R=k.steps[v];if(R)if((typeof R.expectedCommand=="string"?A===R.expectedCommand:R.expectedCommand.test(A))&&D.success)if(U.push({type:"info",text:` +✓ ${R.explanation} +`}),v+1new Set(z).add(k.id));else D.success&&U.push({type:"hint",text:`💡 Hint: ${R.hint}`})}r(R=>[...R,...U]),o(D.state),M(D.action)},[s,M,e,k,v]),J=w.useCallback(async()=>{for(;$.current&&!y.current;)await new Promise(I=>setTimeout(I,100))},[]),ge=w.useCallback(async()=>{l(!0),u(!1),h(0),y.current=!1,$.current=!1;let I=G();o(I),r([{type:"info",text:`--- Running Demo --- +`}]),a([]);const A=ee.length;for(let D=0;DsetTimeout(W,U)),await J(),y.current)break;const R=ee[D],F=ce(R,I);I=F.state;const z=[{type:"input",text:`$ ${R}`}];F.output&&F.output!=="__CLEAR__"&&z.push({type:F.success?"output":"error",text:F.output}),r(W=>[...W,...z]),o(F.state),a(W=>[...W,R]),h(D+1),M(F.action)}y.current||(r(D=>[...D,{type:"info",text:` +--- Demo Complete! Try your own commands. ---`}]),h(A)),l(!1),u(!1)},[M,J]),fe=w.useCallback(()=>{y.current=!0,$.current=!1,l(!1),u(!1)},[]),pe=w.useCallback(()=>{$.current=!0,u(!0)},[]),xe=w.useCallback(()=>{$.current=!1,u(!1)},[]),be=w.useCallback(I=>{N.current=I,b(I)},[]),ye=w.useCallback(()=>{o(G()),r([{type:"info",text:`Repository reset. Type "help" for available commands. +`}]),a([]),l(!1),y.current=!0},[]),we=w.useCallback(I=>{t(I),C(null),E(0),o(G()),a([]),l(!1),y.current=!0,r(I==="guided"?[{type:"info",text:`📚 Guided Mode — Choose a lesson from the panel to begin. +`}]:[{type:"info",text:`Freeplay Mode — Type any git commands. Use "help" for a list. +`}])},[]),K=w.useCallback(I=>{const A=me.find(U=>U.id===I);if(!A)return;C(A),E(0),o(G()),a([]);const D=A.steps[0];r([{type:"info",text:`📖 ${A.title} +`},{type:"info",text:`${A.description} +`},{type:"hint",text:`→ Step 1: ${D.instruction}`}])},[]),ke=w.useCallback(()=>{k&&K(k.id)},[k,K]);return{mode:e,gitState:s,history:n,commandHistory:c,isRunningDemo:m,demoPaused:g,demoSpeed:x,demoProgress:p,demoTotal:ee.length,soundEnabled:O,toggleSound:P,executeCommand:he,runDemo:ge,stopDemo:fe,pauseDemo:pe,resumeDemo:xe,changeDemoSpeed:be,resetState:ye,switchMode:we,activeLesson:k,currentStep:v,completedLessons:_,startLesson:K,restartLesson:ke,lessons:me}}const vt=[{value:"slow",label:"0.5x"},{value:"normal",label:"1x"},{value:"fast",label:"2.5x"}];function Dt(){const{mode:e,gitState:t,history:s,commandHistory:o,isRunningDemo:n,demoPaused:r,demoSpeed:c,demoProgress:a,demoTotal:m,soundEnabled:l,toggleSound:g,executeCommand:u,runDemo:x,stopDemo:b,pauseDemo:p,resumeDemo:h,changeDemoSpeed:y,resetState:$,switchMode:N,activeLesson:O,currentStep:P,completedLessons:M,startLesson:k,restartLesson:C,lessons:v}=Ct(),E=t.detachedHead?`detached @ ${t.head.slice(0,7)}`:t.head;return i.jsxs("div",{className:"flex flex-1 flex-col overflow-hidden bg-[radial-gradient(circle_at_top_left,rgba(249,115,22,0.12),transparent_28%),radial-gradient(circle_at_bottom_right,rgba(99,102,241,0.12),transparent_30%)]",children:[i.jsxs("div",{className:"flex flex-wrap items-center gap-2 border-b border-slate-800/70 bg-slate-950/70 px-4 py-2.5 shadow-lg shadow-black/20 backdrop-blur-sm sm:px-6",children:[i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"text-orange-400",children:[i.jsx("circle",{cx:"18",cy:"18",r:"3"}),i.jsx("circle",{cx:"6",cy:"6",r:"3"}),i.jsx("path",{d:"M6 21V9a9 9 0 0 0 9 9"})]}),i.jsxs("div",{children:[i.jsx("h2",{className:"text-sm font-bold text-white",children:"Git Visualizer"}),i.jsx("p",{className:"hidden text-[10px] text-slate-500 sm:block",children:"Interactive local and remote repository simulator"})]})]}),i.jsxs("div",{className:"flex items-center rounded-lg bg-slate-800/60 p-0.5",children:[i.jsx("button",{onClick:()=>N("guided"),className:`rounded-md px-3 py-1 text-[10px] font-medium transition-all ${e==="guided"?"bg-amber-500/20 text-amber-300 shadow-sm":"text-slate-500 hover:text-slate-300"}`,children:"Guided"}),i.jsx("button",{onClick:()=>N("freeplay"),className:`rounded-md px-3 py-1 text-[10px] font-medium transition-all ${e==="freeplay"?"bg-indigo-500/20 text-indigo-300 shadow-sm":"text-slate-500 hover:text-slate-300"}`,children:"Freeplay"})]}),t.initialized&&i.jsxs("div",{className:"flex items-center gap-1.5 rounded-full bg-slate-800/60 px-2.5 py-1",children:[i.jsx("div",{className:"h-1.5 w-1.5 rounded-full bg-emerald-400"}),i.jsx("span",{className:"text-[10px] font-medium text-slate-300 font-mono",children:E}),t.remotes.length>0&&i.jsxs(i.Fragment,{children:[i.jsx("div",{className:"h-3 w-px bg-slate-700 mx-1"}),i.jsxs("svg",{width:"9",height:"9",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",className:"text-slate-500",children:[i.jsx("circle",{cx:"12",cy:"12",r:"10"}),i.jsx("line",{x1:"2",y1:"12",x2:"22",y2:"12"}),i.jsx("path",{d:"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"})]}),i.jsx("span",{className:"text-[9px] text-slate-500 font-mono",children:t.remotes[0].name})]})]}),i.jsxs("div",{className:"ml-auto flex items-center gap-2",children:[i.jsxs("button",{onClick:()=>g(!l),className:`flex items-center gap-1.5 rounded-lg px-2.5 py-1.5 text-[10px] font-medium transition-all ${l?"bg-indigo-500/15 text-indigo-300 ring-1 ring-indigo-500/30":"bg-slate-800/50 text-slate-500"}`,children:[l?i.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[i.jsx("polygon",{points:"11 5 6 9 2 9 2 15 6 15 11 19 11 5"}),i.jsx("path",{d:"M15.54 8.46a5 5 0 0 1 0 7.07"}),i.jsx("path",{d:"M19.07 4.93a10 10 0 0 1 0 14.14"})]}):i.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[i.jsx("polygon",{points:"11 5 6 9 2 9 2 15 6 15 11 19 11 5"}),i.jsx("line",{x1:"23",y1:"9",x2:"17",y2:"15"}),i.jsx("line",{x1:"17",y1:"9",x2:"23",y2:"15"})]}),"Sound"]}),e==="freeplay"&&!n&&i.jsxs("button",{onClick:x,className:"flex items-center gap-1.5 rounded-lg bg-emerald-500/15 px-3 py-1.5 text-[10px] font-medium text-emerald-300 ring-1 ring-emerald-500/30 transition-all hover:bg-emerald-500/25",children:[i.jsx("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"currentColor",children:i.jsx("polygon",{points:"5 3 19 12 5 21 5 3"})}),"Run Demo"]}),i.jsxs("button",{onClick:e==="guided"&&O?C:$,className:"flex items-center gap-1.5 rounded-lg bg-slate-800/50 px-3 py-1.5 text-[10px] font-medium text-slate-400 transition-all hover:bg-slate-700/50 hover:text-slate-300",children:[i.jsxs("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",children:[i.jsx("path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"}),i.jsx("path",{d:"M3 3v5h5"})]}),"Reset"]})]})]}),n&&i.jsxs("div",{className:"flex items-center gap-3 border-b border-slate-800/50 px-4 py-2 sm:px-6 bg-slate-900/40",children:[i.jsx("button",{onClick:r?h:p,className:"flex h-7 w-7 items-center justify-center rounded-lg bg-slate-800/60 text-slate-300 hover:bg-slate-700/60 hover:text-white transition-all",title:r?"Resume":"Pause",children:r?i.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"currentColor",children:i.jsx("polygon",{points:"5 3 19 12 5 21 5 3"})}):i.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"currentColor",children:[i.jsx("rect",{x:"6",y:"4",width:"4",height:"16",rx:"1"}),i.jsx("rect",{x:"14",y:"4",width:"4",height:"16",rx:"1"})]})}),i.jsx("button",{onClick:b,className:"flex h-7 w-7 items-center justify-center rounded-lg bg-red-500/10 text-red-400 hover:bg-red-500/20 transition-all",title:"Stop",children:i.jsx("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"currentColor",children:i.jsx("rect",{x:"6",y:"6",width:"12",height:"12",rx:"1"})})}),i.jsxs("div",{className:"flex-1 flex items-center gap-2",children:[i.jsx("div",{className:"flex-1 h-1.5 rounded-full bg-slate-800/60 overflow-hidden",children:i.jsx("div",{className:"h-full rounded-full bg-indigo-500 transition-all duration-300",style:{width:`${a/m*100}%`}})}),i.jsxs("span",{className:"text-[10px] text-slate-500 font-mono tabular-nums w-10 text-right",children:[a,"/",m]})]}),i.jsx("div",{className:"flex items-center gap-1 rounded-lg bg-slate-800/60 p-0.5",children:vt.map(({value:_,label:q})=>i.jsx("button",{onClick:()=>y(_),className:`rounded-md px-2 py-1 text-[10px] font-medium transition-all ${c===_?"bg-indigo-500/20 text-indigo-300 shadow-sm":"text-slate-500 hover:text-slate-300"}`,children:q},_))}),r&&i.jsx("span",{className:"text-[10px] text-amber-400 font-medium animate-pulse",children:"PAUSED"})]}),i.jsxs("div",{className:"flex flex-1 flex-col gap-3 overflow-auto p-3 sm:p-4 xl:flex-row xl:gap-4",children:[i.jsx(Ue,{state:t}),i.jsxs("div",{className:"flex min-w-0 flex-1 flex-col gap-3",children:[i.jsx("div",{className:"flex-1 flex min-h-[250px]",children:i.jsx($e,{state:t})}),t.initialized&&i.jsx(Ie,{state:t})]}),i.jsxs("div",{className:"flex flex-col gap-3 xl:w-[410px] 2xl:w-[460px]",children:[e==="guided"&&O&&i.jsx(_e,{lesson:O,currentStep:P,onRestart:C}),i.jsx("div",{className:"flex-1",children:i.jsx(De,{history:s,commandHistory:o,onExecute:u,disabled:n,promptBranch:E})}),e==="guided"?i.jsx(Me,{lessons:v,completedLessons:M,activeLessonId:O?.id,onSelect:k}):i.jsx(Ee,{onRunCommand:u,disabled:n})]})]})]})}export{Dt as default}; diff --git a/docs/assets/GraphTraversalPage-D6V7J1Sh.js b/docs/assets/GraphTraversalPage-D6V7J1Sh.js new file mode 100644 index 0000000..a57c705 --- /dev/null +++ b/docs/assets/GraphTraversalPage-D6V7J1Sh.js @@ -0,0 +1,18 @@ +import{c as W,r,j as e,F as Q,d as Z}from"./index-BfWfBQOp.js";import{N as a,A as D,r as ee,S as te}from"./index-Cj8HB9AY.js";import{V as se,a as ae}from"./volume-x-ChIHiT28.js";import{S as ne}from"./square-BSu6WBc6.js";import{P as oe}from"./play-WRQgdyAG.js";import{R as re}from"./rotate-ccw-EKzY5q_W.js";import{S as le}from"./shuffle-Ri9xSsK2.js";import{g as ie}from"./audioContext-NbgqvQGz.js";const ce=[["path",{d:"M21 21H8a2 2 0 0 1-1.42-.587l-3.994-3.999a2 2 0 0 1 0-2.828l10-10a2 2 0 0 1 2.829 0l5.999 6a2 2 0 0 1 0 2.828L12.834 21",key:"g5wo59"}],["path",{d:"m5.082 11.09 8.828 8.828",key:"1wx5vj"}]],de=W("eraser",ce);const ue=[["path",{d:"M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0",key:"1r0f0z"}],["circle",{cx:"12",cy:"10",r:"3",key:"ilqhr7"}]],me=W("map-pin",ue);const pe=[["path",{d:"m14.622 17.897-10.68-2.913",key:"vj2p1u"}],["path",{d:"M18.376 2.622a1 1 0 1 1 3.002 3.002L17.36 9.643a.5.5 0 0 0 0 .707l.944.944a2.41 2.41 0 0 1 0 3.408l-.944.944a.5.5 0 0 1-.707 0L8.354 7.348a.5.5 0 0 1 0-.707l.944-.944a2.41 2.41 0 0 1 3.408 0l.944.944a.5.5 0 0 0 .707 0z",key:"18tc5c"}],["path",{d:"M9 8c-1.804 2.71-3.97 3.46-6.583 3.948a.507.507 0 0 0-.302.819l7.32 8.883a1 1 0 0 0 1.185.204C12.735 20.405 16 16.792 16 15",key:"ytzfxy"}]],xe=W("paintbrush",pe),fe={[a.EMPTY]:"bg-slate-900/40 hover:bg-slate-700/60",[a.WALL]:"bg-slate-300 animate-wall",[a.START]:"bg-emerald-500 shadow-lg shadow-emerald-500/30",[a.END]:"bg-rose-500 shadow-lg shadow-rose-500/30",[a.VISITED]:"bg-indigo-500/70 animate-visited",[a.PATH]:"bg-amber-400 animate-path shadow-md shadow-amber-400/30",[a.EXPLORING]:"bg-cyan-400 animate-pulse"};function he({row:l,col:n,type:y,onMouseDown:x,onMouseEnter:g,onMouseUp:b}){return e.jsx("div",{className:` + w-[22px] h-[22px] border border-slate-800/30 transition-colors duration-100 + cursor-pointer select-none ${fe[y]} + `,onMouseDown:()=>x(l,n),onMouseEnter:()=>g(l,n),onMouseUp:b,role:"button","aria-label":`Node ${l},${n} - ${y}`})}const ge=r.memo(he,(l,n)=>l.type===n.type&&l.row===n.row&&l.col===n.col);function be({grid:l,isRunning:n,isDrawing:y,setIsDrawing:x,handleNodeInteraction:g}){const b=r.useCallback((f,s)=>{n||(x(!0),g(f,s))},[n,x,g]),T=r.useCallback((f,s)=>{!y||n||g(f,s)},[y,n,g]),m=r.useCallback(()=>{x(!1)},[x]),t=r.useRef(null),u=r.useRef(null),[i,w]=r.useState(1),[h,N]=r.useState("auto");return r.useEffect(()=>{const f=t.current,s=u.current;if(!f||!s)return;const o=()=>{const c=f.clientWidth,p=s.scrollWidth;p>c?w(c/p):w(1)};o();const d=new ResizeObserver(o);return d.observe(f),()=>d.disconnect()},[l]),r.useLayoutEffect(()=>{const f=u.current;f&&N(f.scrollHeight*i)},[i,l]),e.jsx("div",{ref:t,className:"w-full overflow-hidden",children:e.jsx("div",{style:{transform:`scale(${i})`,transformOrigin:"top left",height:h},children:e.jsx("div",{ref:u,className:"inline-block rounded-xl border border-slate-700/50 bg-slate-950/80 p-2 shadow-2xl backdrop-blur-sm",onMouseLeave:()=>x(!1),children:l.map((f,s)=>e.jsx("div",{className:"flex",children:f.map(o=>e.jsx(ge,{row:o.row,col:o.col,type:o.type,onMouseDown:b,onMouseEnter:T,onMouseUp:m},`${o.row}-${o.col}`))},s))})})})}const ye=["bfs","dfs","dijkstra","astar"],Te=["slow","medium","fast","instant"],we=[{mode:"wall",label:"Wall",icon:xe},{mode:"eraser",label:"Eraser",icon:de},{mode:"start",label:"Start",icon:me},{mode:"end",label:"End",icon:Q}];function je({algorithm:l,setAlgorithm:n,speed:y,setSpeed:x,drawMode:g,setDrawMode:b,isRunning:T,isFinished:m,visitedCount:t,pathLength:u,onVisualize:i,onStop:w,onReset:h,onClearVisualization:N,onGenerateMaze:f,soundEnabled:s,onToggleSound:o}){const d=D[l];return e.jsxs("div",{className:"flex flex-col gap-5 w-full md:w-72 shrink-0 overflow-y-auto max-h-full pr-1",children:[e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Algorithm"}),e.jsx("div",{className:"grid grid-cols-2 gap-2",children:ye.map(c=>e.jsx("button",{onClick:()=>!T&&n(c),disabled:T,className:` + rounded-lg px-3 py-2 text-sm font-medium transition-all duration-200 + ${l===c?"bg-indigo-500/20 text-indigo-300 ring-1 ring-indigo-500/40 shadow-lg shadow-indigo-500/10":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50 hover:text-slate-300"} + disabled:opacity-50 disabled:cursor-not-allowed + `,children:D[c].name.split(" ").length>2?D[c].name.split(" ").slice(0,-1).join(" "):D[c].name},c))}),e.jsxs("div",{className:"mt-3 rounded-lg bg-slate-800/40 p-3",children:[e.jsx("p",{className:"text-xs text-slate-400 leading-relaxed",children:d.description}),e.jsxs("div",{className:"mt-2 flex gap-2",children:[d.guaranteesShortestPath&&e.jsx("span",{className:"inline-flex items-center rounded-full bg-emerald-500/10 px-2 py-0.5 text-[10px] font-medium text-emerald-400 ring-1 ring-emerald-500/20",children:"Shortest Path"}),d.weighted&&e.jsx("span",{className:"inline-flex items-center rounded-full bg-amber-500/10 px-2 py-0.5 text-[10px] font-medium text-amber-400 ring-1 ring-amber-500/20",children:"Weighted"})]})]})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400",children:"Speed"}),e.jsxs("button",{onClick:()=>o(!s),className:` + flex items-center gap-1.5 rounded-lg px-2 py-1 text-xs font-medium transition-all duration-200 + ${s?"bg-emerald-500/15 text-emerald-400 ring-1 ring-emerald-500/30":"bg-slate-800/50 text-slate-500 hover:text-slate-400"} + `,title:s?"Mute sound":"Unmute sound",children:[s?e.jsx(se,{size:12}):e.jsx(ae,{size:12}),s?"Sound On":"Sound Off"]})]}),e.jsx("div",{className:"flex gap-1",children:Te.map(c=>e.jsx("button",{onClick:()=>x(c),className:` + flex-1 rounded-lg px-2 py-1.5 text-xs font-medium capitalize transition-all duration-200 + ${y===c?"bg-violet-500/20 text-violet-300 ring-1 ring-violet-500/40":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50 hover:text-slate-300"} + `,children:c},c))})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Tools"}),e.jsx("div",{className:"grid grid-cols-2 gap-2",children:we.map(({mode:c,label:p,icon:v})=>e.jsxs("button",{onClick:()=>b(c),disabled:T,className:` + flex items-center gap-2 rounded-lg px-3 py-2 text-sm font-medium transition-all duration-200 + ${g===c?"bg-cyan-500/20 text-cyan-300 ring-1 ring-cyan-500/40":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50 hover:text-slate-300"} + disabled:opacity-50 disabled:cursor-not-allowed + `,children:[e.jsx(v,{size:14}),p]},c))})]}),e.jsxs("div",{className:"flex flex-col gap-2",children:[T?e.jsxs("button",{onClick:w,className:"flex items-center justify-center gap-2 rounded-xl bg-gradient-to-r from-rose-500 to-pink-500 px-4 py-3 text-sm font-semibold text-white shadow-lg shadow-rose-500/25 transition-all duration-200 hover:brightness-110 active:scale-[0.98]",children:[e.jsx(ne,{size:16}),"Stop"]}):e.jsxs("button",{onClick:i,className:"flex items-center justify-center gap-2 rounded-xl bg-gradient-to-r from-indigo-500 to-violet-500 px-4 py-3 text-sm font-semibold text-white shadow-lg shadow-indigo-500/25 transition-all duration-200 hover:shadow-xl hover:shadow-indigo-500/30 hover:brightness-110 active:scale-[0.98]",children:[e.jsx(Z,{size:16}),"Visualize ",d.name]}),e.jsxs("div",{className:"grid grid-cols-3 gap-2",children:[e.jsxs("button",{onClick:N,disabled:T,className:"flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300 disabled:opacity-50 disabled:cursor-not-allowed",children:[e.jsx(oe,{size:12}),"Clear"]}),e.jsxs("button",{onClick:h,disabled:T,className:"flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300 disabled:opacity-50 disabled:cursor-not-allowed",children:[e.jsx(re,{size:12}),"Reset"]}),e.jsxs("button",{onClick:f,disabled:T,className:"flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300 disabled:opacity-50 disabled:cursor-not-allowed",children:[e.jsx(le,{size:12}),"Maze"]})]})]}),(T||m)&&e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Statistics"}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-xs text-slate-500",children:"Nodes Visited"}),e.jsx("span",{className:"text-sm font-mono font-semibold text-indigo-400",children:t})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-xs text-slate-500",children:"Path Length"}),e.jsx("span",{className:"text-sm font-mono font-semibold text-amber-400",children:u>0?u:m?"No path":"—"})]})]})]})]})}const Ne=[{label:"Start",color:"bg-emerald-500"},{label:"End",color:"bg-rose-500"},{label:"Wall",color:"bg-slate-300"},{label:"Visited",color:"bg-indigo-500/70"},{label:"Path",color:"bg-amber-400"},{label:"Empty",color:"bg-slate-900/40 ring-1 ring-slate-700"}];function ve(){return e.jsx("div",{className:"flex items-center justify-center gap-6 py-3",children:Ne.map(({label:l,color:n})=>e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:`h-4 w-4 rounded-sm ${n}`}),e.jsx("span",{className:"text-xs text-slate-400",children:l})]},l))})}const I=25,O=50,M={row:12,col:10},z={row:12,col:39};function Se(l,n){return{row:l,col:n,type:a.EMPTY,distance:1/0,heuristic:0,totalCost:1/0,parent:null,isVisited:!1}}function $(l,n,y,x){const g=[];for(let b=0;b$(I,O,M,z)),[y,x]=r.useState(M),[g,b]=r.useState(z),[T,m]=r.useState(!1),[t,u]=r.useState("wall"),i=r.useCallback(()=>{n($(I,O,M,z)),x(M),b(z)},[]),w=r.useCallback(()=>{n(s=>s.map(o=>o.map(d=>({...d,type:d.type===a.VISITED||d.type===a.PATH||d.type===a.EXPLORING?a.EMPTY:d.type,isVisited:!1,distance:1/0,heuristic:0,totalCost:1/0,parent:null}))))},[]),h=r.useCallback((s,o)=>{n(d=>{const c=d.map(v=>v.map(S=>({...S}))),p=c[s][o];return t==="start"?p.type===a.END?d:(c[y.row][y.col].type=a.EMPTY,p.type=a.START,x({row:s,col:o}),c):t==="end"?p.type===a.START?d:(c[g.row][g.col].type=a.EMPTY,p.type=a.END,b({row:s,col:o}),c):p.type===a.START||p.type===a.END?d:(t==="wall"?p.type=a.WALL:t==="eraser"&&(p.type=a.EMPTY),c)})},[t,y,g]),N=r.useCallback((s,o,d)=>{n(c=>{const p=c.map(v=>v.map(S=>({...S})));return p[s][o].type=d,p})},[]),f=r.useCallback(()=>{const s=$(I,O,M,z);for(let o=0;oie(),[]),y=r.useCallback((m,t,u,i,w)=>{if(!l.current||w==="instant")return;const h=n();if(!h)return;const N=F[w],f=H[w],s=(m*i+t)/(u*i),o=Math.floor(s*(q.length-1)),d=q[Math.min(o,q.length-1)],c=h.createOscillator(),p=h.createGain();c.type="sine",c.frequency.setValueAtTime(d,h.currentTime),p.gain.setValueAtTime(f,h.currentTime),p.gain.exponentialRampToValueAtTime(.001,h.currentTime+N),c.connect(p),p.connect(h.destination),c.start(h.currentTime),c.stop(h.currentTime+N)},[n]),x=r.useCallback((m,t,u)=>{if(!l.current||u==="instant")return;const i=n();if(!i)return;const w=F[u]*3,h=H[u]*1.5,f=440+m/Math.max(t-1,1)*440,s=i.createOscillator(),o=i.createGain();s.type="triangle",s.frequency.setValueAtTime(f,i.currentTime),o.gain.setValueAtTime(h,i.currentTime),o.gain.exponentialRampToValueAtTime(.001,i.currentTime+w),s.connect(o),o.connect(i.destination),s.start(i.currentTime),s.stop(i.currentTime+w)},[n]),g=r.useCallback(m=>{if(!l.current)return;const t=n();if(!t)return;const u=t.createOscillator(),i=t.createGain();u.type="sine",i.gain.setValueAtTime(.1,t.currentTime),m?(u.frequency.setValueAtTime(523.25,t.currentTime),u.frequency.setValueAtTime(659.25,t.currentTime+.15),u.frequency.setValueAtTime(783.99,t.currentTime+.3),i.gain.exponentialRampToValueAtTime(.001,t.currentTime+.5),u.connect(i),i.connect(t.destination),u.start(t.currentTime),u.stop(t.currentTime+.5)):(u.frequency.setValueAtTime(392,t.currentTime),u.frequency.setValueAtTime(293.66,t.currentTime+.2),i.gain.exponentialRampToValueAtTime(.001,t.currentTime+.4),u.connect(i),i.connect(t.destination),u.start(t.currentTime),u.stop(t.currentTime+.4))},[n]),b=r.useCallback(m=>{l.current=m},[]),T=r.useCallback(()=>l.current,[]);return{playVisitedTone:y,playPathTone:x,playCompleteTone:g,setEnabled:b,isEnabled:T}}function Ae({grid:l,startPos:n,endPos:y,setNodeType:x,clearVisualization:g}){const[b,T]=r.useState("bfs"),[m,t]=r.useState("fast"),[u,i]=r.useState(!1),[w,h]=r.useState(!1),[N,f]=r.useState(0),[s,o]=r.useState(0),[d,c]=r.useState(!0),p=r.useRef([]),{playVisitedTone:v,playPathTone:S,playCompleteTone:A,setEnabled:R}=ke(),U=r.useCallback(C=>{c(C),R(C)},[R]),G=r.useCallback(()=>{p.current.forEach(C=>clearTimeout(C)),p.current=[],i(!1)},[]),Y=r.useCallback(()=>{G(),g(),h(!1),f(0),o(0);const C=ee(b,l,n,y),{visitedNodesInOrder:V,shortestPath:E}=C,_=te[m],X=l.length,B=l[0].length;if(i(!0),_===0){for(const j of V)j.type!==a.START&&j.type!==a.END&&x(j.row,j.col,a.VISITED);for(const j of E)j.type!==a.START&&j.type!==a.END&&x(j.row,j.col,a.PATH);f(V.length),o(E.length),i(!1),h(!0),A(E.length>0);return}for(let j=0;j{const P=V[j];if(P.type!==a.START&&P.type!==a.END&&x(P.row,P.col,a.VISITED),v(P.row,P.col,X,B,m),f(j+1),j===V.length-1){for(let k=0;k{const L=E[k];L.type!==a.START&&L.type!==a.END&&x(L.row,L.col,a.PATH),S(k,E.length,m),o(k+1),k===E.length-1&&(i(!1),h(!0),A(!0))},_*3*k);p.current.push(K)}E.length===0&&(i(!1),h(!0),A(!1))}},_*j);p.current.push(J)}V.length===0&&(i(!1),h(!0))},[b,l,n,y,m,x,g,G,v,S,A]);return{algorithm:b,setAlgorithm:T,speed:m,setSpeed:t,isRunning:u,isFinished:w,visitedCount:N,pathLength:s,soundEnabled:d,toggleSound:U,visualize:Y,stopVisualization:G}}function Ie(){const{grid:l,startPos:n,endPos:y,isDrawing:x,drawMode:g,setDrawMode:b,setIsDrawing:T,resetGrid:m,clearVisualization:t,handleNodeInteraction:u,setNodeType:i,generateMaze:w}=Ee(),{algorithm:h,setAlgorithm:N,speed:f,setSpeed:s,isRunning:o,isFinished:d,visitedCount:c,pathLength:p,soundEnabled:v,toggleSound:S,visualize:A,stopVisualization:R}=Ae({grid:l,startPos:n,endPos:y,setNodeType:i,clearVisualization:t});return e.jsxs("div",{className:"flex flex-1 flex-col md:flex-row gap-4 md:gap-6 overflow-auto p-4 md:p-6",children:[e.jsxs("div",{className:"order-last md:order-first flex md:flex-1 flex-col items-center justify-center gap-3 min-h-[40vh] md:min-h-0 max-h-[50vh] md:max-h-none overflow-auto",children:[e.jsx(be,{grid:l,isRunning:o,isDrawing:x,drawMode:g,setIsDrawing:T,handleNodeInteraction:u}),e.jsx(ve,{})]}),e.jsx(je,{algorithm:h,setAlgorithm:N,speed:f,setSpeed:s,drawMode:g,setDrawMode:b,isRunning:o,isFinished:d,visitedCount:c,pathLength:p,onVisualize:A,onStop:R,onReset:m,onClearVisualization:t,onGenerateMaze:w,soundEnabled:v,onToggleSound:S})]})}export{Ie as default}; diff --git a/docs/assets/LinkedListAlgoPage-wdM2t0_B.js b/docs/assets/LinkedListAlgoPage-wdM2t0_B.js new file mode 100644 index 0000000..be1e727 --- /dev/null +++ b/docs/assets/LinkedListAlgoPage-wdM2t0_B.js @@ -0,0 +1 @@ +import{r as j,j as s,L as Q}from"./index-BfWfBQOp.js";import{P as Z}from"./linkedListAlgo-0_WYfSZm.js";import{u as ee,A as te}from"./AlgorithmCodePanel-DWTIRULe.js";import{S as ne}from"./shuffle-Ri9xSsK2.js";import{C as se,a as oe}from"./chevron-right-CNA9GG_w.js";import{P as re}from"./pause-Bg-8t1oj.js";import{P as ie}from"./play-WRQgdyAG.js";import{R as le}from"./rotate-ccw-EKzY5q_W.js";import{V as ae,a as ce}from"./volume-x-ChIHiT28.js";import{A as de}from"./arrow-left-CkNLVmJL.js";import"./audioContext-NbgqvQGz.js";let V=1;function I(u){return u.map(e=>({id:V++,value:e}))}function T(u){return u.split(",").map(e=>Number(e.trim())).filter(e=>Number.isFinite(e))}function v(u){return u.map(e=>({...e}))}function B(u,e){switch(u){case"find-middle":return pe(T(e));case"reverse-list":return ue(T(e));case"add-two-numbers":return he(e);case"reverse-k-group":return xe(e);case"palindrome":return me(T(e));case"lru-cache":return ge(e);case"segregate":return fe(T(e));case"detect-cycle":return ve(e);case"sort-list":return ye(T(e));default:return[]}}function pe(u){const e=I(u),a=[],h=e.length;if(h===0)return[{description:"List is empty — no middle.",event:"not-found",nodes:[],pointers:[],highlights:[],done:!0}];a.push({description:"Start: place both slow and fast pointers on the head node.",event:"visit",nodes:v(e),pointers:[{name:"slow",index:0,color:"green"},{name:"fast",index:0,color:"red"}],highlights:[{index:0,color:"blue"}],meta:["slow = head","fast = head"],codeLine:1});let t=0,l=0;for(;l+2<=h-1;)t+=1,l+=2,a.push({description:`Move slow → index ${t} (value ${e[t].value}), fast → index ${l} (value ${e[l].value}). slow walks 1, fast walks 2.`,event:"compare",nodes:v(e),pointers:[{name:"slow",index:t,color:"green"},{name:"fast",index:l,color:"red"}],highlights:[{index:t,color:"green"},{index:l,color:"red"}],meta:[`slow = ${t}`,`fast = ${l}`],codeLine:4});return l+1===h-1&&(t+=1,l+=1,a.push({description:`fast has one node left → take a final step: slow → ${t} (${e[t].value}), fast → ${l} (${e[l].value}).`,event:"compare",nodes:v(e),pointers:[{name:"slow",index:t,color:"green"},{name:"fast",index:l,color:"red"}],highlights:[{index:t,color:"green"},{index:l,color:"red"}],meta:[`slow = ${t}`,`fast = ${l}`],codeLine:5})),a.push({description:`fast reached the end, so slow stops at the middle: index ${t}, value ${e[t].value}.`,event:"found",nodes:v(e),pointers:[{name:"middle",index:t,color:"green"}],highlights:[{index:t,color:"green"}],meta:[`middle index = ${t}`,`middle value = ${e[t].value}`],codeLine:6,done:!0}),a}function ue(u){const e=I(u),a=e.length;if(a===0)return[{description:"List is empty — nothing to reverse.",event:"complete",nodes:[],pointers:[],highlights:[],done:!0}];if(a===1)return[{description:"Single node — reversing leaves it unchanged.",event:"complete",nodes:v(e),pointers:[{name:"head",index:0,color:"green"}],highlights:[{index:0,color:"green"}],codeLine:8,done:!0}];const h=[];h.push({description:"Start: prev = null, curr = head. We walk the list once, flipping each next pointer to point backwards.",event:"visit",nodes:v(e),pointers:[{name:"curr",index:0,color:"yellow"}],highlights:[{index:0,color:"blue"}],meta:["prev = null","curr = head"],codeLine:1});const t=[];for(let n=0;no.value).join(", ")}]`],codeLine:5}),t.push(c);const m=[...t].reverse().concat(e.slice(n+1));h.push({description:`Advance: prev = ${c.value}, curr = ${n+1o.value).join(", ")}].`,event:"visit",nodes:v(m),pointers:[{name:"prev",index:0,color:"green"},...n+1o.value).join(", ")}]`],codeLine:7})}const l=[...t].reverse();return h.push({description:`curr is null → done. prev is the new head. Reversed list: [${l.map(n=>n.value).join(", ")}]. ✓`,event:"complete",nodes:v(l),pointers:[{name:"head",index:0,color:"green"}],highlights:l.map((n,c)=>({index:c,color:"green"})),codeLine:8,done:!0}),h}function he(u){const[e="0",a="0"]=u.split(";"),h=Math.abs(Math.trunc(Number(e.trim())||0)),t=Math.abs(Math.trunc(Number(a.trim())||0)),l=g=>String(g).split("").map(Number).reverse(),n=l(h),c=l(t),p=[],r=[],m=`A = ${n.join("→")} (=${h})`,o=`B = ${c.join("→")} (=${t})`;p.push({description:`Add ${h} + ${t}. Digits are stored least-significant-first, so we add node by node from the front, carrying overflow.`,event:"visit",nodes:[],pointers:[],highlights:[],meta:[m,o,"carry = 0"],codeLine:2});let i=0;const d=Math.max(n.length,c.length);for(let g=0;g0;g+=1){const y=n[g]??0,b=c[g]??0,f=y+b+i,$=f%10;i=Math.floor(f/10),r.push({id:V++,value:$}),p.push({description:`Position ${g}: ${y} + ${b} + carry ${f-y-b} = ${f} → write digit ${$}, carry ${i}.`,event:i>0?"compare":"push",nodes:v(r),pointers:[{name:"tail",index:r.length-1,color:"green"}],highlights:[{index:r.length-1,color:i>0?"yellow":"green"}],meta:[m,o,`sum = ${f}`,`carry = ${i}`],codeLine:i>0?7:8})}const x=h+t;return p.push({description:`Done. Result list (least-significant-first): [${r.map(g=>g.value).join(", ")}] = ${x}. ✓`,event:"complete",nodes:v(r),pointers:[{name:"head",index:0,color:"green"}],highlights:r.map((g,y)=>({index:y,color:"green"})),meta:[m,o,`${h} + ${t} = ${x}`],codeLine:10,done:!0}),p}function xe(u){const[e="",a="2"]=u.split(";"),h=T(e),t=I(h),l=t.length,n=Math.max(1,Math.trunc(Number(a.trim())||2));if(l===0)return[{description:"List is empty — nothing to reverse.",event:"complete",nodes:[],pointers:[],highlights:[],done:!0}];const c=[],p=t.slice();c.push({description:`Reverse the list in groups of k = ${n}. Each full block of ${n} nodes is reversed; a trailing group with fewer than ${n} nodes is left untouched.`,event:"visit",nodes:v(p),pointers:[],highlights:p.map((o,i)=>({index:i,color:"blue"})),meta:[`k = ${n}`,`length = ${l}`],codeLine:0});let r=0,m=0;for(;r+n<=l;){m+=1,c.push({description:`Group ${m}: indices ${r}…${r+n-1} form a full block of ${n} — reverse it in place.`,event:"recurse",nodes:v(p),pointers:[{name:"start",index:r,color:"green"},{name:"kth",index:r+n-1,color:"red"}],highlights:K(r,r+n).map(d=>({index:d,color:"yellow"})),meta:[`group ${m}`],codeLine:4});let o=r,i=r+n-1;for(;od.value).join(", ")}].`,event:"visit",nodes:v(p),pointers:[],highlights:K(r,r+n).map(d=>({index:d,color:"purple"})),codeLine:13}),r+=n}return r({index:o,color:"blue"})),codeLine:5}),c.push({description:`Done. Result: [${p.map(o=>o.value).join(", ")}]. ✓`,event:"complete",nodes:v(p),pointers:[{name:"head",index:0,color:"green"}],highlights:p.map((o,i)=>({index:i,color:"green"})),codeLine:14,done:!0}),c}function me(u){const e=I(u),a=[],h=e.length;if(h===0)return[{description:"Empty list is trivially a palindrome.",event:"found",nodes:[],pointers:[],highlights:[],done:!0}];a.push({description:"Phase 1 — find the middle with slow (1×) and fast (2×) pointers.",event:"visit",nodes:v(e),pointers:[{name:"slow",index:0,color:"green"},{name:"fast",index:0,color:"red"}],highlights:[{index:0,color:"blue"}],codeLine:2});let t=0,l=0;for(;l+2<=h-1;)t+=1,l+=2,a.push({description:`Advance: slow → ${t} (${e[t].value}), fast → ${l} (${e[l].value}).`,event:"compare",nodes:v(e),pointers:[{name:"slow",index:t,color:"green"},{name:"fast",index:l,color:"red"}],highlights:[{index:t,color:"green"},{index:l,color:"red"}],codeLine:4});const n=(h%2===0,t+1);a.push({description:`Middle found at index ${t}. The second half (indices ${n}…${h-1}) will be reversed.`,event:"visit",nodes:v(e),pointers:[{name:"mid",index:t,color:"yellow"}],highlights:Array.from({length:h-n},(x,g)=>({index:n+g,color:"purple"})),meta:["Phase 2 — reverse 2nd half"],codeLine:6});const c=e.slice(0,n),p=e.slice(n).reverse(),r=[...c,...p];a.push({description:"Second half reversed. Now compare the front half and the reversed back half moving inward.",event:"swap",nodes:v(r),pointers:[{name:"left",index:0,color:"green"},{name:"right",index:h-1,color:"red"}],highlights:Array.from({length:p.length},(x,g)=>({index:c.length+g,color:"purple"})),codeLine:8});let m=0,o=n,i=!0;const d=p.length;for(let x=0;x({index:g,color:i?"green":"red"})),meta:[i?"palindrome = true":"palindrome = false"],codeLine:i?12:10,done:!0}),a}function ge(u){const[e,a=""]=u.split(";"),h=Math.max(1,Number(e.trim())||1),t=a.split(",").map(p=>p.trim()).filter(Boolean),l=[];let n=[];const c=(p,r,m={},o,i=!1)=>{l.push({description:p,event:r,nodes:[],pointers:[],highlights:[],lru:{capacity:h,entries:n.map(d=>({...d})),op:m?.op,hitKey:m?.hitKey??null,missKey:m?.missKey??null,evictKey:m?.evictKey??null},meta:[`capacity = ${h}`,`size = ${n.length}`],codeLine:o,done:i})};c(`Create an LRU cache with capacity ${h}. The front is most-recently-used, the back is least-recently-used.`,"visit",{op:"init"},0);for(const p of t){const r=p.split(/\s+/),m=r[0]?.toLowerCase();if(m==="put"){const o=Number(r[1]),i=Number(r[2]),d=n.findIndex(x=>x.key===o);if(d>=0){const[x]=n.splice(d,1);x.value=i,n.unshift(x),c(`put(${o}, ${i}): key ${o} already exists → update value and move to front (most-recently-used).`,"swap",{op:`put ${o} ${i}`,hitKey:o},11)}else{if(n.length>=h){const x=n[n.length-1];c(`put(${o}, ${i}): cache is full → evict least-recently-used key ${x.key}.`,"pop",{op:`put ${o} ${i}`,evictKey:x.key},13),n=n.slice(0,n.length-1)}n.unshift({key:o,value:i}),c(`put(${o}, ${i}): insert new entry at the front.`,"push",{op:`put ${o} ${i}`,hitKey:o},14)}}else if(m==="get"){const o=Number(r[1]),i=n.findIndex(d=>d.key===o);if(i>=0){const[d]=n.splice(i,1);n.unshift(d),c(`get(${o}) → ${d.value} (HIT). Move key ${o} to the front.`,"found",{op:`get ${o}`,hitKey:o},6)}else c(`get(${o}) → -1 (MISS). Key ${o} is not in the cache.`,"not-found",{op:`get ${o}`,missKey:o},5)}}return c("All operations processed.","complete",{op:"done"},0,!0),l}function fe(u){const e=I(u),a=[],h=e.length;if(h===0)return[{description:"List is empty — nothing to segregate.",event:"complete",nodes:[],pointers:[],highlights:[],done:!0}];a.push({description:"Goal: move all even-valued nodes before all odd-valued nodes, preserving relative order. Scan from the head.",event:"visit",nodes:v(e),pointers:[{name:"curr",index:0,color:"yellow"}],highlights:[{index:0,color:"blue"}],meta:["evens = [ ]","odds = [ ]"],codeLine:3});const t=[],l=[];for(let c=0;cm.value).join(", ")}]`,`odds = [${l.map(m=>m.value).join(", ")}]`],codeLine:r?5:6})}const n=[...t,...l];return a.push({description:`Join the chains: evens (${t.length}) followed by odds (${l.length}).`,event:"swap",nodes:v(n),pointers:[],highlights:n.map((c,p)=>({index:p,color:c.value%2===0?"green":"red"})),meta:[`evens = [${t.map(c=>c.value).join(", ")}]`,`odds = [${l.map(c=>c.value).join(", ")}]`],codeLine:8,done:!0}),a}function ve(u){const[e,a="-1"]=u.split(";"),h=T(e),t=I(h),l=t.length,n=Math.trunc(Number(a.trim())),c=n>=0&&n0,p=c?n:null,r=[];if(l===0)return[{description:"List is empty — no cycle.",event:"not-found",nodes:[],pointers:[],highlights:[],cycleTo:null,done:!0}];const m=L=>L===l-1?c?n:-1:L+1;r.push({description:c?`Tail (index ${l-1}) links back to index ${n}. Run Floyd's tortoise & hare from the head.`:"No cycle declared (tail → null). Run Floyd's tortoise & hare to confirm.",event:"visit",nodes:v(t),pointers:[{name:"slow",index:0,color:"green"},{name:"fast",index:0,color:"red"}],highlights:[{index:0,color:"blue"}],cycleTo:p,meta:["Phase 1 — detect"],codeLine:2});let o=0,i=0,d=-1,x=0;const g=l*4+10;for(;x=0?[{name:"slow",index:o,color:"green"}]:[],highlights:[],cycleTo:p,meta:["cycle = false"],codeLine:6,done:!0}),r;if(r.push({description:`slow → ${o} (${t[o].value}), fast → ${i} (${t[i].value}). ${o===i?"They MET — a cycle exists!":"Not equal yet, keep moving."}`,event:o===i?"found":"compare",nodes:v(t),pointers:[{name:"slow",index:o,color:"green"},{name:"fast",index:i,color:"red"}],highlights:o===i?[{index:o,color:"yellow"}]:[{index:o,color:"green"},{index:i,color:"red"}],cycleTo:p,codeLine:o===i?5:4}),o===i){d=o;break}}if(d===-1)return r.push({description:"No cycle detected.",event:"not-found",nodes:v(t),pointers:[],highlights:[],cycleTo:p,codeLine:6,done:!0}),r;let y=1,b=m(d);for(;b!==d;)y+=1,b=m(b);r.push({description:`Phase 2 — measure loop length: walk from the meeting node until returning to it → length = ${y}.`,event:"visit",nodes:v(t),pointers:[{name:"meet",index:d,color:"yellow"}],highlights:be(d,m).map(L=>({index:L,color:"purple"})),cycleTo:p,meta:[`loop length = ${y}`],codeLine:8});let f=0,$=d;for(r.push({description:"Phase 3 — find loop start: reset one pointer to head; advance both one step at a time. They meet at the loop entry.",event:"visit",nodes:v(t),pointers:[{name:"p1",index:f,color:"green"},{name:"p2",index:$,color:"red"}],highlights:[{index:f,color:"green"},{index:$,color:"red"}],cycleTo:p,codeLine:10});f!==$;)f=m(f),$=m($),r.push({description:`p1 → ${f} (${t[f].value}), p2 → ${$} (${t[$].value}). ${f===$?"Met at the loop start!":"Advance both by one."}`,event:f===$?"found":"compare",nodes:v(t),pointers:[{name:"p1",index:f,color:"green"},{name:"p2",index:$,color:"red"}],highlights:f===$?[{index:f,color:"yellow"}]:[{index:f,color:"green"},{index:$,color:"red"}],cycleTo:p,codeLine:11});const C=f;return r.push({description:`Phase 4 — remove the loop: the node before the loop start (the tail, index ${l-1}) has its next set to null.`,event:"swap",nodes:v(t),pointers:[{name:"start",index:C,color:"yellow"},{name:"tail",index:l-1,color:"red"}],highlights:[{index:C,color:"yellow"},{index:l-1,color:"red"}],cycleTo:p,meta:[`loop start = index ${C}`,`loop length = ${y}`],codeLine:13}),r.push({description:"Loop removed — the list is now a clean acyclic chain ending in null. ✓",event:"complete",nodes:v(t),pointers:[],highlights:t.map((L,w)=>({index:w,color:"green"})),cycleTo:null,meta:["cycle = false",`removed link tail → ${n}`],codeLine:13,done:!0}),r}function be(u,e){const a=[u];let h=e(u);for(;h!==u;)a.push(h),h=e(h);return a}function ye(u){const e=I(u),a=[],h=e.length;if(h<=1)return[{description:h===0?"Empty list — already sorted.":"Single node — already sorted.",event:"complete",nodes:v(e),pointers:[],highlights:e.map((n,c)=>({index:c,color:"green"})),codeLine:2,done:!0}];a.push({description:"Merge sort: recursively split the list into halves until single nodes remain, then merge sorted runs.",event:"visit",nodes:v(e),pointers:[],highlights:e.map((n,c)=>({index:c,color:"blue"})),meta:["Time O(n log n)"],codeLine:0});const t=e.slice(),l=(n,c)=>{if(c-n<=1)return;const p=n+c>>1;a.push({description:`Split indices ${n}…${c-1} into [${n}…${p-1}] and [${p}…${c-1}].`,event:"recurse",nodes:v(t),pointers:[{name:"mid",index:p,color:"yellow"}],highlights:[...K(n,p).map(x=>({index:x,color:"green"})),...K(p,c).map(x=>({index:x,color:"red"}))],codeLine:3}),l(n,p),l(p,c);const r=t.slice(n,p),m=t.slice(p,c),o=[];let i=0,d=0;for(;ix.value).join(", ")}] sorted into indices ${n}…${c-1}.`,event:"swap",nodes:v(t),pointers:[],highlights:K(n,c).map(x=>({index:x,color:"purple"})),codeLine:6})};return l(0,h),a.push({description:`Done — list sorted: [${t.map(n=>n.value).join(", ")}]. ✓`,event:"complete",nodes:v(t),pointers:[],highlights:t.map((n,c)=>({index:c,color:"green"})),codeLine:6,done:!0}),a}function K(u,e){const a=[];for(let h=u;hB(u,e.defaultInput)),[n,c]=j.useState(0),[p,r]=j.useState(!1),[m,o]=j.useState(700),i=j.useRef(m),d=j.useRef(null),x=j.useRef(t),{soundEnabled:g,toggleSound:y,playEvent:b}=ee(),f=j.useRef(b);j.useEffect(()=>{i.current=m},[m]),j.useEffect(()=>{x.current=t},[t]),j.useEffect(()=>{f.current=b},[b]);const $=j.useCallback(()=>{d.current&&(clearTimeout(d.current),d.current=null)},[]);j.useEffect(()=>()=>$(),[$]);const C=t[n]??t[0]??null,L=t.length>0?(n+1)/t.length*100:0,w=j.useCallback(()=>{r(!1),$()},[$]),P=j.useCallback((N,S=!0)=>{const A=x.current,O=Math.max(0,Math.min(A.length-1,N));if(c(O),S){const F=A[O];F&&f.current(F.event,O,A.length)}},[]),W=j.useCallback(()=>{const N=x.current;if(N.length===0)return;let S=n>=N.length-1?0:n;c(S),r(!0);const A=()=>{if(S>=N.length-1){r(!1),$();return}S+=1,c(S);const F=N[S];F&&f.current(F.event,S,N.length),d.current=setTimeout(A,i.current)},O=N[S];O&&f.current(O.event,S,N.length),d.current=setTimeout(A,i.current)},[n,$]),U=j.useCallback(()=>{p?w():W()},[p,W,w]),H=j.useCallback(()=>{w(),P(n+1)},[w,P,n]),X=j.useCallback(()=>{w(),P(n-1)},[w,P,n]),q=j.useCallback(()=>{w(),P(0,!1)},[w,P]),Y=j.useCallback(N=>{w();const A=B(u,N??a);l(A),x.current=A,c(0),A[0]&&f.current(A[0].event,0,A.length)},[a,u,w]),J=j.useMemo(()=>t.reduce((N,S)=>Math.max(N,S.nodes.length),0),[t]);return{info:e,input:a,setInput:h,steps:t,stepIndex:n,currentStep:C,progress:L,isPlaying:p,speed:m,setSpeed:o,soundEnabled:g,toggleSound:y,maxNodes:J,run:Y,togglePlay:U,next:H,prev:X,reset:q,goToStep:N=>{w(),P(N)},canGoNext:n0}}const we={green:{border:"#34d399",bg:"rgba(52,211,153,0.18)",text:"#6ee7b7"},red:{border:"#f87171",bg:"rgba(248,113,113,0.18)",text:"#fca5a5"},yellow:{border:"#fbbf24",bg:"rgba(251,191,36,0.18)",text:"#fde68a"},blue:{border:"#60a5fa",bg:"rgba(96,165,250,0.18)",text:"#93c5fd"},purple:{border:"#c084fc",bg:"rgba(192,132,252,0.18)",text:"#d8b4fe"}},je={border:"#475569",bg:"rgba(30,41,59,0.7)",text:"#cbd5e1"},ke={green:"#34d399",red:"#f87171",yellow:"#fbbf24",blue:"#60a5fa",purple:"#c084fc"},R=60,k=48,D=40,_=R+D,z=6,G=k+78;function Ne({step:u}){return u?u.lru?s.jsx(Se,{step:u}):s.jsx(Le,{step:u}):null}function Le({step:u}){const{nodes:e,pointers:a,highlights:h,cycleTo:t}=u,l=new Map(h.map(d=>[d.index,d.color])),n=new Map;for(const d of a){const x=n.get(d.index)??[];x.push(d),n.set(d.index,x)}if(e.length===0)return s.jsx("div",{className:"flex h-full min-h-[260px] w-full items-center justify-center",children:s.jsx("div",{className:"flex h-16 w-48 items-center justify-center rounded-lg border-2 border-dashed border-slate-700 text-xs text-slate-600",children:"Empty list — null"})});const c=Math.ceil(e.length/z),r=Math.min(e.length,z)*_+D,m=c*G+20,o=28,i=d=>{const x=Math.floor(d/z);return{x:d%z*_+D,y:x*G+o}};return s.jsxs("div",{className:"flex h-full w-full flex-col items-center justify-center gap-4 overflow-auto px-2",children:[s.jsxs("svg",{viewBox:`0 0 ${r+20} ${m}`,width:"100%",style:{maxWidth:`${r+20}px`,overflow:"visible"},children:[e.map((d,x)=>{const g=x===e.length-1,{x:y,y:b}=i(x),f=x%z!==z-1;if(g)return null;if(f)return s.jsxs("g",{children:[s.jsx("line",{x1:y+R,y1:b+k/2,x2:y+_,y2:b+k/2,stroke:"#475569",strokeWidth:1.6}),s.jsx("polygon",{points:`${y+_},${b+k/2} ${y+_-7},${b+k/2-4} ${y+_-7},${b+k/2+4}`,fill:"#475569"})]},`edge-${d.id}`);const $=i(x+1);return s.jsx("path",{d:`M ${y+R} ${b+k/2} L ${y+R+14} ${b+k/2} L ${y+R+14} ${b+k+28} L ${$.x-14} ${$.y+k/2} L ${$.x} ${$.y+k/2}`,fill:"none",stroke:"#475569",strokeWidth:1.6,markerEnd:""},`wrap-${d.id}`)}),t==null&&e.length>0&&(()=>{const d=e.length-1,{x,y:g}=i(d);return s.jsx("text",{x:x+R+22,y:g+k/2+4,textAnchor:"middle",fontSize:"10",fill:"#64748b",fontFamily:"monospace",children:"null"},"null")})(),t!=null&&e.length>0&&(()=>{const d=i(e.length-1),x=i(t),g=d.x+R/2,y=d.y+k,b=x.x+R/2,f=x.y+k,$=Math.max(y,f)+46;return s.jsxs("g",{children:[s.jsx("path",{d:`M ${g} ${y} C ${g} ${$}, ${b} ${$}, ${b} ${f}`,fill:"none",stroke:"#f59e0b",strokeWidth:1.8,strokeDasharray:"5 4"}),s.jsx("polygon",{points:`${b},${f} ${b-4},${f+8} ${b+4},${f+8}`,fill:"#f59e0b"}),s.jsxs("text",{x:(g+b)/2,y:$+12,textAnchor:"middle",fontSize:"9",fill:"#fbbf24",fontFamily:"monospace",children:["cycle → index ",t]})]})})(),e.map((d,x)=>{const{x:g,y}=i(x),b=l.get(x),f=b?we[b]:je,$=n.get(x)??[];return s.jsxs("g",{children:[x===0&&s.jsx("text",{x:g+R/2,y:y-16,textAnchor:"middle",fontSize:"9",fill:"#818cf8",fontFamily:"monospace",children:"head"}),$.map((C,L)=>s.jsx("g",{children:s.jsxs("text",{x:g+R/2,y:y-6-L*11,textAnchor:"middle",fontSize:"9",fontWeight:"bold",fill:ke[C.color??"blue"],fontFamily:"monospace",children:[C.name,"↓"]})},C.name)),s.jsx("rect",{x:g,y,width:R,height:k,rx:8,fill:f.bg,stroke:f.border,strokeWidth:b?2.2:1.5}),s.jsx("text",{x:g+R/2,y:y+k/2+5,textAnchor:"middle",fontSize:"15",fontWeight:"bold",fill:f.text,fontFamily:"sans-serif",children:d.value}),s.jsxs("text",{x:g+R/2,y:y+k+12,textAnchor:"middle",fontSize:"8",fill:"#475569",fontFamily:"monospace",children:["[",x,"]"]})]},d.id)})]}),u.description&&s.jsx("div",{className:"w-full max-w-xl rounded-lg bg-slate-800/60 px-4 py-2 text-center text-xs leading-relaxed text-indigo-300",children:u.description}),u.meta&&u.meta.length>0&&s.jsx("div",{className:"flex flex-wrap justify-center gap-1.5",children:u.meta.map(d=>s.jsx("span",{className:"rounded-full bg-slate-800/80 px-2.5 py-0.5 text-[10px] font-mono text-slate-300 ring-1 ring-slate-700/50",children:d},d))})]})}function Se({step:u}){const e=u.lru,a=Array.from({length:e.capacity});return s.jsxs("div",{className:"flex h-full w-full flex-col items-center justify-center gap-5 overflow-auto px-2",children:[s.jsxs("div",{className:"flex w-full max-w-2xl items-center justify-between text-[10px] uppercase tracking-wider text-slate-500",children:[s.jsx("span",{className:"text-emerald-400",children:"← Most recently used"}),s.jsx("span",{className:"text-rose-400",children:"Least recently used →"})]}),s.jsx("div",{className:"flex flex-wrap items-center justify-center gap-3",children:a.map((h,t)=>{const l=e.entries[t];if(!l)return s.jsx("div",{className:"flex h-20 w-24 flex-col items-center justify-center rounded-xl border-2 border-dashed border-slate-700 text-[10px] text-slate-600",children:"empty"},`empty-${t}`);const n=e.hitKey===l.key,p=e.evictKey===l.key?"border-rose-400 bg-rose-500/15":n?"border-emerald-400 bg-emerald-500/15":"border-slate-600 bg-slate-800/70";return s.jsxs("div",{className:`flex h-20 w-24 flex-col items-center justify-center rounded-xl border-2 ${p} transition-all`,children:[s.jsxs("span",{className:"text-[9px] font-mono uppercase tracking-wide text-slate-400",children:["key ",l.key]}),s.jsx("span",{className:"mt-0.5 text-xl font-bold text-white",children:l.value}),t===0&&s.jsx("span",{className:"mt-0.5 text-[8px] font-mono text-emerald-400",children:"MRU"}),t===e.entries.length-1&&e.entries.length===e.capacity&&t!==0&&s.jsx("span",{className:"mt-0.5 text-[8px] font-mono text-rose-400",children:"LRU"})]},l.key)})}),e.missKey!=null&&s.jsxs("div",{className:"rounded-lg bg-rose-500/10 px-3 py-1 text-xs font-mono text-rose-300 ring-1 ring-rose-500/30",children:["MISS · key ",e.missKey," not present"]}),u.description&&s.jsx("div",{className:"w-full max-w-xl rounded-lg bg-slate-800/60 px-4 py-2 text-center text-xs leading-relaxed text-indigo-300",children:u.description}),u.meta&&u.meta.length>0&&s.jsx("div",{className:"flex flex-wrap justify-center gap-1.5",children:u.meta.map(h=>s.jsx("span",{className:"rounded-full bg-slate-800/80 px-2.5 py-0.5 text-[10px] font-mono text-slate-300 ring-1 ring-slate-700/50",children:h},h))})]})}const M=(u,e)=>Math.floor(Math.random()*(e-u+1))+u;function E(u,e=1,a=99){return Array.from({length:u},()=>M(e,a))}function Re(u){switch(u){case"find-middle":return E(M(5,9)).join(",");case"palindrome":{const e=E(M(2,3));if(Math.random()<.6){const a=Math.random()<.5?[M(1,9)]:[];return[...e,...a,...[...e].reverse()].join(",")}return E(M(4,7)).join(",")}case"lru-cache":{const e=M(2,3),a=[1,2,3,4,5],h=[];for(let t=0;t{const w=Re(e);t(w),x(w)};return s.jsxs("aside",{className:"w-full space-y-4 xl:w-80 xl:shrink-0",children:[s.jsxs("section",{className:"rounded-2xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[s.jsx("h3",{className:"mb-2 text-xs font-semibold uppercase tracking-wider text-slate-400",children:"Input"}),s.jsx("label",{className:"text-[11px] text-slate-500",children:a.inputLabel}),s.jsx("textarea",{value:h,onChange:w=>t(w.target.value),rows:3,className:"mt-1 w-full resize-none rounded-xl bg-slate-950/70 px-3 py-2 text-xs font-mono text-slate-200 outline-none ring-1 ring-slate-700/50 focus:ring-indigo-500/50"}),s.jsx("p",{className:"mt-2 text-[10px] leading-relaxed text-slate-500",children:a.helper}),s.jsxs("div",{className:"mt-3 grid grid-cols-2 gap-2",children:[s.jsx("button",{onClick:()=>x(),className:"rounded-xl bg-indigo-500/20 px-3 py-2 text-xs font-semibold text-indigo-300 ring-1 ring-indigo-500/40 hover:bg-indigo-500/30",children:"Build Steps"}),s.jsxs("button",{onClick:L,className:"inline-flex items-center justify-center gap-1 rounded-xl bg-slate-800/70 px-3 py-2 text-xs font-semibold text-slate-300 ring-1 ring-slate-700/50 hover:bg-slate-700/70",children:[s.jsx(ne,{size:13})," Random"]})]})]}),s.jsxs("section",{className:"rounded-2xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[s.jsxs("div",{className:"mb-3 flex items-center justify-between",children:[s.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400",children:"Playback"}),s.jsxs("span",{className:"font-mono text-xs text-indigo-300",children:[Math.min(n+1,l.length)," / ",l.length]})]}),s.jsx("div",{className:"h-2 overflow-hidden rounded-full bg-slate-800",children:s.jsx("div",{className:"h-full rounded-full bg-indigo-400 transition-all",style:{width:`${p}%`}})}),s.jsxs("div",{className:"mt-3 rounded-xl border border-slate-700/40 bg-slate-950/40 p-3",children:[s.jsxs("div",{className:"mb-2 flex items-center justify-between",children:[s.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-wider text-slate-500",children:"Animation Speed"}),s.jsxs("span",{className:"font-mono text-[10px] text-indigo-300",children:[(m/1e3).toFixed(2),"s"]})]}),s.jsx("input",{type:"range",min:120,max:3e3,step:20,value:3120-m,onChange:w=>o(3120-Number(w.target.value)),className:"w-full accent-indigo-400","aria-label":"Animation speed"}),s.jsxs("div",{className:"mt-1 flex justify-between text-[9px] uppercase tracking-wide text-slate-600",children:[s.jsx("span",{children:"Slow"}),s.jsx("span",{children:"Fast"})]})]}),s.jsxs("div",{className:"mt-3 grid grid-cols-3 gap-2",children:[s.jsxs("button",{onClick:b,disabled:!C,className:"inline-flex items-center justify-center gap-1 rounded-xl bg-slate-800/70 px-2 py-2 text-xs text-slate-300 ring-1 ring-slate-700/50 disabled:opacity-30",children:[s.jsx(se,{size:13})," Back"]}),s.jsx("button",{onClick:g,className:`inline-flex items-center justify-center gap-1 rounded-xl px-2 py-2 text-xs font-semibold ring-1 ${r?"bg-amber-500/15 text-amber-300 ring-amber-500/30":"bg-emerald-500/15 text-emerald-300 ring-emerald-500/30"}`,children:r?s.jsxs(s.Fragment,{children:[s.jsx(re,{size:13})," Pause"]}):s.jsxs(s.Fragment,{children:[s.jsx(ie,{size:13})," Play"]})}),s.jsxs("button",{onClick:y,disabled:!$,className:"inline-flex items-center justify-center gap-1 rounded-xl bg-slate-800/70 px-2 py-2 text-xs text-slate-300 ring-1 ring-slate-700/50 disabled:opacity-30",children:["Next ",s.jsx(oe,{size:13})]})]}),s.jsxs("button",{onClick:f,className:"mt-2 inline-flex w-full items-center justify-center gap-1 rounded-xl bg-slate-800/70 px-3 py-2 text-xs text-slate-300 ring-1 ring-slate-700/50 hover:bg-slate-700/70",children:[s.jsx(le,{size:13})," Reset"]}),s.jsx("p",{className:"mt-3 min-h-10 text-xs leading-relaxed text-slate-300",children:c?.description})]}),s.jsxs("section",{className:"rounded-2xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[s.jsxs("button",{onClick:()=>d(!i),className:`inline-flex w-full items-center justify-center gap-2 rounded-xl px-3 py-2 text-xs font-semibold ring-1 ${i?"bg-indigo-500/15 text-indigo-300 ring-indigo-500/30":"bg-slate-800/70 text-slate-400 ring-slate-700/40"}`,children:[i?s.jsx(ae,{size:14}):s.jsx(ce,{size:14}),i?"Sound On":"Sound Off"]}),s.jsx("div",{className:"mt-3 flex flex-wrap gap-1.5",children:a.tags.map(w=>s.jsx("span",{className:"rounded-full bg-violet-500/10 px-2 py-0.5 text-[10px] font-medium text-violet-300 ring-1 ring-violet-500/20",children:w},w))}),s.jsx("p",{className:"mt-2 text-[10px] font-mono text-slate-500",children:a.complexity})]})]})}function De({problem:u}){const e=$e(u),{info:a}=e;return s.jsxs("div",{className:"flex flex-1 flex-col gap-4 overflow-auto p-4 md:p-6 xl:flex-row",children:[s.jsxs("main",{className:"order-last flex min-h-[520px] flex-1 flex-col gap-4 xl:order-first",children:[s.jsxs("section",{className:"rounded-2xl border border-slate-700/50 bg-slate-900/60 p-5 backdrop-blur-sm",children:[s.jsxs(Q,{to:"/algorithms/linked-list",className:"mb-3 inline-flex items-center gap-1.5 text-xs font-medium text-slate-400 transition-colors hover:text-indigo-300",children:[s.jsx(de,{size:13})," Linked List Algorithms"]}),s.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-[0.24em] text-indigo-300",children:"Linked List Algorithms"}),s.jsx("h2",{className:"mt-1 text-xl font-bold text-white",children:a.title}),s.jsx("p",{className:"mt-1 text-sm text-slate-400",children:a.subtitle})]}),s.jsx("section",{className:"flex flex-1 items-center justify-center rounded-2xl border border-slate-700/50 bg-slate-900/40 p-4 backdrop-blur-sm",children:s.jsx(Ne,{step:e.currentStep})}),s.jsx(te,{pseudocode:a.pseudocode,activeLine:e.currentStep?.codeLine??null})]}),s.jsx(Me,{hook:e,problem:u})]})}export{De as default}; diff --git a/docs/assets/LinkedListAlgorithmsPage-4LF4-86u.js b/docs/assets/LinkedListAlgorithmsPage-4LF4-86u.js new file mode 100644 index 0000000..2fd3b2d --- /dev/null +++ b/docs/assets/LinkedListAlgorithmsPage-4LF4-86u.js @@ -0,0 +1 @@ +import{c as a,j as e,L as r,N as c,G as d,a as x,S as m,b as h,A as p}from"./index-BfWfBQOp.js";import{P as g}from"./linkedListAlgo-0_WYfSZm.js";import{A as f}from"./arrow-left-CkNLVmJL.js";import{R as u}from"./rotate-ccw-EKzY5q_W.js";const k=[["path",{d:"m17 2 4 4-4 4",key:"nntrym"}],["path",{d:"M3 11v-1a4 4 0 0 1 4-4h14",key:"84bu3i"}],["path",{d:"m7 22-4-4 4-4",key:"1wqhfi"}],["path",{d:"M21 13v1a4 4 0 0 1-4 4H3",key:"1rx37r"}]],w=a("repeat",k);const y=[["circle",{cx:"6",cy:"6",r:"3",key:"1lh9wr"}],["path",{d:"M8.12 8.12 12 12",key:"1alkpv"}],["path",{d:"M20 4 8.12 15.88",key:"xgtan2"}],["circle",{cx:"6",cy:"18",r:"3",key:"fqmcym"}],["path",{d:"M14.8 14.8 20 20",key:"ptml3r"}]],b=a("scissors",y);const j=[["path",{d:"M17.971 4.285A2 2 0 0 1 21 6v12a2 2 0 0 1-3.029 1.715l-9.997-5.998a2 2 0 0 1-.003-3.432z",key:"15892j"}],["path",{d:"M3 20V4",key:"1ptbpl"}]],N=a("skip-back",j);const v=[["circle",{cx:"19",cy:"5",r:"2",key:"mhkx31"}],["circle",{cx:"5",cy:"19",r:"2",key:"v8kfzx"}],["path",{d:"M5 17A12 12 0 0 1 17 5",key:"1okkup"}]],L=a("spline",v),C={"find-middle":{gradient:"from-sky-500 to-cyan-500",shadowColor:"shadow-sky-500/20",icon:h},"reverse-list":{gradient:"from-rose-500 to-pink-500",shadowColor:"shadow-rose-500/20",icon:u},"add-two-numbers":{gradient:"from-blue-500 to-indigo-500",shadowColor:"shadow-blue-500/20",icon:m},"reverse-k-group":{gradient:"from-purple-500 to-fuchsia-500",shadowColor:"shadow-purple-500/20",icon:N},palindrome:{gradient:"from-fuchsia-500 to-pink-500",shadowColor:"shadow-fuchsia-500/20",icon:L},"lru-cache":{gradient:"from-emerald-500 to-teal-500",shadowColor:"shadow-emerald-500/20",icon:x},segregate:{gradient:"from-lime-500 to-green-500",shadowColor:"shadow-lime-500/20",icon:b},"detect-cycle":{gradient:"from-amber-500 to-orange-500",shadowColor:"shadow-amber-500/20",icon:w},"sort-list":{gradient:"from-indigo-500 to-violet-500",shadowColor:"shadow-indigo-500/20",icon:d}},R=["find-middle","reverse-list","add-two-numbers","reverse-k-group","palindrome","lru-cache","segregate","detect-cycle","sort-list"];function z(){return e.jsxs("div",{className:"flex-1 overflow-y-auto",children:[e.jsxs("section",{className:"flex flex-col items-center justify-center px-6 pt-12 pb-8 text-center",children:[e.jsxs(r,{to:"/algorithms",className:"mb-4 inline-flex items-center gap-1.5 rounded-full bg-slate-800/60 px-3 py-1.5 text-xs font-medium text-slate-400 ring-1 ring-slate-700/50 transition-colors hover:text-indigo-300",children:[e.jsx(f,{size:13})," Back to Algorithms"]}),e.jsxs("div",{className:"mb-4 inline-flex items-center gap-2 rounded-full bg-indigo-500/10 px-4 py-1.5 ring-1 ring-indigo-500/20",children:[e.jsx(c,{size:14,className:"text-indigo-400"}),e.jsx("span",{className:"text-xs font-medium text-indigo-300",children:"Linked List Algorithms"})]}),e.jsxs("h2",{className:"text-3xl font-extrabold tracking-tight text-white",children:["Linked ",e.jsx("span",{className:"bg-gradient-to-r from-indigo-400 to-fuchsia-400 bg-clip-text text-transparent",children:"List"})]}),e.jsx("p",{className:"mt-3 max-w-2xl mx-auto text-sm text-slate-400 leading-relaxed",children:"Two-pointer tricks, Floyd's cycle detection, merge sort, and an LRU cache — each with step playback, a speed slider, and audio feedback."})]}),e.jsx("section",{className:"px-6 pb-12",children:e.jsx("div",{className:"mx-auto grid max-w-6xl grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3",children:R.map(t=>{const s=g[t],{gradient:l,shadowColor:o,icon:n}=C[t];return e.jsxs(r,{to:`/algorithms/linked-list/${t}`,className:`group relative flex flex-col rounded-2xl border border-slate-700/40 bg-slate-900/50 p-6 shadow-lg backdrop-blur-sm transition-all duration-300 hover:scale-[1.01] hover:border-slate-600/60 hover:bg-slate-900/70 ${o}`,children:[e.jsx("div",{className:`mb-3 flex h-11 w-11 items-center justify-center rounded-xl bg-gradient-to-br ${l} shadow-lg ${o}`,children:e.jsx(n,{size:20,className:"text-white"})}),e.jsx("h4",{className:"text-base font-bold text-white",children:s.title}),e.jsx("p",{className:"text-[10px] text-slate-500 italic",children:s.subtitle}),e.jsx("p",{className:"mt-2 flex-1 text-xs leading-relaxed text-slate-400",children:s.helper}),e.jsx("div",{className:"mt-3 flex flex-wrap gap-1.5",children:s.tags.map(i=>e.jsx("span",{className:"rounded-full bg-slate-800/60 px-2 py-0.5 text-[10px] font-medium text-slate-400",children:i},i))}),e.jsxs("div",{className:"mt-3 flex items-center gap-1 text-xs font-medium text-indigo-400 opacity-0 transition-opacity group-hover:opacity-100",children:["Explore ",e.jsx(p,{size:12})]})]},t)})})})]})}export{z as default}; diff --git a/docs/assets/LinkedListPage-DBaHdW5c.js b/docs/assets/LinkedListPage-DBaHdW5c.js new file mode 100644 index 0000000..fd1cf9d --- /dev/null +++ b/docs/assets/LinkedListPage-DBaHdW5c.js @@ -0,0 +1 @@ +import{r as a,j as e,e as de}from"./index-BfWfBQOp.js";import{u as ce}from"./useDSSound-BMrOIkPj.js";import{P as K}from"./plus-BEk43_MF.js";import{T as xe}from"./trash-2-RJG3j28z.js";import{R as ue}from"./rotate-ccw-EKzY5q_W.js";import{S as he}from"./shuffle-Ri9xSsK2.js";import{V as ge,a as pe}from"./volume-x-ChIHiT28.js";import{C as me,a as fe}from"./chevron-right-CNA9GG_w.js";import"./audioContext-NbgqvQGz.js";let U=1;const be=[3,7,1,9].map(p=>({id:U++,value:p}));function je(){const[p,m]=a.useState(be),[c,H]=a.useState("singly"),[h,y]=a.useState([]),[x,r]=a.useState(-1),[S,M]=a.useState(""),[V,X]=a.useState(""),[G,P]=a.useState([]),[j,A]=a.useState(400),[n,C]=a.useState(!1),$=a.useRef(null),R=a.useRef(j),v=a.useRef(!1),{soundEnabled:o,toggleSound:F,playInsert:N,playDelete:I,playTraverse:k,playFound:T,playNotFound:D}=ce(),B=a.useRef(N),Y=a.useRef(I),q=a.useRef(k);a.useEffect(()=>{B.current=N},[N]),a.useEffect(()=>{Y.current=I},[I]),a.useEffect(()=>{q.current=k},[k]),a.useEffect(()=>{R.current=j},[j]),a.useEffect(()=>{if(!v.current||h.length===0)return;v.current=!1,$.current&&clearTimeout($.current),C(!0);let t=0;const s=()=>{if(t>=h.length-1){C(!1);return}t++,r(t);const i=h[t];i&&(i.highlightColor==="green"?B.current():i.highlightColor==="red"?Y.current():i.highlightColor==="yellow"&&q.current(t,h.length)),$.current=setTimeout(s,R.current)};$.current=setTimeout(s,R.current)},[h]);const J=x>=0&&h[x]?h[x].nodes:p,l=x>=0?h[x]:null,E=c==="singly"?"singly linked list":c==="doubly"?"doubly linked list":"circular linked list",O=t=>P(s=>[t,...s].slice(0,20)),Q=a.useCallback(t=>{H(t),y([]),r(-1),C(!1),P(s=>[`Switch to ${t}`,...s].slice(0,20))},[]),w=(t,s,i=[],d=null,u=null)=>({description:t,nodes:s,highlightIds:new Set(i),highlightColor:d,newNodeId:u}),Z=a.useCallback(t=>{const s={id:U++,value:t};m(i=>{const d=[s,...i],u=[w(`Prepend ${t}: creating new node at head in the ${E}...`,i,[],null,s.id),w(`${t} inserted at position 0. Updating ${c==="doubly"?"prev/next pointers":c==="circular"?"tail.next back to head":"head pointer"}.`,d,[s.id],"green",s.id)];return y(u),r(0),v.current=!0,N(),O(`Prepend ${t}`),d})},[N,c,E]),ee=a.useCallback(t=>{const s={id:U++,value:t};m(i=>{const d=[...i,s],u=[];for(let f=0;f{const i={id:U++,value:t};m(d=>{if(s<0||s>d.length)return d;const u=[...d.slice(0,s),i,...d.slice(s)],f=[];for(let W=0;W{m(s=>{if(t<0||t>=s.length)return s;const i=s[t],d=[];for(let f=0;f<=t;f++)d.push(w(`Traversing to index ${t}: at node ${s[f].value}...`,s,[s[f].id],"yellow"));d.push(w(`Deleting node ${i.value} at index ${t}: re-linking ${c==="doubly"?"prev and next pointers":c==="circular"?"cycle pointers":"next pointer"}.`,s,[i.id],"red"));const u=s.filter((f,W)=>W!==t);return d.push(w(`Node ${i.value} removed. List size: ${u.length}`,u,[],null)),y(d),r(0),v.current=!0,I(),O(`Delete [${t}] → ${i.value}`),u})},[I,c]),le=a.useCallback(t=>{m(s=>{const i=[];let d=-1;for(let u=0;u{m([]),y([]),r(-1),O("Clear list")},[]),ae=a.useCallback(()=>{const t=Math.floor(Math.random()*4)+4,s=Array.from({length:t},()=>({id:U++,value:Math.floor(Math.random()*90)+1}));m(s),y([]),r(-1),O("Random list")},[]),ie=a.useCallback(()=>{r(t=>Math.min(t+1,h.length-1))},[h.length]),re=a.useCallback(()=>{r(t=>Math.max(t-1,0))},[]),oe=a.useCallback(()=>{if(n){C(!1),$.current&&clearTimeout($.current);return}if(x>=h.length-1)return;C(!0);let t=x;const s=()=>{if(t>=h.length-1){C(!1);return}t++,r(t),$.current=setTimeout(s,j)};$.current=setTimeout(s,j)},[n,x,h.length,j]);return{nodes:p,variant:c,changeVariant:Q,displayNodes:J,steps:h,stepIndex:x,currentStep:l,inputValue:S,setInputValue:M,indexValue:V,setIndexValue:X,history:G,speed:j,setSpeed:A,isPlaying:n,prepend:Z,append:ee,insertAt:te,deleteAt:se,search:le,clear:ne,generateRandom:ae,nextStep:ie,prevStep:re,autoPlay:oe,canGoNext:x0,soundEnabled:o,toggleSound:F}}const ye={green:{border:"#34d399",bg:"rgba(52,211,153,0.15)",text:"#6ee7b7"},red:{border:"#f87171",bg:"rgba(248,113,113,0.15)",text:"#fca5a5"},yellow:{border:"#fbbf24",bg:"rgba(251,191,36,0.15)",text:"#fde68a"},blue:{border:"#60a5fa",bg:"rgba(96,165,250,0.15)",text:"#93c5fd"}},Ne={border:"#475569",bg:"rgba(30,41,59,0.7)",text:"#cbd5e1"},b=64,g=48,L=36,z=b+L,_=5;function ve({nodes:p,currentStep:m,variant:c}){const H=m?.highlightIds??new Set,h=m?.highlightColor??null,y=[];for(let j=0;j{const n=A*r+20,C=A===y.length-1,$=A*_;return e.jsx("g",{children:j.map((R,v)=>{const o=v*z+L/2,F=H.has(R.id),N=F&&h?ye[h]:Ne,I=$+v,k=I===0,T=I===p.length-1,D=v===j.length-1;return e.jsxs("g",{children:[k&&e.jsx("text",{x:o+b/2,y:n-8,textAnchor:"middle",fontSize:"10",fill:"#818cf8",fontFamily:"monospace",children:"head"}),e.jsx("rect",{x:o,y:n,width:b,height:g,rx:8,fill:N.bg,stroke:N.border,strokeWidth:F?2:1.5}),e.jsx("text",{x:o+b*.38,y:n+g/2+5,textAnchor:"middle",fontSize:"15",fontWeight:"bold",fill:N.text,fontFamily:"sans-serif",children:R.value}),e.jsx("line",{x1:o+b*.62,y1:n+4,x2:o+b*.62,y2:n+g-4,stroke:N.border,strokeWidth:1,opacity:.5}),e.jsx("text",{x:o+b*.82,y:n+g/2+4,textAnchor:"middle",fontSize:"9",fill:"#64748b",fontFamily:"monospace",children:T?c==="circular"?"↺":"null":"→"}),c==="doubly"&&e.jsx("text",{x:o+b*.2,y:n+g-7,textAnchor:"middle",fontSize:"8",fill:"#93c5fd",fontFamily:"monospace",children:k?"null":"←"}),!T&&!D&&e.jsxs("g",{children:[e.jsx("line",{x1:o+b,y1:n+g/2,x2:o+z,y2:n+g/2,stroke:"#475569",strokeWidth:1.5}),e.jsx("polygon",{points:`${o+z},${n+g/2} ${o+z-6},${n+g/2-4} ${o+z-6},${n+g/2+4}`,fill:"#475569"})]}),c==="doubly"&&!T&&!D&&e.jsxs("g",{opacity:.75,children:[e.jsx("line",{x1:o+z,y1:n+g/2+12,x2:o+b,y2:n+g/2+12,stroke:"#60a5fa",strokeWidth:1.2}),e.jsx("polygon",{points:`${o+b},${n+g/2+12} ${o+b+6},${n+g/2+8} ${o+b+6},${n+g/2+16}`,fill:"#60a5fa"})]}),D&&!C&&e.jsxs("g",{children:[e.jsx("path",{d:`M ${o+b} ${n+g/2} L ${o+b+14} ${n+g/2} L ${o+b+14} ${n+g+20} L ${L/2} ${n+g+20} L ${L/2} ${n+r}`,fill:"none",stroke:"#475569",strokeWidth:1.5}),e.jsx("polygon",{points:`${L/2},${n+r} ${L/2-4},${n+r-6} ${L/2+4},${n+r-6}`,fill:"#475569"})]})]},R.id)})},A)}),c==="circular"&&y.length>0&&p.length>1&&e.jsxs("g",{children:[e.jsx("path",{d:`M ${G+b} ${P+g/2} C ${x+40} ${S+16}, -20 ${S+16}, ${L/2+b/2} 78`,fill:"none",stroke:"#f59e0b",strokeDasharray:"5 5",strokeWidth:1.5}),e.jsx("text",{x:x/2,y:S-4,textAnchor:"middle",fontSize:"10",fill:"#fbbf24",fontFamily:"monospace",children:"tail.next → head"})]})]}),m?.description&&e.jsx("div",{className:"w-full max-w-sm rounded-lg bg-slate-800/60 px-4 py-2 text-center text-xs text-indigo-300 leading-relaxed",children:m.description}),e.jsxs("div",{className:"text-xs text-slate-500 font-mono",children:[c," list · length = ",p.length]})]})}const $e=[{label:"Slow",value:700},{label:"Med",value:350},{label:"Fast",value:120}];function ke({hook:p}){const{nodes:m,variant:c,changeVariant:H,steps:h,stepIndex:y,inputValue:x,setInputValue:r,indexValue:S,setIndexValue:M,history:V,speed:X,setSpeed:G,isPlaying:P,prepend:j,append:A,insertAt:n,deleteAt:C,search:$,clear:R,generateRandom:v,nextStep:o,prevStep:F,canGoNext:N,canGoPrev:I,soundEnabled:k,toggleSound:T}=p,D=()=>{const l=parseInt(x);isNaN(l)||(j(l),r(""))},B=()=>{const l=parseInt(x);isNaN(l)||(A(l),r(""))},Y=()=>{const l=parseInt(x),E=parseInt(S);!isNaN(l)&&!isNaN(E)&&(n(l,E),r(""))},q=()=>{const l=parseInt(S);isNaN(l)||C(l)},J=()=>{const l=parseInt(x);isNaN(l)||$(l)};return e.jsxs("div",{className:"flex flex-col gap-4 w-full md:w-72 shrink-0 overflow-y-auto max-h-full pr-1",children:[e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-sm font-bold text-indigo-300 mb-1",children:"Linked List"}),e.jsxs("p",{className:"text-xs text-slate-400 leading-relaxed",children:["A chain of ",e.jsx("strong",{className:"text-slate-300",children:"nodes"}),". Switch between singly, doubly, and circular pointer layouts while keeping the same operations."]}),e.jsx("div",{className:"mt-2 flex flex-wrap gap-1.5",children:["Prepend O(1)","Append O(n)","Insert O(n)","Delete O(n)","Search O(n)"].map(l=>e.jsx("span",{className:"rounded-full bg-violet-500/10 px-2 py-0.5 text-[10px] font-medium text-violet-400 ring-1 ring-violet-500/20",children:l},l))})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"List Type"}),e.jsx("div",{className:"grid grid-cols-3 gap-1",children:["singly","doubly","circular"].map(l=>e.jsx("button",{onClick:()=>H(l),className:`rounded-lg px-2 py-2 text-[10px] font-semibold capitalize transition-all ${c===l?"bg-indigo-500/20 text-indigo-300 ring-1 ring-indigo-500/40":"bg-slate-800/60 text-slate-400 hover:bg-slate-700/60"}`,children:l},l))}),e.jsx("p",{className:"mt-2 text-[10px] leading-relaxed text-slate-500",children:"Doubly lists show backward pointers; circular lists connect the tail back to the head."})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Operations"}),e.jsxs("div",{className:"grid grid-cols-2 gap-2 mb-3",children:[e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("label",{className:"text-[10px] text-slate-500 uppercase tracking-wider",children:"Value"}),e.jsx("input",{type:"number",value:x,onChange:l=>r(l.target.value),placeholder:"e.g. 42",className:"w-full rounded-lg bg-slate-800/60 px-3 py-2 text-sm text-slate-200 placeholder-slate-600 outline-none ring-1 ring-slate-700/50 focus:ring-indigo-500/50 transition-all"})]}),e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("label",{className:"text-[10px] text-slate-500 uppercase tracking-wider",children:"Index"}),e.jsx("input",{type:"number",value:S,onChange:l=>M(l.target.value),placeholder:"e.g. 0",min:"0",className:"w-full rounded-lg bg-slate-800/60 px-3 py-2 text-sm text-slate-200 placeholder-slate-600 outline-none ring-1 ring-slate-700/50 focus:ring-indigo-500/50 transition-all"})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsxs("button",{onClick:D,disabled:m.length>=12,className:"flex items-center justify-center gap-1.5 rounded-lg bg-gradient-to-r from-emerald-500/80 to-green-500/80 px-3 py-2 text-xs font-semibold text-white shadow-lg shadow-emerald-500/15 transition-all hover:brightness-110 active:scale-[0.98] disabled:opacity-40 disabled:cursor-not-allowed",children:[e.jsx(K,{size:13})," Prepend"]}),e.jsxs("button",{onClick:B,disabled:m.length>=12,className:"flex items-center justify-center gap-1.5 rounded-lg bg-indigo-500/20 px-3 py-2 text-xs font-semibold text-indigo-300 ring-1 ring-indigo-500/30 transition-all hover:bg-indigo-500/30 active:scale-[0.98] disabled:opacity-40 disabled:cursor-not-allowed",children:[e.jsx(K,{size:13})," Append"]}),e.jsxs("button",{onClick:Y,disabled:m.length>=12,className:"flex items-center justify-center gap-1.5 rounded-lg bg-violet-500/20 px-3 py-2 text-xs font-semibold text-violet-300 ring-1 ring-violet-500/30 transition-all hover:bg-violet-500/30 active:scale-[0.98] disabled:opacity-40 disabled:cursor-not-allowed",children:[e.jsx(K,{size:13})," Insert at"]}),e.jsxs("button",{onClick:q,disabled:m.length===0,className:"flex items-center justify-center gap-1.5 rounded-lg bg-gradient-to-r from-rose-500/80 to-pink-500/80 px-3 py-2 text-xs font-semibold text-white shadow-lg shadow-rose-500/15 transition-all hover:brightness-110 active:scale-[0.98] disabled:opacity-40 disabled:cursor-not-allowed",children:[e.jsx(xe,{size:13})," Delete at"]}),e.jsxs("button",{onClick:J,disabled:m.length===0,className:"flex items-center justify-center gap-1.5 rounded-lg bg-amber-500/20 px-3 py-2 text-xs font-semibold text-amber-300 ring-1 ring-amber-500/30 transition-all hover:bg-amber-500/30 active:scale-[0.98] disabled:opacity-40 disabled:cursor-not-allowed",children:[e.jsx(de,{size:13})," Search"]}),e.jsxs("button",{onClick:R,disabled:m.length===0,className:"flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-slate-400 transition-all hover:bg-slate-700/60 disabled:opacity-40 disabled:cursor-not-allowed",children:[e.jsx(ue,{size:13})," Clear"]})]}),e.jsxs("button",{onClick:v,className:"mt-2 w-full flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300",children:[e.jsx(he,{size:12})," Random List"]}),e.jsxs("button",{onClick:()=>T(!k),className:`mt-2 w-full flex items-center justify-center gap-1.5 rounded-lg px-3 py-2 text-xs font-medium transition-all ${k?"bg-indigo-500/15 text-indigo-300 ring-1 ring-indigo-500/30":"bg-slate-800/60 text-slate-400 hover:bg-slate-700/60"}`,children:[k?e.jsx(ge,{size:12}):e.jsx(pe,{size:12}),k?"Sound On":"Sound Off"]})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Animation Speed"}),e.jsx("div",{className:"flex gap-1",children:$e.map(l=>e.jsx("button",{onClick:()=>G(l.value),className:`flex-1 rounded-lg px-2 py-1.5 text-xs font-medium transition-all duration-200 ${X===l.value?"bg-violet-500/20 text-violet-300 ring-1 ring-violet-500/40":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50 hover:text-slate-300"}`,children:l.label},l.value))})]}),h.length>0&&e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Step Through"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("button",{onClick:F,disabled:!I||P,className:"flex-1 flex items-center justify-center gap-1 rounded-lg bg-slate-800/60 px-3 py-2.5 text-sm font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300 disabled:opacity-30 disabled:cursor-not-allowed",children:[e.jsx(me,{size:16})," Prev"]}),e.jsxs("button",{onClick:o,disabled:!N||P,className:"flex-1 flex items-center justify-center gap-1 rounded-lg bg-slate-800/60 px-3 py-2.5 text-sm font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300 disabled:opacity-30 disabled:cursor-not-allowed",children:["Next ",e.jsx(fe,{size:16})]})]}),e.jsxs("div",{className:"mt-2 flex items-center justify-between",children:[e.jsx("span",{className:"text-xs text-slate-500",children:"Step"}),e.jsxs("span",{className:"text-sm font-mono font-semibold text-indigo-400",children:[Math.max(0,y+1)," / ",h.length]})]})]}),V.length>0&&e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"History"}),e.jsx("div",{className:"max-h-36 overflow-y-auto space-y-1",children:V.map((l,E)=>e.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[e.jsx("span",{className:"font-mono text-slate-600 w-4 text-right",children:E+1}),e.jsx("span",{className:l.startsWith("Prepend")||l.startsWith("Append")||l.startsWith("Insert")?"text-emerald-400":l.startsWith("Delete")?"text-rose-400":l.startsWith("Search")?"text-amber-400":"text-slate-400",children:l})]},E))})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Legend"}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-emerald-500"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Insert / found"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-rose-500"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Delete"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-amber-400"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Traversal / search"})]})]})]})]})}function Ee(){const p=je();return e.jsxs("div",{className:"flex flex-1 flex-col md:flex-row gap-4 md:gap-6 overflow-auto p-4 md:p-6",children:[e.jsx("div",{className:"order-last md:order-first flex md:flex-1 flex-col items-center justify-center gap-3 min-h-[40vh] md:min-h-0 max-h-[55vh] md:max-h-none overflow-auto",children:e.jsx(ve,{nodes:p.displayNodes,currentStep:p.currentStep,variant:p.variant})}),e.jsx(ke,{hook:p})]})}export{Ee as default}; diff --git a/docs/assets/MahjongGamePage-CcjiTEak.js b/docs/assets/MahjongGamePage-CcjiTEak.js new file mode 100644 index 0000000..186fe9e --- /dev/null +++ b/docs/assets/MahjongGamePage-CcjiTEak.js @@ -0,0 +1,8 @@ +import{c as U,j as e,d as ve,e as ke,E as we,r as c,A as de}from"./index-BfWfBQOp.js";import{S as Te}from"./shuffle-Ri9xSsK2.js";import{R as K}from"./rotate-ccw-EKzY5q_W.js";import{V as Q,a as ee}from"./volume-x-ChIHiT28.js";import{E as Ce}from"./eye-off-B7FP-9s5.js";import{C as Se,a as $e}from"./chevron-right-CNA9GG_w.js";import{P as We}from"./pause-Bg-8t1oj.js";import{P as Pe}from"./play-WRQgdyAG.js";import{T as Y}from"./trophy-CUioHXrM.js";import{g as _e}from"./audioContext-NbgqvQGz.js";import{L as Me,F as Ae}from"./lightbulb-D7RWgS3V.js";import{S as Re,B as ze}from"./skip-forward-DUFQw-PC.js";import{T as He}from"./timer-t0ca9c1j.js";import{Z as Ee}from"./zap-CxtzYT6S.js";const Be=[["path",{d:"M8 3 4 7l4 4",key:"9rb6wj"}],["path",{d:"M4 7h16",key:"6tx8e3"}],["path",{d:"m16 21 4-4-4-4",key:"siv7j2"}],["path",{d:"M20 17H4",key:"h6l3hr"}]],Ie=U("arrow-left-right",Be);const Oe=[["path",{d:"M21.801 10A10 10 0 1 1 17 3.335",key:"yps3ct"}],["path",{d:"m9 11 3 3L22 4",key:"1pflzl"}]],V=U("circle-check-big",Oe);const Fe=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m15 9-6 6",key:"1uzhvr"}],["path",{d:"m9 9 6 6",key:"z0biqf"}]],re=U("circle-x",Fe);const Ge=[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["path",{d:"M16 3.128a4 4 0 0 1 0 7.744",key:"16gr8j"}],["path",{d:"M22 21v-2a4 4 0 0 0-3-3.87",key:"kshegd"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}]],pe=U("users",Ge);const Ve=[["path",{d:"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z",key:"1ngwbx"}]],Le=U("wrench",Ve),he={B:"Bamboo",C:"Characters",D:"Dots"},Z={B:"#4ade80",C:"#f87171",D:"#60a5fa"},De={sandbox:{label:"Sandbox",description:"Build any hand and check it freely"},guided:{label:"Guided",description:"Learn to spot pairs & melds step-by-step"},challenge:{label:"Challenge",description:"Speed rounds — Win or Not Win?"},"two-player":{label:"2 Player",description:"Take turns building hands"}},P=14,E=4,O=[1,2,3,4,5,6,7,8,9],B=["B","C","D"],J={title:"Mahjong Hand Solver",subtitle:"Backtracking-based winning hand validator",what:"Build a 14-tile Mahjong hand and check if it forms a valid winning combination — 4 melds (pongs or chows) plus 1 pair. Watch the backtracking solver try every possibility step-by-step.",skills:["Backtracking","Constraint Validation","Combinatorics","Pattern Matching"]},xe={sm:"w-9 h-12 sm:w-10 sm:h-14",md:"w-11 h-14 sm:w-12 sm:h-16 md:w-14 md:h-[4.35rem]",lg:"w-12 h-16 sm:w-14 sm:h-[4.6rem] md:w-16 md:h-20"};function I({code:t,index:s,count:n,size:a="md",selected:l=!1,disabled:r=!1,faded:m=!1,interactive:k=!1,removable:p=!1,placeholder:T=!1,onClick:i}){if(T||!t)return e.jsx("div",{className:`${xe[a]} relative rounded-xl border border-dashed border-emerald-900/30 bg-emerald-950/20 shadow-inner`,children:e.jsx("div",{className:"absolute inset-1 rounded-lg border border-emerald-900/20"})});const o=t[0],x=Number(t[1]),u=Z[o],g=e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"absolute inset-0 rounded-xl bg-gradient-to-br from-stone-50 via-amber-50 to-stone-200"}),e.jsx("div",{className:"absolute inset-x-1 top-1 h-1 rounded-full bg-white/80"}),e.jsx("div",{className:"absolute inset-1 rounded-lg border border-amber-950/10 bg-[radial-gradient(circle_at_30%_15%,rgba(255,255,255,0.8),transparent_38%),linear-gradient(135deg,rgba(255,255,255,0.35),transparent)]"}),e.jsx("div",{className:"absolute inset-y-1 right-0.5 w-1 rounded-r-lg bg-emerald-900/25"}),e.jsx("div",{className:"relative z-10 flex h-full flex-col items-center justify-center px-1 text-center",children:e.jsx(Ue,{suit:o,value:x,color:u,size:a})}),e.jsx("div",{className:"absolute left-1 top-1 text-[8px] font-black leading-none text-slate-900/35",children:x}),e.jsx("div",{className:"absolute bottom-1 right-1 rotate-180 text-[8px] font-black leading-none text-slate-900/35",children:x}),typeof s=="number"&&s>=0&&e.jsx("span",{className:"absolute -bottom-1 left-1/2 z-20 -translate-x-1/2 rounded-full bg-slate-950/80 px-1 text-[7px] font-mono text-slate-400 ring-1 ring-slate-700/50",children:s+1}),typeof n=="number"&&n>0&&e.jsx("span",{className:"absolute -right-1.5 -top-1.5 z-20 flex h-5 w-5 items-center justify-center rounded-full bg-emerald-950 text-[10px] font-bold text-emerald-200 ring-1 ring-emerald-500/50",children:n}),p&&e.jsx("span",{className:"absolute inset-0 z-30 flex items-center justify-center rounded-xl bg-red-950/70 text-sm font-black text-white opacity-0 transition-opacity group-hover:opacity-100",children:"x"})]}),b=` + group relative ${xe[a]} shrink-0 overflow-visible rounded-xl border transition-all duration-200 + shadow-[0_10px_18px_rgba(0,0,0,0.35),inset_0_-3px_0_rgba(0,0,0,0.18)] + ${l?"z-10 -translate-y-2 rotate-[-1deg] border-amber-300 ring-2 ring-amber-300/50":"border-amber-950/25"} + ${r?"cursor-not-allowed opacity-45 grayscale":""} + ${m?"opacity-35":""} + ${k&&!r?"cursor-pointer hover:-translate-y-2 hover:rotate-1 hover:shadow-[0_18px_28px_rgba(0,0,0,0.45)] active:translate-y-0":""} + `;return k||i?e.jsx("button",{onClick:i,disabled:r,title:t,className:b,children:g}):e.jsx("div",{className:b,children:g})}function Ue({suit:t,value:s,color:n,size:a}){return t==="C"?e.jsxs("div",{className:"flex flex-col items-center",children:[e.jsx("span",{style:{color:n},className:`${a==="sm"?"text-xl":a==="lg"?"text-3xl":"text-2xl"} font-black leading-none drop-shadow-sm`,children:s}),e.jsx("span",{style:{color:n},className:`${a==="sm"?"text-base":"text-lg"} font-black leading-none`,children:"萬"})]}):t==="B"?e.jsx("div",{className:"grid grid-cols-3 gap-0.5",children:Array.from({length:s}).map((l,r)=>e.jsx("span",{className:"h-3 w-1 rounded-full border border-emerald-950/20 bg-gradient-to-b from-emerald-300 to-emerald-700 shadow-sm"},r))}):e.jsx("div",{className:"grid grid-cols-3 gap-0.5",children:Array.from({length:s}).map((l,r)=>e.jsx("span",{className:"h-2.5 w-2.5 rounded-full border border-blue-950/30 bg-white shadow-sm",style:{boxShadow:`inset 0 0 0 2px ${n}`}},r))})}function Je(t,s){return t.filter(n=>n===s).length}function qe({suit:t,value:s,count:n,disabled:a,onClick:l}){const r=n>=4,m=`${t}${s}`;return e.jsx(I,{code:m,count:n,size:"md",disabled:a||r,interactive:!0,onClick:l})}function Ye({hand:t,handIsFull:s,onAddTile:n}){return e.jsxs("div",{className:"rounded-2xl border border-slate-700/50 bg-slate-900/70 p-4 shadow-xl shadow-black/20 backdrop-blur-sm md:p-5",children:[e.jsxs("div",{className:"mb-3 md:mb-4",children:[e.jsx("h3",{className:"text-xs md:text-sm font-semibold uppercase tracking-wider text-slate-300",children:"Tile Wall"}),e.jsx("p",{className:"mt-0.5 text-[10px] text-slate-500",children:"Choose up to four copies of each realistic Mahjong tile"})]}),e.jsx("div",{className:"space-y-4 md:space-y-5",children:B.map(a=>e.jsxs("div",{className:"rounded-xl border border-slate-800/70 bg-slate-950/35 p-3",children:[e.jsxs("div",{className:"mb-2 flex items-center gap-2",children:[e.jsx("span",{className:"h-2 w-2 rounded-full",style:{backgroundColor:Z[a]}}),e.jsx("p",{className:"text-[10px] md:text-xs font-semibold uppercase tracking-wider",style:{color:Z[a]},children:he[a]})]}),e.jsx("div",{className:"flex flex-wrap items-end gap-1.5 md:gap-2",children:O.map(l=>{const r=`${a}${l}`;return e.jsx(qe,{suit:a,value:l,count:Je(t,r),disabled:s,onClick:()=>n(r)},r)})})]},a))})]})}function Ze({hand:t,onRemoveTile:s}){const n=P-t.length;return e.jsxs("div",{className:"relative overflow-hidden rounded-2xl border border-emerald-900/40 bg-[radial-gradient(circle_at_top_left,rgba(16,185,129,0.14),transparent_34%),linear-gradient(135deg,rgba(15,23,42,0.96),rgba(6,78,59,0.36))] p-4 shadow-2xl shadow-black/30 md:p-5",children:[e.jsx("div",{className:"pointer-events-none absolute inset-x-0 bottom-0 h-16 bg-gradient-to-t from-black/25 to-transparent"}),e.jsxs("div",{className:"flex items-center justify-between mb-3 md:mb-4",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-xs md:text-sm font-semibold uppercase tracking-wider text-emerald-200",children:"Your Hand"}),e.jsx("p",{className:"mt-0.5 text-[10px] text-emerald-100/50",children:"Click a tile to discard it from the rack"})]}),e.jsxs("span",{className:`text-xs md:text-sm font-mono font-bold ${t.length===P?"text-emerald-400":"text-slate-500"}`,children:[t.length," / ",P]})]}),e.jsxs("div",{className:"relative flex min-h-[5.5rem] flex-wrap items-end gap-1.5 rounded-xl border border-emerald-950/40 bg-emerald-950/20 p-3 shadow-inner md:gap-2",children:[t.map((a,l)=>e.jsx(I,{code:a,index:l,size:"lg",interactive:!0,removable:!0,onClick:()=>s(l)},`${a}-${l}`)),n>0&&Array.from({length:n}).map((a,l)=>e.jsx(I,{size:"lg",placeholder:!0},`empty-${l}`))]})]})}function ie({code:t}){return e.jsx(I,{code:t,size:"sm"})}function Xe({meld:t,index:s}){return e.jsxs("div",{className:"flex items-center gap-2 rounded-xl bg-slate-950/35 p-2 ring-1 ring-slate-800/70 md:gap-3",children:[e.jsxs("span",{className:"w-14 shrink-0 text-[10px] font-semibold uppercase tracking-wider text-slate-500 md:w-16 md:text-xs",children:[t.type==="pong"?"Pong":"Chow"," ",s+1]}),e.jsx("div",{className:"flex gap-1 md:gap-1.5",children:t.tiles.map((n,a)=>e.jsx(ie,{code:n},`${n}-${a}`))})]})}function Ke({result:t}){return t?t.isWin?e.jsxs("div",{className:"rounded-2xl border border-emerald-500/30 bg-[radial-gradient(circle_at_top_left,rgba(16,185,129,0.18),transparent_36%),rgba(16,185,129,0.05)] p-4 shadow-xl shadow-emerald-950/20 backdrop-blur-sm md:p-5",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-3 md:mb-4",children:[e.jsx("span",{className:"text-lg md:text-2xl",children:"🀄"}),e.jsx("h3",{className:"text-sm md:text-base font-bold text-emerald-300",children:"Winning Hand!"})]}),e.jsxs("div",{className:"mb-3 flex items-center gap-2 rounded-xl bg-slate-950/35 p-2 ring-1 ring-slate-800/70 md:mb-4 md:gap-3",children:[e.jsx("span",{className:"w-14 shrink-0 text-[10px] font-semibold uppercase tracking-wider text-slate-500 md:w-16 md:text-xs",children:"Pair"}),e.jsxs("div",{className:"flex gap-1 md:gap-1.5",children:[e.jsx(ie,{code:t.pair[0]}),e.jsx(ie,{code:t.pair[1]})]})]}),e.jsx("div",{className:"space-y-2 md:space-y-3",children:t.melds.map((s,n)=>e.jsx(Xe,{meld:s,index:n},n))})]}):e.jsxs("div",{className:"rounded-xl border border-red-500/30 bg-red-500/5 p-4 md:p-5 backdrop-blur-sm",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-lg md:text-2xl",children:"❌"}),e.jsx("h3",{className:"text-sm md:text-base font-bold text-red-300",children:"Not a Winning Hand"})]}),e.jsx("p",{className:"mt-2 text-xs md:text-sm text-slate-400",children:"Hand is not a valid winning combination. A winning hand needs 4 melds (pongs or chows) and 1 pair."})]}):null}const Qe=[{label:"Slow",value:800},{label:"Med",value:400},{label:"Fast",value:150}];function et({handIsFull:t,result:s,showAnimation:n,steps:a,stepIndex:l,stepsTotal:r,isAnimating:m,animSpeed:k,currentStep:p,lastError:T,onCheckHand:i,onResetHand:o,onRandomHand:x,onWinningHand:u,onToggleAnimation:g,onStepForward:b,onStepBack:w,onAutoPlay:$,onSetAnimSpeed:N,soundEnabled:f,onToggleSound:C}){return e.jsxs("div",{className:"flex flex-col gap-4 w-full md:w-80 shrink-0 overflow-y-auto max-h-full pr-1",children:[e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 md:p-5 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-sm md:text-base font-bold text-indigo-300 mb-1",children:J.title}),e.jsx("p",{className:"text-[10px] md:text-xs text-slate-500 italic mb-2",children:J.subtitle}),e.jsx("p",{className:"text-xs md:text-sm text-slate-400 leading-relaxed",children:J.what}),e.jsx("div",{className:"mt-2 flex flex-wrap gap-1.5",children:J.skills.map(h=>e.jsx("span",{className:"inline-flex items-center rounded-full bg-violet-500/10 px-2 py-0.5 text-[10px] md:text-xs font-medium text-violet-400 ring-1 ring-violet-500/20",children:h},h))})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 md:p-5 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs md:text-sm font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Actions"}),e.jsxs("div",{className:"grid grid-cols-2 gap-2 md:gap-2.5 mb-3",children:[e.jsxs("button",{onClick:x,className:"flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2.5 text-xs md:text-sm font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300",children:[e.jsx(Te,{size:14})," Random"]}),e.jsxs("button",{onClick:u,className:"flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2.5 text-xs md:text-sm font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300",children:[e.jsx(ve,{size:14})," Winning"]}),e.jsxs("button",{onClick:o,className:"flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2.5 text-xs md:text-sm font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300",children:[e.jsx(K,{size:14})," Reset"]}),e.jsxs("button",{onClick:i,disabled:!t,className:`flex items-center justify-center gap-1.5 rounded-lg px-3 py-2.5 text-xs md:text-sm font-medium transition-all ${t?"bg-indigo-500/20 text-indigo-300 ring-1 ring-indigo-500/40 hover:bg-indigo-500/30":"bg-slate-800/40 text-slate-600 cursor-not-allowed"}`,children:[e.jsx(ke,{size:14})," Check"]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-2 md:gap-2.5",children:[e.jsxs("button",{onClick:()=>C(!f),className:`flex items-center justify-center gap-1.5 rounded-lg px-3 py-2.5 text-xs md:text-sm font-medium transition-all ${f?"bg-indigo-500/15 text-indigo-300 ring-1 ring-indigo-500/30":"bg-slate-800/60 text-slate-400 hover:bg-slate-700/60 hover:text-slate-300"}`,children:[f?e.jsx(Q,{size:14}):e.jsx(ee,{size:14})," Sound"]}),e.jsxs("button",{onClick:g,className:`flex items-center justify-center gap-1.5 rounded-lg px-3 py-2.5 text-xs md:text-sm font-medium transition-all ${n?"bg-amber-500/15 text-amber-300 ring-1 ring-amber-500/30":"bg-slate-800/60 text-slate-400 hover:bg-slate-700/60 hover:text-slate-300"}`,children:[n?e.jsx(we,{size:14}):e.jsx(Ce,{size:14}),n?"Anim On":"Anim Off"]})]})]}),n&&a.length>0&&e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 md:p-5 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs md:text-sm font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Solver Steps"}),e.jsxs("div",{className:"flex gap-2 mb-3",children:[e.jsxs("button",{onClick:w,disabled:l<=-1,className:"flex-1 flex items-center justify-center gap-1 rounded-lg bg-slate-800/60 px-2 py-2.5 text-xs md:text-sm font-medium text-slate-400 hover:bg-slate-700/60 hover:text-slate-300 disabled:opacity-30 disabled:cursor-not-allowed",children:[e.jsx(Se,{size:14})," Prev"]}),e.jsx("button",{onClick:$,className:`flex-1 flex items-center justify-center gap-1 rounded-lg px-2 py-2.5 text-xs md:text-sm font-medium transition-all ${m?"bg-amber-500/20 text-amber-300 ring-1 ring-amber-500/30":"bg-indigo-500/20 text-indigo-300 ring-1 ring-indigo-500/30 hover:bg-indigo-500/30"}`,children:m?e.jsxs(e.Fragment,{children:[e.jsx(We,{size:14})," Pause"]}):e.jsxs(e.Fragment,{children:[e.jsx(Pe,{size:14})," Play"]})}),e.jsxs("button",{onClick:b,disabled:l>=r-1,className:"flex-1 flex items-center justify-center gap-1 rounded-lg bg-slate-800/60 px-2 py-2.5 text-xs md:text-sm font-medium text-slate-400 hover:bg-slate-700/60 hover:text-slate-300 disabled:opacity-30 disabled:cursor-not-allowed",children:["Next ",e.jsx($e,{size:14})]})]}),e.jsx("div",{className:"flex gap-1 mb-2",children:Qe.map(h=>e.jsx("button",{onClick:()=>N(h.value),className:`flex-1 rounded-md px-2 py-1.5 text-[10px] md:text-xs font-medium transition-all ${k===h.value?"bg-indigo-500/20 text-indigo-300 ring-1 ring-indigo-500/30":"bg-slate-800/50 text-slate-500 hover:text-slate-400"}`,children:h.label},h.value))}),r>0&&e.jsxs("div",{className:"flex items-center justify-between text-[10px] md:text-xs text-slate-500",children:[e.jsx("span",{children:"Step"}),e.jsxs("span",{className:"font-mono font-semibold text-indigo-300",children:[Math.max(0,l+1)," / ",r]})]})]}),n&&p&&e.jsxs("div",{className:`rounded-xl border p-4 md:p-5 backdrop-blur-sm ${p.action.type==="found_win"?"border-emerald-500/30 bg-emerald-500/5":p.action.type==="backtrack"||p.action.type==="pair_failed"?"border-amber-500/30 bg-amber-500/5":p.action.type==="no_win"?"border-red-500/30 bg-red-500/5":"border-slate-700/50 bg-slate-900/60"}`,children:[e.jsx("h3",{className:"text-xs md:text-sm font-semibold uppercase tracking-wider text-slate-400 mb-2",children:"Current Step"}),e.jsx("p",{className:"text-xs md:text-sm text-slate-300 leading-relaxed",children:p.description})]}),s&&!n&&e.jsx("div",{className:`rounded-xl border p-4 md:p-5 backdrop-blur-sm ${s.isWin?"border-emerald-500/30 bg-emerald-500/5":"border-red-500/30 bg-red-500/5"}`,children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Y,{size:16,className:s.isWin?"text-emerald-400":"text-red-400"}),e.jsx("span",{className:`text-sm md:text-base font-bold ${s.isWin?"text-emerald-300":"text-red-300"}`,children:s.isWin?"Winning Hand!":"Not a Winner"})]})}),T&&e.jsx("div",{className:"rounded-lg border border-red-500/30 bg-red-500/5 px-3 py-2.5 text-center text-xs md:text-sm font-medium text-red-400 animate-pulse",children:T})]})}const oe=B.flatMap(t=>O.map(s=>`${t}${s}`));function fe(t){return{suit:t[0],value:Number(t[1])}}function tt(t){const s={};for(const n of t)s[n]=(s[n]??0)+1;return s}const me={B:0,C:1,D:2};function L(t){return[...t].sort((s,n)=>{const a=me[s[0]],l=me[n[0]];return a!==l?a-l:Number(s[1])-Number(n[1])})}function st(t){if(t.length===0)return"Hand is empty. Add 14 tiles.";if(t.lengthP)return`Hand has ${t.length} tiles. Maximum is ${P}.`;const s=tt(t);for(const[n,a]of Object.entries(s))if(a>E)return`Too many copies of ${n} (${a}). Maximum is ${E}.`;return null}function be(t,s){return t.length>=P?`Hand is full (${P} tiles).`:t.filter(a=>a===s).length>=E?`Already have ${E} copies of ${s}.`:null}function D(){const t={},s=[];for(;s.length(s[r]??0)>=E?!1:(t.push(r),s[r]=(s[r]??0)+1,!0);for(let r=0;r<4;r++){const m=B[Math.floor(Math.random()*B.length)];if(Math.random()<.4){const i=O[Math.floor(Math.random()*O.length)],o=`${m}${i}`;if((s[o]??0)+3<=E){n(o),n(o),n(o);continue}}let p=!1;const T=[...O.filter(i=>i<=7)].sort(()=>Math.random()-.5);for(const i of T){const o=`${m}${i}`,x=`${m}${i+1}`,u=`${m}${i+2}`;if((s[o]??0)Math.random()-.5);for(const r of l)if((s[r]??0)+2<=E){n(r),n(r),a=!0;break}return!a||t.length!==P?L(["B1","B2","B3","C4","C5","C6","D7","D7","D7","B8","B8","B8","C1","C1"]):L(t)}function je(t){const s={B:{},C:{},D:{}};for(const n of t){const{suit:a,value:l}=fe(n);s[a][l]=(s[a][l]??0)+1}return s}function ye(t){const s={B:{},C:{},D:{}};for(const n of B)for(const[a,l]of Object.entries(t[n]))s[n][Number(a)]=l;return s}function F(t){const s={};for(const n of B)for(const[a,l]of Object.entries(t[n]))l>0&&(s[`${n}${a}`]=l);return s}function nt(t){let s=0;for(const n of B)for(const a of Object.values(t[n]))s+=a;return s}function X(t,s,n,a){if(s===0)return nt(t)===0;for(const l of B)for(let r=1;r<=9;r++)if(!((t[l][r]??0)<=0)){if(t[l][r]>=3){const m=[`${l}${r}`,`${l}${r}`,`${l}${r}`];if(t[l][r]-=3,a&&a.push({action:{type:"try_meld",meldType:"pong",tiles:m,success:!0},description:`Try Pong: ${m.join(" ")}`,remaining:F(t)}),n.push({type:"pong",tiles:m}),X(t,s-1,n,a))return!0;n.pop(),t[l][r]+=3,a&&a.push({action:{type:"backtrack",tiles:m},description:`Backtrack: undo Pong ${m.join(" ")}`,remaining:F(t)})}if(r<=7&&(t[l][r]??0)>=1&&(t[l][r+1]??0)>=1&&(t[l][r+2]??0)>=1){const m=[`${l}${r}`,`${l}${r+1}`,`${l}${r+2}`];if(t[l][r]-=1,t[l][r+1]-=1,t[l][r+2]-=1,a&&a.push({action:{type:"try_meld",meldType:"chow",tiles:m,success:!0},description:`Try Chow: ${m.join(" ")}`,remaining:F(t)}),n.push({type:"chow",tiles:m}),X(t,s-1,n,a))return!0;n.pop(),t[l][r]+=1,t[l][r+1]+=1,t[l][r+2]+=1,a&&a.push({action:{type:"backtrack",tiles:m},description:`Backtrack: undo Chow ${m.join(" ")}`,remaining:F(t)})}return!1}return s===0}function G(t){const s=je(t),n=[];for(const a of B)for(let l=1;l<=9;l++)(s[a][l]??0)>=2&&n.push({suit:a,value:l});for(const{suit:a,value:l}of n){const r=ye(s);r[a][l]-=2;const m=[];if(X(r,4,m,null)){const k=`${a}${l}`;return{isWin:!0,pair:[k,k],melds:m}}}return{isWin:!1}}function at(t){const s=je(t),n=[],a=[];for(const l of B)for(let r=1;r<=9;r++)(s[l][r]??0)>=2&&a.push({suit:l,value:r});for(const{suit:l,value:r}of a){const m=`${l}${r}`;n.push({action:{type:"select_pair",pair:m},description:`Try pair: ${m} ${m}`,remaining:F(s)});const k=ye(s);k[l][r]-=2;const p=[];if(X(k,4,p,n)){const T={type:"found_win",pair:[m,m],melds:p.map(i=>({...i,tiles:[...i.tiles]}))};return n.push({action:T,description:`WIN! Pair: ${m} ${m} | Melds: ${p.map(i=>i.tiles.join(" ")).join(" | ")}`,remaining:{}}),{result:{isWin:!0,pair:[m,m],melds:p},steps:n}}n.push({action:{type:"pair_failed",pair:m},description:`Pair ${m} ${m} failed — no valid 4 melds found`,remaining:F(s)})}return n.push({action:{type:"no_win"},description:"No valid winning combination found.",remaining:F(s)}),{result:{isWin:!1},steps:n}}const lt=[261.63,293.66,329.63,392,440,493.88,523.25,587.33,659.25];function te(){const t=c.useRef(!0),s=c.useCallback(()=>_e(),[]),n=c.useCallback(i=>{t.current=i},[]),a=c.useCallback(i=>{if(!t.current)return;const o=s();if(!o)return;const x=lt[Math.max(0,Math.min(i-1,8))],u=o.createOscillator(),g=o.createGain();u.type="sine",u.frequency.setValueAtTime(x,o.currentTime),g.gain.setValueAtTime(.1,o.currentTime),g.gain.exponentialRampToValueAtTime(.001,o.currentTime+.2),u.connect(g),g.connect(o.destination),u.start(),u.stop(o.currentTime+.2);const b=o.createOscillator(),w=o.createGain();b.type="triangle",b.frequency.setValueAtTime(x*2,o.currentTime),w.gain.setValueAtTime(.03,o.currentTime),w.gain.exponentialRampToValueAtTime(.001,o.currentTime+.15),b.connect(w),w.connect(o.destination),b.start(o.currentTime+.02),b.stop(o.currentTime+.17)},[s]),l=c.useCallback(()=>{if(!t.current)return;const i=s();if(!i)return;const o=i.createOscillator(),x=i.createGain();o.type="sine",o.frequency.setValueAtTime(480,i.currentTime),o.frequency.setValueAtTime(320,i.currentTime+.08),x.gain.setValueAtTime(.07,i.currentTime),x.gain.exponentialRampToValueAtTime(.001,i.currentTime+.12),o.connect(x),x.connect(i.destination),o.start(),o.stop(i.currentTime+.12)},[s]),r=c.useCallback(()=>{if(!t.current)return;const i=s();if(!i)return;[523.25,587.33,659.25,783.99,880,1046.5].forEach((x,u)=>{const g=i.createOscillator(),b=i.createGain();g.type="sine",g.frequency.value=x,b.gain.setValueAtTime(.08,i.currentTime+u*.09),b.gain.exponentialRampToValueAtTime(.001,i.currentTime+u*.09+.2),g.connect(b),b.connect(i.destination),g.start(i.currentTime+u*.09),g.stop(i.currentTime+u*.09+.2)})},[s]),m=c.useCallback(()=>{if(!t.current)return;const i=s();if(!i)return;[400,340,280].forEach((x,u)=>{const g=i.createOscillator(),b=i.createGain();g.type="sine",g.frequency.value=x,b.gain.setValueAtTime(.07,i.currentTime+u*.1),b.gain.exponentialRampToValueAtTime(.001,i.currentTime+u*.1+.2),g.connect(b),b.connect(i.destination),g.start(i.currentTime+u*.1),g.stop(i.currentTime+u*.1+.2)})},[s]),k=c.useCallback(()=>{if(!t.current)return;const i=s();if(!i)return;const o=i.createOscillator(),x=i.createGain();o.type="sawtooth",o.frequency.setValueAtTime(190,i.currentTime),o.frequency.setValueAtTime(130,i.currentTime+.12),x.gain.setValueAtTime(.07,i.currentTime),x.gain.exponentialRampToValueAtTime(.001,i.currentTime+.25),o.connect(x),x.connect(i.destination),o.start(),o.stop(i.currentTime+.25)},[s]),p=c.useCallback(i=>{if(!t.current)return;const o=s();if(!o)return;const x=400+i%8*50,u=o.createOscillator(),g=o.createGain();u.type="sine",u.frequency.setValueAtTime(x,o.currentTime),g.gain.setValueAtTime(.05,o.currentTime),g.gain.exponentialRampToValueAtTime(.001,o.currentTime+.08),u.connect(g),g.connect(o.destination),u.start(),u.stop(o.currentTime+.08)},[s]),T=c.useCallback(()=>{if(!t.current)return;const i=s();if(!i)return;const o=i.createOscillator(),x=i.createGain();o.type="triangle",o.frequency.setValueAtTime(550,i.currentTime),o.frequency.setValueAtTime(350,i.currentTime+.06),x.gain.setValueAtTime(.05,i.currentTime),x.gain.exponentialRampToValueAtTime(.001,i.currentTime+.1),o.connect(x),x.connect(i.destination),o.start(),o.stop(i.currentTime+.1)},[s]);return{playTilePlaced:a,playTileRemoved:l,playWinSound:r,playLoseSound:m,playErrorSound:k,playStepTick:p,playBacktrackSound:T,setEnabled:n}}function rt(){if(Math.random()<.6){const s=ce(),n=G(s);return{hand:s,isWinning:n.isWin,solution:n.isWin?n:null}}for(let s=0;s<50;s++){const n=D();if(!G(n).isWin)return{hand:n,isWinning:!1,solution:null}}return{hand:D(),isWinning:!1,solution:null}}const ne={hand:[],isWinning:!1,solution:null,phase:"judging",playerSaidWin:null,selectedTiles:[],foundPair:null,foundMelds:[],hintsUsed:0,showHint:!1,feedback:null,roundComplete:!1};function it(){const[t,s]=c.useState(ne),[n,a]=c.useState(0),[l,r]=c.useState(0),[m,k]=c.useState(0),[p,T]=c.useState(!1),[i,o]=c.useState(!0),x=te(),u=c.useCallback(()=>{const d=rt();s({...ne,hand:d.hand,isWinning:d.isWinning,solution:d.solution}),T(!0)},[]),g=c.useCallback(d=>{const v=d===t.isWinning;v&&t.isWinning&&t.solution?(x.playTilePlaced(5),s(j=>({...j,playerSaidWin:d,phase:"grouping",feedback:"Correct! Now identify the pair and melds."}))):v&&!t.isWinning?(x.playWinSound(),a(j=>j+100-t.hintsUsed*20),r(j=>j+1),k(j=>j+1),s(j=>({...j,playerSaidWin:d,phase:"feedback",feedback:"Correct! This hand is not a winner.",roundComplete:!0}))):(x.playLoseSound(),r(j=>j+1),s(j=>({...j,playerSaidWin:d,phase:"feedback",feedback:t.isWinning?"Wrong — this hand IS a winner! Check the solution below.":"Wrong — this hand is NOT a winner.",roundComplete:!0})))},[t,x]),b=c.useCallback(d=>{s(v=>{const j=v.selectedTiles.includes(d)?v.selectedTiles.filter(y=>y!==d):[...v.selectedTiles,d];return{...v,selectedTiles:j}}),x.playTilePlaced(3)},[x]),w=c.useCallback(()=>{if(t.selectedTiles.length!==2||!t.solution)return;const d=t.selectedTiles.map(y=>t.hand[y]),v=t.solution.pair;d[0]===d[1]&&d[0]===v[0]?(x.playTilePlaced(7),s(y=>({...y,foundPair:[d[0],d[1]],selectedTiles:[],feedback:"Pair found! Now identify the 4 melds."}))):(x.playErrorSound(),s(y=>({...y,selectedTiles:[],feedback:"That's not the correct pair. Try again!"})))},[t,x]),$=c.useCallback(()=>{if(t.selectedTiles.length!==3||!t.solution)return;const d=t.selectedTiles.map(y=>t.hand[y]).sort(),v=t.solution.melds.filter((y,W)=>!t.foundMelds.some(S=>JSON.stringify(S.tiles.sort())===JSON.stringify(t.solution.melds[W].tiles.sort()))),j=v.findIndex(y=>JSON.stringify([...y.tiles].sort())===JSON.stringify(d));if(j>=0){const y=v[j];x.playTilePlaced(8);const W=[...t.foundMelds,y];W.length===4?(x.playWinSound(),a(S=>S+200-t.hintsUsed*30),r(S=>S+1),k(S=>S+1),s(S=>({...S,foundMelds:W,selectedTiles:[],phase:"feedback",feedback:"Excellent! You identified all groups correctly!",roundComplete:!0}))):s(S=>({...S,foundMelds:W,selectedTiles:[],feedback:`Meld ${W.length}/4 found! Keep going.`}))}else x.playErrorSound(),s(y=>({...y,selectedTiles:[],feedback:"Those 3 tiles don't form a valid meld in the solution. Try again!"}))},[t,x]),N=c.useCallback(()=>{t.solution&&(x.playBacktrackSound(),s(d=>({...d,hintsUsed:d.hintsUsed+1,showHint:!0})),setTimeout(()=>{s(d=>({...d,showHint:!1}))},3e3))},[t.solution,x]),f=c.useCallback(()=>{r(d=>d+1),s(d=>({...d,phase:"feedback",feedback:"Skipped grouping. Here's the solution:",roundComplete:!0}))},[]),C=c.useCallback(()=>{s(ne),a(0),r(0),k(0),T(!1)},[]),h=c.useCallback(d=>{o(d),x.setEnabled(d)},[x]);return{round:t,score:n,totalRounds:l,correctRounds:m,started:p,soundEnabled:i,startNewRound:u,judgeHand:g,toggleTileSelection:b,submitPair:w,submitMeld:$,useHint:N,skipGrouping:f,resetGame:C,toggleSound:h}}function q({code:t,index:s,selected:n,onClick:a}){return e.jsx(I,{code:t,index:s,size:"lg",selected:n,interactive:!!a,disabled:!a,onClick:a})}function ot(){const{round:t,score:s,totalRounds:n,correctRounds:a,started:l,soundEnabled:r,startNewRound:m,judgeHand:k,toggleTileSelection:p,submitPair:T,submitMeld:i,useHint:o,skipGrouping:x,resetGame:u,toggleSound:g}=it();if(!l)return e.jsx("div",{className:"flex flex-1 items-center justify-center p-6",children:e.jsxs("div",{className:"max-w-md text-center",children:[e.jsx("div",{className:"text-4xl mb-4",children:"📖"}),e.jsx("h2",{className:"text-xl md:text-2xl font-bold text-white mb-2",children:"Guided Mode"}),e.jsxs("p",{className:"text-sm md:text-base text-slate-400 mb-6 leading-relaxed",children:["Practice identifying winning Mahjong hands step-by-step. First judge if the hand is a winner, then identify the ",e.jsx("span",{className:"text-indigo-300 font-semibold",children:"pair"})," and ",e.jsx("span",{className:"text-violet-300 font-semibold",children:"4 melds"})," by selecting tiles. Use hints if you get stuck!"]}),e.jsx("button",{onClick:m,className:"rounded-xl bg-gradient-to-r from-indigo-500 to-violet-500 px-8 py-3 text-sm md:text-base font-bold text-white shadow-lg shadow-indigo-500/25 transition-all hover:shadow-indigo-500/40 hover:scale-105 active:scale-95",children:"Start Learning"})]})});const{hand:b,phase:w,selectedTiles:$,foundPair:N,foundMelds:f,feedback:C,showHint:h,solution:d,roundComplete:v,hintsUsed:j}=t,y=d&&h?N?`Hint: Next meld is ${d.melds[f.length]?.tiles.join(" ")??"done!"}`:`Hint: The pair is ${d.pair[0]} ${d.pair[1]}`:null,W=new Set;if(N){let S=0;for(let M=0;M=0&&(W.add(z),M.splice(H,1))}}return e.jsxs("div",{className:"flex flex-1 flex-col md:flex-row gap-4 md:gap-6 overflow-auto p-4 md:p-6",children:[e.jsxs("div",{className:"flex flex-col gap-4 w-full md:w-80 shrink-0 overflow-y-auto max-h-full pr-1",children:[e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 md:p-5 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs md:text-sm font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Progress"}),e.jsxs("div",{className:"grid grid-cols-3 gap-3 text-center",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-lg md:text-xl font-bold text-indigo-300",children:s}),e.jsx("p",{className:"text-[10px] md:text-xs text-slate-500",children:"Score"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-lg md:text-xl font-bold text-emerald-300",children:a}),e.jsx("p",{className:"text-[10px] md:text-xs text-slate-500",children:"Correct"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-lg md:text-xl font-bold text-slate-300",children:n}),e.jsx("p",{className:"text-[10px] md:text-xs text-slate-500",children:"Rounds"})]})]})]}),w==="judging"&&e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 md:p-5 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs md:text-sm font-semibold uppercase tracking-wider text-slate-400 mb-2",children:"Step 1: Judge"}),e.jsx("p",{className:"text-xs md:text-sm text-slate-400 mb-4",children:"Is this a valid winning hand?"}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("button",{onClick:()=>k(!0),className:"flex items-center justify-center gap-2 rounded-xl bg-emerald-500/15 px-4 py-3 text-sm md:text-base font-bold text-emerald-300 ring-1 ring-emerald-500/30 transition-all hover:bg-emerald-500/25 hover:scale-105 active:scale-95",children:[e.jsx(V,{size:16})," Win"]}),e.jsxs("button",{onClick:()=>k(!1),className:"flex items-center justify-center gap-2 rounded-xl bg-red-500/15 px-4 py-3 text-sm md:text-base font-bold text-red-300 ring-1 ring-red-500/30 transition-all hover:bg-red-500/25 hover:scale-105 active:scale-95",children:[e.jsx(re,{size:16})," Not Win"]})]})]}),w==="grouping"&&e.jsxs("div",{className:"rounded-xl border border-indigo-500/30 bg-indigo-500/5 p-4 md:p-5 backdrop-blur-sm",children:[e.jsxs("h3",{className:"text-xs md:text-sm font-semibold uppercase tracking-wider text-indigo-300 mb-2",children:["Step 2: ",N?`Find Meld ${f.length+1}/4`:"Find the Pair"]}),e.jsx("p",{className:"text-xs md:text-sm text-slate-400 mb-3",children:N?"Select 3 tiles that form a pong (AAA) or chow (ABC).":"Select 2 identical tiles that form the pair."}),e.jsxs("p",{className:"text-xs md:text-sm text-indigo-300 font-mono mb-3",children:["Selected: ",$.length," / ",N?3:2]}),e.jsx("div",{className:"flex gap-2 mb-3",children:N?e.jsxs("button",{onClick:i,disabled:$.length!==3,className:"flex-1 flex items-center justify-center gap-1.5 rounded-lg bg-indigo-500/20 px-3 py-2.5 text-xs md:text-sm font-medium text-indigo-300 ring-1 ring-indigo-500/30 transition-all hover:bg-indigo-500/30 disabled:opacity-30 disabled:cursor-not-allowed",children:[e.jsx(V,{size:14})," Submit Meld"]}):e.jsxs("button",{onClick:T,disabled:$.length!==2,className:"flex-1 flex items-center justify-center gap-1.5 rounded-lg bg-indigo-500/20 px-3 py-2.5 text-xs md:text-sm font-medium text-indigo-300 ring-1 ring-indigo-500/30 transition-all hover:bg-indigo-500/30 disabled:opacity-30 disabled:cursor-not-allowed",children:[e.jsx(V,{size:14})," Submit Pair"]})}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("button",{onClick:o,className:"flex-1 flex items-center justify-center gap-1.5 rounded-lg bg-amber-500/15 px-3 py-2 text-xs md:text-sm font-medium text-amber-300 ring-1 ring-amber-500/30 transition-all hover:bg-amber-500/25",children:[e.jsx(Me,{size:14})," Hint (",j,")"]}),e.jsxs("button",{onClick:x,className:"flex-1 flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs md:text-sm font-medium text-slate-400 transition-all hover:bg-slate-700/60",children:[e.jsx(Re,{size:14})," Skip"]})]})]}),C&&e.jsxs("div",{className:`rounded-xl border p-4 md:p-5 backdrop-blur-sm ${w==="feedback"&&v?t.playerSaidWin===t.isWinning?"border-emerald-500/30 bg-emerald-500/5":"border-red-500/30 bg-red-500/5":"border-indigo-500/30 bg-indigo-500/5"}`,children:[e.jsx("p",{className:"text-xs md:text-sm text-slate-300 leading-relaxed",children:C}),y&&e.jsx("p",{className:"mt-2 text-xs md:text-sm text-amber-300 font-mono animate-pulse",children:y}),v&&d&&e.jsxs("div",{className:"mt-3 text-[10px] md:text-xs text-slate-500",children:[e.jsxs("p",{children:["Solution: Pair ",d.pair.join(" ")]}),d.melds.map((S,M)=>e.jsxs("p",{children:[S.type==="pong"?"Pong":"Chow",": ",S.tiles.join(" ")]},M))]}),v&&e.jsxs("button",{onClick:m,className:"mt-3 w-full flex items-center justify-center gap-2 rounded-lg bg-indigo-500/20 px-4 py-2.5 text-xs md:text-sm font-medium text-indigo-300 ring-1 ring-indigo-500/30 transition-all hover:bg-indigo-500/30",children:["Next Round ",e.jsx(de,{size:14})]})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("button",{onClick:u,className:"flex-1 flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2.5 text-xs md:text-sm font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300",children:[e.jsx(K,{size:14})," Reset"]}),e.jsx("button",{onClick:()=>g(!r),className:`flex items-center justify-center gap-1.5 rounded-lg px-3 py-2.5 text-xs md:text-sm font-medium transition-all ${r?"bg-indigo-500/15 text-indigo-300 ring-1 ring-indigo-500/30":"bg-slate-800/60 text-slate-400"}`,children:r?e.jsx(Q,{size:14}):e.jsx(ee,{size:14})})]})]}),e.jsxs("div",{className:"order-last md:order-first flex md:flex-1 flex-col gap-4 min-h-0 md:overflow-auto",children:[e.jsxs("div",{className:"rounded-2xl border border-emerald-900/40 bg-[radial-gradient(circle_at_top_left,rgba(16,185,129,0.14),transparent_34%),linear-gradient(135deg,rgba(15,23,42,0.96),rgba(6,78,59,0.32))] p-4 shadow-2xl shadow-black/30 md:p-5",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3 md:mb-4",children:[e.jsx("h3",{className:"text-xs md:text-sm font-semibold uppercase tracking-wider text-emerald-200",children:"Hand"}),N&&e.jsxs("span",{className:"text-xs md:text-sm font-mono text-emerald-300",children:["Pair ✓ | Melds ",f.length,"/4"]})]}),e.jsx("div",{className:"flex flex-wrap items-end gap-1.5 rounded-xl border border-emerald-950/40 bg-emerald-950/20 p-3 shadow-inner md:gap-2",children:b.map((S,M)=>{const z=W.has(M),H=$.includes(M),se=w==="grouping"&&!z;return e.jsx("div",{className:z?"opacity-30":"",children:e.jsx(q,{code:S,index:M,selected:H,onClick:se?()=>p(M):void 0})},`${S}-${M}`)})})]}),(N||f.length>0)&&e.jsxs("div",{className:"rounded-2xl border border-emerald-500/20 bg-emerald-500/5 p-4 shadow-xl shadow-emerald-950/20 backdrop-blur-sm md:p-5",children:[e.jsx("h3",{className:"text-xs md:text-sm font-semibold uppercase tracking-wider text-emerald-400 mb-3",children:"Found Groups"}),N&&e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsx("span",{className:"text-[10px] md:text-xs font-medium text-slate-600 w-14 shrink-0",children:"Pair"}),e.jsxs("div",{className:"flex gap-1",children:[e.jsx(q,{code:N[0],index:-1,selected:!1}),e.jsx(q,{code:N[1],index:-1,selected:!1})]})]}),f.map((S,M)=>e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsxs("span",{className:"text-[10px] md:text-xs font-medium text-slate-600 w-14 shrink-0",children:[S.type==="pong"?"Pong":"Chow"," ",M+1]}),e.jsx("div",{className:"flex gap-1",children:S.tiles.map((z,H)=>e.jsx(q,{code:z,index:-1,selected:!1},`${z}-${H}`))})]},M))]})]})]})}function ue(){if(Math.random()<.5){const s=ce(),n=G(s);return{hand:s,isWinning:n.isWin,solution:n.isWin?n:null}}for(let s=0;s<50;s++){const n=D();if(!G(n).isWin)return{hand:n,isWinning:!1,solution:null}}return{hand:D(),isWinning:!1,solution:null}}const ae={hand:[],isWinning:!1,solution:null,round:0,score:0,streak:0,bestStreak:0,timer:0,answered:!1,lastCorrect:null,totalCorrect:0,totalAnswered:0};function dt(){const[t,s]=c.useState(ae),[n,a]=c.useState(!1),l=c.useRef(null),r=te(),[m,k]=c.useState(!0);c.useEffect(()=>(n&&!t.answered&&(l.current=setInterval(()=>{s(u=>({...u,timer:u.timer+1}))},1e3)),()=>{l.current&&clearInterval(l.current)}),[n,t.answered]);const p=c.useCallback(()=>{const{hand:u,isWinning:g,solution:b}=ue();s({...ae,hand:u,isWinning:g,solution:b,round:1}),a(!0)},[]),T=c.useCallback(()=>{const{hand:u,isWinning:g,solution:b}=ue();s(w=>({...w,hand:u,isWinning:g,solution:b,round:w.round+1,timer:0,answered:!1,lastCorrect:null}))},[]),i=c.useCallback(u=>{if(t.answered)return;const g=u===t.isWinning,b=Math.max(0,10-t.timer),w=g?100+b*10+t.streak*25:0;g?r.playWinSound():r.playLoseSound(),s($=>({...$,answered:!0,lastCorrect:g,score:$.score+w,streak:g?$.streak+1:0,bestStreak:g?Math.max($.bestStreak,$.streak+1):$.bestStreak,totalCorrect:$.totalCorrect+(g?1:0),totalAnswered:$.totalAnswered+1}))},[t.answered,t.isWinning,t.timer,t.streak,r]),o=c.useCallback(()=>{s(ae),a(!1),l.current&&clearInterval(l.current)},[]),x=c.useCallback(u=>{k(u),r.setEnabled(u)},[r]);return{...t,isRunning:n,soundEnabled:m,startGame:p,nextRound:T,answer:i,resetGame:o,toggleSound:x}}function ct({code:t}){return e.jsx(I,{code:t,size:"lg"})}function xt(){const{hand:t,isWinning:s,solution:n,round:a,score:l,streak:r,bestStreak:m,timer:k,answered:p,lastCorrect:T,totalCorrect:i,totalAnswered:o,isRunning:x,soundEnabled:u,startGame:g,nextRound:b,answer:w,resetGame:$,toggleSound:N}=dt();return x?e.jsxs("div",{className:"flex flex-1 flex-col md:flex-row gap-4 md:gap-6 overflow-auto p-4 md:p-6",children:[e.jsxs("div",{className:"flex flex-col gap-4 w-full md:w-80 shrink-0 overflow-y-auto max-h-full pr-1",children:[e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 md:p-5 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs md:text-sm font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Stats"}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Y,{size:14,className:"text-amber-400"}),e.jsxs("div",{children:[e.jsx("p",{className:"text-lg md:text-xl font-bold text-white",children:l}),e.jsx("p",{className:"text-[10px] md:text-xs text-slate-500",children:"Score"})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Ae,{size:14,className:"text-orange-400"}),e.jsxs("div",{children:[e.jsx("p",{className:"text-lg md:text-xl font-bold text-orange-300",children:r}),e.jsx("p",{className:"text-[10px] md:text-xs text-slate-500",children:"Streak"})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(He,{size:14,className:"text-cyan-400"}),e.jsxs("div",{children:[e.jsxs("p",{className:"text-lg md:text-xl font-bold text-cyan-300",children:[k,"s"]}),e.jsx("p",{className:"text-[10px] md:text-xs text-slate-500",children:"Time"})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(V,{size:14,className:"text-emerald-400"}),e.jsxs("div",{children:[e.jsxs("p",{className:"text-lg md:text-xl font-bold text-emerald-300",children:[i,"/",o]}),e.jsx("p",{className:"text-[10px] md:text-xs text-slate-500",children:"Correct"})]})]})]}),e.jsxs("div",{className:"mt-3 flex items-center justify-between text-[10px] md:text-xs text-slate-500",children:[e.jsxs("span",{children:["Round ",a]}),e.jsxs("span",{children:["Best streak: ",m]})]})]}),!p&&e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 md:p-5 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs md:text-sm font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Your Judgment"}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("button",{onClick:()=>w(!0),className:"flex items-center justify-center gap-2 rounded-xl bg-emerald-500/15 px-4 py-4 text-sm md:text-base font-bold text-emerald-300 ring-1 ring-emerald-500/30 transition-all hover:bg-emerald-500/25 hover:scale-105 active:scale-95",children:[e.jsx(V,{size:18})," Win"]}),e.jsxs("button",{onClick:()=>w(!1),className:"flex items-center justify-center gap-2 rounded-xl bg-red-500/15 px-4 py-4 text-sm md:text-base font-bold text-red-300 ring-1 ring-red-500/30 transition-all hover:bg-red-500/25 hover:scale-105 active:scale-95",children:[e.jsx(re,{size:18})," Not Win"]})]})]}),p&&e.jsxs("div",{className:`rounded-xl border p-4 md:p-5 backdrop-blur-sm ${T?"border-emerald-500/30 bg-emerald-500/5":"border-red-500/30 bg-red-500/5"}`,children:[e.jsx("div",{className:"flex items-center gap-2 mb-2",children:T?e.jsxs(e.Fragment,{children:[e.jsx(V,{size:18,className:"text-emerald-400"}),e.jsx("span",{className:"text-sm md:text-base font-bold text-emerald-300",children:"Correct!"})]}):e.jsxs(e.Fragment,{children:[e.jsx(re,{size:18,className:"text-red-400"}),e.jsx("span",{className:"text-sm md:text-base font-bold text-red-300",children:"Wrong!"})]})}),e.jsxs("p",{className:"text-xs md:text-sm text-slate-400 mb-3",children:["The hand was ",e.jsx("span",{className:`font-bold ${s?"text-emerald-300":"text-red-300"}`,children:s?"a Winner":"Not a Winner"}),"."]}),s&&n&&e.jsxs("div",{className:"text-[10px] md:text-xs text-slate-500 mb-3",children:["Pair: ",n.pair.join(" ")," | Melds: ",n.melds.map(f=>f.tiles.join(" ")).join(" | ")]}),e.jsxs("button",{onClick:b,className:"w-full flex items-center justify-center gap-2 rounded-lg bg-indigo-500/20 px-4 py-2.5 text-xs md:text-sm font-medium text-indigo-300 ring-1 ring-indigo-500/30 transition-all hover:bg-indigo-500/30",children:["Next Round ",e.jsx(de,{size:14})]})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("button",{onClick:$,className:"flex-1 flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2.5 text-xs md:text-sm font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300",children:[e.jsx(K,{size:14})," Reset"]}),e.jsx("button",{onClick:()=>N(!u),className:`flex items-center justify-center gap-1.5 rounded-lg px-3 py-2.5 text-xs md:text-sm font-medium transition-all ${u?"bg-indigo-500/15 text-indigo-300 ring-1 ring-indigo-500/30":"bg-slate-800/60 text-slate-400"}`,children:u?e.jsx(Q,{size:14}):e.jsx(ee,{size:14})})]})]}),e.jsx("div",{className:"order-last md:order-first flex md:flex-1 flex-col gap-4 min-h-0 md:overflow-auto",children:e.jsxs("div",{className:"rounded-2xl border border-emerald-900/40 bg-[radial-gradient(circle_at_top_left,rgba(16,185,129,0.14),transparent_34%),linear-gradient(135deg,rgba(15,23,42,0.96),rgba(6,78,59,0.32))] p-4 shadow-2xl shadow-black/30 md:p-5",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3 md:mb-4",children:[e.jsx("h3",{className:"text-xs md:text-sm font-semibold uppercase tracking-wider text-emerald-200",children:"Hand to Judge"}),e.jsxs("span",{className:"text-xs md:text-sm font-mono font-bold text-indigo-300",children:["Round ",a]})]}),e.jsx("div",{className:"flex flex-wrap items-end gap-1.5 rounded-xl border border-emerald-950/40 bg-emerald-950/20 p-3 shadow-inner md:gap-2",children:t.map((f,C)=>e.jsx(ct,{code:f},`${f}-${C}`))})]})})]}):e.jsx("div",{className:"flex flex-1 items-center justify-center p-6",children:e.jsxs("div",{className:"max-w-md text-center",children:[e.jsx("div",{className:"text-4xl mb-4",children:"⚡"}),e.jsx("h2",{className:"text-xl md:text-2xl font-bold text-white mb-2",children:"Challenge Mode"}),e.jsxs("p",{className:"text-sm md:text-base text-slate-400 mb-6 leading-relaxed",children:["You'll see a 14-tile hand. Decide as fast as you can: is it a ",e.jsx("span",{className:"text-emerald-400 font-semibold",children:"Winning Hand"})," or ",e.jsx("span",{className:"text-red-400 font-semibold",children:"Not a Winner"}),"? Score points for correct answers. Faster = more bonus points. Build streaks for multipliers!"]}),e.jsx("button",{onClick:g,className:"rounded-xl bg-gradient-to-r from-indigo-500 to-violet-500 px-8 py-3 text-sm md:text-base font-bold text-white shadow-lg shadow-indigo-500/25 transition-all hover:shadow-indigo-500/40 hover:scale-105 active:scale-95",children:"Start Challenge"})]})})}function ge(t){return{name:t,hand:[],result:null,score:0}}const le={phase:"building",players:[ge("Player 1"),ge("Player 2")],currentPlayer:0,round:1,roundComplete:!1};function mt(){const[t,s]=c.useState(le),[n,a]=c.useState(null),[l,r]=c.useState(!1),[m,k]=c.useState(!0),p=te(),T=t.players[t.currentPlayer].hand,i=T.length>=P,o=t.players[0].hand.length>=P&&t.players[1].hand.length>=P,x=c.useCallback(()=>{s({...le}),r(!0),a(null)},[]),u=c.useCallback(h=>{if(t.phase!=="building")return;const d=t.players[t.currentPlayer].hand,v=be(d,h);if(v){a(v),p.playErrorSound();return}a(null);const{value:j}={value:Number(h[1])};p.playTilePlaced(j),s(y=>{const W=[...y.players],S={...W[y.currentPlayer]};S.hand=L([...S.hand,h]),W[y.currentPlayer]=S;const M=S.hand.length>=P,z=W[1-y.currentPlayer].hand.length>=P;let H=y.currentPlayer;return M&&!z?H=1-y.currentPlayer:M||(H=1-y.currentPlayer,W[H].hand.length>=P&&(H=y.currentPlayer)),{...y,players:W,currentPlayer:H}})},[t.phase,t.currentPlayer,t.players,p]),g=c.useCallback(h=>{t.phase==="building"&&(p.playTileRemoved(),a(null),s(d=>{const v=[...d.players],j={...v[d.currentPlayer]},y=[...j.hand];return y.splice(h,1),j.hand=y,v[d.currentPlayer]=j,{...d,players:v}}))},[t.phase,p]),b=c.useCallback(()=>{if(!o)return;const h=G(t.players[0].hand),d=G(t.players[1].hand),v=h.isWin?1:0,j=d.isWin?1:0;v>j||j>v?p.playWinSound():p.playLoseSound(),s(y=>{const W=[...y.players];return W[0]={...W[0],result:h,score:W[0].score+v},W[1]={...W[1],result:d,score:W[1].score+j},{...y,players:W,phase:"results",roundComplete:!0}})},[o,t.players,p]),w=c.useCallback(()=>{s(h=>({...h,phase:"building",players:[{...h.players[0],hand:[],result:null},{...h.players[1],hand:[],result:null}],currentPlayer:0,round:h.round+1,roundComplete:!1})),a(null)},[]),$=c.useCallback(()=>{s(le),r(!1),a(null)},[]),N=c.useCallback(()=>{if(t.phase!=="building")return;const h=1-t.currentPlayer;t.players[h].hand.length>=P||s(d=>({...d,currentPlayer:h}))},[t.phase,t.currentPlayer,t.players]),f=()=>{if(t.phase!=="results")return null;const h=t.players[0].result,d=t.players[1].result;return!h||!d?null:h.isWin&&!d.isWin?t.players[0].name:!h.isWin&&d.isWin?t.players[1].name:h.isWin&&d.isWin?"Both Win!":"Neither Wins"},C=c.useCallback(h=>{k(h),p.setEnabled(h)},[p]);return{state:t,lastError:n,started:l,soundEnabled:m,currentHand:T,currentHandIsFull:i,bothFull:o,winner:f(),startGame:x,addTile:u,removeTile:g,checkBothHands:b,nextRound:w,resetGame:$,switchPlayer:N,toggleSound:C}}function ut({code:t,onRemove:s}){return e.jsx(I,{code:t,size:"md",interactive:!!s,removable:!!s,onClick:s})}function gt(t,s){return t.filter(n=>n===s).length}function pt({suit:t,value:s,count:n,disabled:a,onClick:l}){const r=n>=4,m=`${t}${s}`;return e.jsx(I,{code:m,count:n,size:"sm",disabled:a||r,interactive:!0,onClick:l})}function ht(){const{state:t,lastError:s,started:n,soundEnabled:a,currentHand:l,currentHandIsFull:r,bothFull:m,winner:k,startGame:p,addTile:T,removeTile:i,checkBothHands:o,nextRound:x,resetGame:u,switchPlayer:g,toggleSound:b}=mt();if(!n)return e.jsx("div",{className:"flex flex-1 items-center justify-center p-6",children:e.jsxs("div",{className:"max-w-md text-center",children:[e.jsx("div",{className:"text-4xl mb-4",children:"👥"}),e.jsx("h2",{className:"text-xl md:text-2xl font-bold text-white mb-2",children:"2 Player Mode"}),e.jsxs("p",{className:"text-sm md:text-base text-slate-400 mb-6 leading-relaxed",children:["Take turns placing tiles to build your 14-tile hands. Players alternate picks. Once both hands are complete, the solver checks both — whoever has a valid ",e.jsx("span",{className:"text-emerald-400 font-semibold",children:"winning hand"})," scores a point!"]}),e.jsx("button",{onClick:p,className:"rounded-xl bg-gradient-to-r from-indigo-500 to-violet-500 px-8 py-3 text-sm md:text-base font-bold text-white shadow-lg shadow-indigo-500/25 transition-all hover:shadow-indigo-500/40 hover:scale-105 active:scale-95",children:"Start Game"})]})});const{phase:w,players:$,currentPlayer:N,round:f}=t,C=$[0],h=$[1];return e.jsxs("div",{className:"flex flex-1 flex-col md:flex-row gap-4 md:gap-6 overflow-auto p-4 md:p-6",children:[e.jsxs("div",{className:"flex flex-col gap-4 w-full md:w-80 shrink-0 overflow-y-auto max-h-full pr-1",children:[e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 md:p-5 backdrop-blur-sm",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[e.jsx(pe,{size:14,className:"text-indigo-400"}),e.jsxs("h3",{className:"text-xs md:text-sm font-semibold uppercase tracking-wider text-slate-400",children:["Round ",f]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("div",{className:`rounded-lg p-3 text-center transition-all ${w==="building"&&N===0?"bg-indigo-500/15 ring-2 ring-indigo-400/40":"bg-slate-800/40"}`,children:[e.jsx("p",{className:"text-sm md:text-base font-bold text-indigo-300",children:C.name}),e.jsx("p",{className:"text-lg md:text-xl font-extrabold text-white",children:C.score}),e.jsxs("p",{className:"text-[10px] md:text-xs text-slate-500",children:[C.hand.length,"/",P," tiles"]}),w==="results"&&C.result&&e.jsx("p",{className:`mt-1 text-[10px] md:text-xs font-bold ${C.result.isWin?"text-emerald-400":"text-red-400"}`,children:C.result.isWin?"✓ Winner":"✗ No Win"})]}),e.jsxs("div",{className:`rounded-lg p-3 text-center transition-all ${w==="building"&&N===1?"bg-violet-500/15 ring-2 ring-violet-400/40":"bg-slate-800/40"}`,children:[e.jsx("p",{className:"text-sm md:text-base font-bold text-violet-300",children:h.name}),e.jsx("p",{className:"text-lg md:text-xl font-extrabold text-white",children:h.score}),e.jsxs("p",{className:"text-[10px] md:text-xs text-slate-500",children:[h.hand.length,"/",P," tiles"]}),w==="results"&&h.result&&e.jsx("p",{className:`mt-1 text-[10px] md:text-xs font-bold ${h.result.isWin?"text-emerald-400":"text-red-400"}`,children:h.result.isWin?"✓ Winner":"✗ No Win"})]})]})]}),w==="building"&&e.jsxs("div",{className:`rounded-xl border p-4 md:p-5 backdrop-blur-sm ${N===0?"border-indigo-500/30 bg-indigo-500/5":"border-violet-500/30 bg-violet-500/5"}`,children:[e.jsxs("p",{className:`text-sm md:text-base font-bold ${N===0?"text-indigo-300":"text-violet-300"}`,children:[$[N].name,"'s Turn"]}),e.jsx("p",{className:"text-xs md:text-sm text-slate-400 mt-1",children:"Pick a tile to add to your hand."}),!r&&e.jsxs("button",{onClick:g,className:"mt-3 w-full flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs md:text-sm font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300",children:[e.jsx(Ie,{size:14})," Switch Player"]})]}),w==="building"&&m&&e.jsxs("button",{onClick:o,className:"w-full flex items-center justify-center gap-2 rounded-xl bg-gradient-to-r from-indigo-500/20 to-violet-500/20 px-4 py-3 text-sm md:text-base font-bold text-indigo-200 ring-1 ring-indigo-500/30 transition-all hover:from-indigo-500/30 hover:to-violet-500/30 active:scale-95",children:[e.jsx(Y,{size:16})," Check Both Hands"]}),w==="results"&&k&&e.jsxs("div",{className:`rounded-xl border p-4 md:p-5 backdrop-blur-sm ${k.includes("Neither")?"border-slate-700/50 bg-slate-900/60":"border-emerald-500/30 bg-emerald-500/5"}`,children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsx(Y,{size:18,className:"text-amber-400"}),e.jsx("span",{className:"text-base md:text-lg font-bold text-white",children:k})]}),$.map((d,v)=>d.result&&d.result.isWin&&e.jsxs("div",{className:"mt-2 text-[10px] md:text-xs text-slate-500",children:[e.jsxs("p",{className:"font-semibold text-slate-400",children:[d.name,":"]}),e.jsxs("p",{children:["Pair: ",d.result.pair.join(" ")]}),d.result.melds.map((j,y)=>e.jsxs("p",{children:[j.type==="pong"?"Pong":"Chow",": ",j.tiles.join(" ")]},y))]},v)),e.jsxs("button",{onClick:x,className:"mt-3 w-full flex items-center justify-center gap-2 rounded-lg bg-indigo-500/20 px-4 py-2.5 text-xs md:text-sm font-medium text-indigo-300 ring-1 ring-indigo-500/30 transition-all hover:bg-indigo-500/30",children:["Next Round ",e.jsx(de,{size:14})]})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("button",{onClick:u,className:"flex-1 flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2.5 text-xs md:text-sm font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300",children:[e.jsx(K,{size:14})," Reset"]}),e.jsx("button",{onClick:()=>b(!a),className:`flex items-center justify-center gap-1.5 rounded-lg px-3 py-2.5 text-xs md:text-sm font-medium transition-all ${a?"bg-indigo-500/15 text-indigo-300 ring-1 ring-indigo-500/30":"bg-slate-800/60 text-slate-400"}`,children:a?e.jsx(Q,{size:14}):e.jsx(ee,{size:14})})]}),s&&e.jsx("div",{className:"rounded-lg border border-red-500/30 bg-red-500/5 px-3 py-2.5 text-center text-xs md:text-sm font-medium text-red-400 animate-pulse",children:s})]}),e.jsxs("div",{className:"order-last md:order-first flex md:flex-1 flex-col gap-4 min-h-0 md:overflow-auto",children:[$.map((d,v)=>e.jsxs("div",{className:`rounded-2xl border p-4 shadow-xl backdrop-blur-sm md:p-5 ${w==="building"&&N===v?v===0?"border-indigo-500/30 bg-indigo-500/5":"border-violet-500/30 bg-violet-500/5":"border-emerald-900/40 bg-[radial-gradient(circle_at_top_left,rgba(16,185,129,0.12),transparent_34%),linear-gradient(135deg,rgba(15,23,42,0.96),rgba(6,78,59,0.28))]"}`,children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("h3",{className:`text-xs md:text-sm font-semibold uppercase tracking-wider ${v===0?"text-indigo-400":"text-violet-400"}`,children:d.name}),e.jsxs("span",{className:`text-xs md:text-sm font-mono font-bold ${d.hand.length===P?"text-emerald-400":"text-slate-500"}`,children:[d.hand.length,"/",P]})]}),e.jsxs("div",{className:"flex min-h-[5rem] flex-wrap items-end gap-1.5 rounded-xl border border-emerald-950/40 bg-emerald-950/20 p-3 shadow-inner md:gap-2",children:[d.hand.map((j,y)=>e.jsx(ut,{code:j,onRemove:w==="building"&&N===v?()=>i(y):void 0},`${j}-${y}`)),d.hand.lengthe.jsx(I,{size:"md",placeholder:!0},`e-${y}`))]})]},v)),w==="building"&&!r&&e.jsxs("div",{className:"rounded-2xl border border-slate-700/50 bg-slate-900/70 p-4 shadow-xl shadow-black/20 backdrop-blur-sm md:p-5",children:[e.jsx("h3",{className:"text-xs md:text-sm font-semibold uppercase tracking-wider text-slate-300 mb-3",children:"Tile Wall"}),e.jsx("div",{className:"space-y-3 md:space-y-4",children:B.map(d=>e.jsxs("div",{className:"rounded-xl border border-slate-800/70 bg-slate-950/35 p-3",children:[e.jsx("p",{className:"text-[10px] md:text-xs font-medium mb-1.5",style:{color:Z[d]},children:he[d]}),e.jsx("div",{className:"flex flex-wrap items-end gap-1 md:gap-1.5",children:O.map(v=>{const j=`${d}${v}`;return e.jsx(pt,{suit:d,value:v,count:gt(l,j),disabled:r,onClick:()=>T(j)},j)})})]},d))})]})]})]})}function ft(){const[t,s]=c.useState([]),[n,a]=c.useState(null),[l,r]=c.useState([]),[m,k]=c.useState(-1),[p,T]=c.useState(!1),[i,o]=c.useState(400),[x,u]=c.useState(null),[g,b]=c.useState(!1),[w,$]=c.useState(!0),N=c.useRef(null),f=te();c.useEffect(()=>()=>{N.current&&clearInterval(N.current)},[]);const C=c.useCallback(()=>{a(null),r([]),k(-1),T(!1),N.current&&(clearInterval(N.current),N.current=null)},[]),h=c.useCallback(_=>{s(A=>{const R=be(A,_);return R?(u(R),f.playErrorSound(),A):(u(null),C(),f.playTilePlaced(fe(_).value),L([...A,_]))})},[C,f]),d=c.useCallback(_=>{s(A=>{const R=[...A];return R.splice(_,1),C(),f.playTileRemoved(),R}),u(null)},[C,f]),v=c.useCallback(()=>{s([]),u(null),C()},[C]),j=c.useCallback(()=>{s(D()),u(null),C()},[C]),y=c.useCallback(()=>{s(ce()),u(null),C()},[C]),W=c.useCallback(()=>{const _=st(t);if(_){u(_),f.playErrorSound();return}if(u(null),g){const{result:A,steps:R}=at(t);a(A),r(R),k(-1)}else{const A=G(t);a(A),r([]),k(-1),A.isWin?f.playWinSound():f.playLoseSound()}},[t,g,f]),S=c.useCallback(()=>{k(_=>{const A=Math.min(_+1,l.length-1);if(A>=0&&A{k(_=>Math.max(_-1,-1))},[]),z=c.useCallback(()=>{if(p){N.current&&(clearInterval(N.current),N.current=null),T(!1);return}T(!0),k(_=>_>=l.length-1?-1:_),N.current=setInterval(()=>{k(_=>{if(_>=l.length-1)return N.current&&clearInterval(N.current),N.current=null,T(!1),_;const A=_+1;if(A{b(_=>!_),C()},[C]),se=c.useCallback(_=>{$(_),f.setEnabled(_)},[f]),Ne=m>=0&&m=P,soundEnabled:w,addTile:h,removeTile:d,resetHand:v,randomHand:j,winningHand:y,checkHand:W,stepForward:S,stepBack:M,autoPlay:z,setAnimSpeed:o,toggleAnimation:H,toggleSound:se}}const bt={sandbox:e.jsx(Le,{size:14}),guided:e.jsx(ze,{size:14}),challenge:e.jsx(Ee,{size:14}),"two-player":e.jsx(pe,{size:14})},jt=["sandbox","guided","challenge","two-player"];function yt(){const{hand:t,result:s,steps:n,stepIndex:a,stepsTotal:l,currentStep:r,isAnimating:m,animSpeed:k,showAnimation:p,lastError:T,handIsFull:i,addTile:o,removeTile:x,resetHand:u,randomHand:g,winningHand:b,checkHand:w,stepForward:$,stepBack:N,autoPlay:f,setAnimSpeed:C,toggleAnimation:h,soundEnabled:d,toggleSound:v}=ft();return e.jsxs("div",{className:"flex flex-1 flex-col md:flex-row gap-4 md:gap-6 overflow-auto bg-[radial-gradient(circle_at_top,rgba(16,185,129,0.08),transparent_34%),linear-gradient(180deg,rgba(15,23,42,0),rgba(6,78,59,0.16))] p-4 md:p-6",children:[e.jsx(et,{handIsFull:i,result:s,showAnimation:p,steps:n,stepIndex:a,stepsTotal:l,isAnimating:m,animSpeed:k,currentStep:r,lastError:T,onCheckHand:w,onResetHand:u,onRandomHand:g,onWinningHand:b,onToggleAnimation:h,onStepForward:$,onStepBack:N,onAutoPlay:f,onSetAnimSpeed:C,soundEnabled:d,onToggleSound:v}),e.jsxs("div",{className:"order-last md:order-first flex md:flex-1 flex-col gap-4 min-h-0 md:min-h-0 md:overflow-auto",children:[e.jsx(Ze,{hand:t,onRemoveTile:x}),s&&e.jsx(Ke,{result:s}),e.jsx(Ye,{hand:t,handIsFull:i,onAddTile:o})]})]})}function zt(){const[t,s]=c.useState("sandbox");return e.jsxs("div",{className:"flex flex-1 flex-col overflow-hidden",children:[e.jsx("div",{className:"shrink-0 border-b border-emerald-900/40 bg-[linear-gradient(135deg,rgba(15,23,42,0.9),rgba(6,78,59,0.34))] backdrop-blur-sm px-4 md:px-6 pt-3 pb-0",children:e.jsx("div",{className:"flex gap-1 overflow-x-auto",children:jt.map(n=>e.jsxs("button",{onClick:()=>s(n),className:`flex items-center gap-1.5 rounded-t-lg px-4 py-2.5 text-xs md:text-sm font-medium transition-all whitespace-nowrap ${t===n?"bg-slate-800/80 text-indigo-300 border border-b-0 border-slate-700/50 -mb-px":"text-slate-500 hover:text-slate-300 hover:bg-slate-800/30"}`,children:[bt[n],e.jsx("span",{children:De[n].label})]},n))})}),e.jsxs("div",{className:"flex flex-1 overflow-hidden",children:[t==="sandbox"&&e.jsx(yt,{}),t==="guided"&&e.jsx(ot,{}),t==="challenge"&&e.jsx(xt,{}),t==="two-player"&&e.jsx(ht,{})]})]})}export{zt as default}; diff --git a/docs/assets/QueuePage-Dm9bXwaQ.js b/docs/assets/QueuePage-Dm9bXwaQ.js new file mode 100644 index 0000000..34a580b --- /dev/null +++ b/docs/assets/QueuePage-Dm9bXwaQ.js @@ -0,0 +1,5 @@ +import{r as l,j as e,E as W}from"./index-BfWfBQOp.js";import{u as _}from"./useDSSound-BMrOIkPj.js";import{P as K}from"./plus-BEk43_MF.js";import{T as U}from"./trash-2-RJG3j28z.js";import{R as X}from"./rotate-ccw-EKzY5q_W.js";import{S as B}from"./shuffle-Ri9xSsK2.js";import{V as J,a as Y}from"./volume-x-ChIHiT28.js";import{C as Z,a as ee}from"./chevron-right-CNA9GG_w.js";import"./audioContext-NbgqvQGz.js";let I=1;const te=[{id:I++,value:5},{id:I++,value:12},{id:I++,value:8}];function se(){const[r,d]=l.useState(te),[n,m]=l.useState([]),[i,o]=l.useState(-1),[x,y]=l.useState(""),[p,b]=l.useState([]),[h,P]=l.useState(400),[w,j]=l.useState(!1),u=l.useRef(null),k=l.useRef(h),v=l.useRef(!1),{soundEnabled:$,toggleSound:z,playInsert:g,playDelete:N,playAccess:C,playTraverse:q}=_(),a=l.useRef(()=>{});l.useEffect(()=>{k.current=h},[h]),l.useEffect(()=>{if(!v.current||n.length===0)return;v.current=!1,u.current&&clearTimeout(u.current),j(!0);let t=0;const s=()=>{if(t>=n.length-1){j(!1);return}t++,o(t),a.current(t,n),u.current=setTimeout(s,k.current)};u.current=setTimeout(s,k.current)},[n]);const f=l.useCallback((t,s)=>{const c=s[t];c&&(c.highlightColor==="green"?g():c.highlightColor==="red"?N():c.highlightColor==="yellow"&&q(t,s.length))},[g,N,q]);l.useEffect(()=>{a.current=f},[f]);const Q=i>=0&&n[i]?n[i].queue:r,F=i>=0?n[i]:null,S=t=>b(s=>[t,...s].slice(0,20)),T=l.useCallback(t=>{const s={id:I++,value:t};d(c=>{const E=[...c,s],L=[{description:`Enqueuing ${t} at the rear of the queue...`,queue:c,highlightIndex:null,highlightColor:null},{description:`${t} added to the rear. Queue size: ${E.length}`,queue:E,highlightIndex:E.length-1,highlightColor:"green"}];return m(L),o(0),v.current=!0,g(),S(`Enqueue ${t}`),E})},[g]),O=l.useCallback(()=>{d(t=>{if(t.length===0)return t;const s=t[0],c=[{description:`Dequeue: checking front element ${s.value}...`,queue:t,highlightIndex:0,highlightColor:"yellow"},{description:`Removing ${s.value} from the front.`,queue:t,highlightIndex:0,highlightColor:"red"},{description:`${s.value} removed. Queue size: ${t.length-1}`,queue:t.slice(1),highlightIndex:null,highlightColor:null}];return m(c),o(0),v.current=!0,N(),S(`Dequeue → ${s.value}`),t.slice(1)})},[N]),D=l.useCallback(()=>{d(t=>{if(t.length===0)return t;const s=t[0],c=[{description:"Peek front: reading without removing.",queue:t,highlightIndex:0,highlightColor:"yellow"},{description:`Front element is ${s.value}.`,queue:t,highlightIndex:0,highlightColor:"yellow"}];return m(c),o(0),v.current=!0,C(),S(`Peek → ${s.value}`),t})},[C]),M=l.useCallback(()=>{d([]),m([]),o(-1),S("Clear queue")},[]),V=l.useCallback(()=>{const t=Math.floor(Math.random()*4)+3,s=Array.from({length:t},()=>({id:I++,value:Math.floor(Math.random()*90)+1}));d(s),m([]),o(-1),S("Random queue")},[]),H=l.useCallback(()=>{o(t=>{const s=Math.min(t+1,n.length-1);return f(s,n),s})},[n,f]),A=l.useCallback(()=>{o(t=>Math.max(t-1,0))},[]),G=l.useCallback(()=>{if(w){j(!1),u.current&&clearTimeout(u.current);return}j(!0);let t=i;const s=()=>{if(t>=n.length-1){j(!1);return}t++,o(t),f(t,n),u.current=setTimeout(s,h)};u.current=setTimeout(s,h)},[w,i,n,h,f]);return{queue:r,displayQueue:Q,steps:n,stepIndex:i,currentStep:F,inputValue:x,setInputValue:y,history:p,speed:h,setSpeed:P,isPlaying:w,enqueue:T,dequeue:O,peekFront:D,clear:M,generateRandom:V,nextStep:H,prevStep:A,autoPlay:G,soundEnabled:$,toggleSound:z,canGoNext:i0}}const le={green:"border-emerald-400 bg-emerald-500/20 text-emerald-300",red:"border-rose-400 bg-rose-500/20 text-rose-300",yellow:"border-amber-400 bg-amber-500/20 text-amber-300"},R=8;function ae({queue:r,currentStep:d}){const n=r.slice(0,R),m=d?.highlightIndex??null,i=d?.highlightColor??null;return e.jsxs("div",{className:"flex flex-col items-center justify-center w-full h-full min-h-[300px] gap-6 px-4",children:[e.jsxs("div",{className:"flex flex-col items-center gap-3 w-full",children:[e.jsx("div",{className:"flex items-center gap-1.5 w-full justify-center",children:r.length>0&&e.jsxs("div",{className:"flex items-end gap-1.5 flex-wrap justify-center",children:[n.map((o,x)=>{const y=x===m,p=x===0,b=x===r.length-1&&xR&&e.jsxs("div",{className:"flex flex-col items-center gap-1",children:[e.jsx("div",{className:"h-4"}),e.jsx("div",{className:"h-3"}),e.jsxs("div",{className:"flex items-center justify-center rounded-lg border-2 border-dashed border-slate-700 w-14 h-14 text-slate-600 text-xs",children:["+",r.length-R]}),e.jsx("span",{className:"text-[10px] font-mono text-slate-600",children:"..."})]})]})}),r.length>0&&e.jsxs("div",{className:"flex items-center gap-4 text-xs text-slate-500",children:[e.jsx("span",{className:"text-indigo-400 font-mono",children:"dequeue ←"}),e.jsx("div",{className:"flex-1 border-t border-dashed border-slate-700"}),e.jsx("span",{className:"text-violet-400 font-mono",children:"→ enqueue"})]}),r.length===0&&e.jsx("div",{className:"flex items-center justify-center w-48 h-16 border-2 border-dashed border-slate-700 rounded-lg text-slate-600 text-xs",children:"Empty Queue"})]}),d?.description&&e.jsx("div",{className:"w-full max-w-sm rounded-lg bg-slate-800/60 px-4 py-2 text-center text-xs text-indigo-300 leading-relaxed",children:d.description}),e.jsxs("div",{className:"text-xs text-slate-500 font-mono",children:["size = ",r.length]})]})}const ne=[{label:"Slow",value:700},{label:"Med",value:350},{label:"Fast",value:120}];function re({hook:r}){const{queue:d,steps:n,stepIndex:m,inputValue:i,setInputValue:o,history:x,speed:y,setSpeed:p,isPlaying:b,enqueue:h,dequeue:P,peekFront:w,clear:j,generateRandom:u,nextStep:k,prevStep:v,canGoNext:$,canGoPrev:z,soundEnabled:g,toggleSound:N}=r,C=()=>{const a=parseInt(i);isNaN(a)||(h(a),o(""))},q=a=>{a.key==="Enter"&&C()};return e.jsxs("div",{className:"flex flex-col gap-4 w-full md:w-72 shrink-0 overflow-y-auto max-h-full pr-1",children:[e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-sm font-bold text-indigo-300 mb-1",children:"Queue"}),e.jsxs("p",{className:"text-xs text-slate-400 leading-relaxed",children:["A ",e.jsx("strong",{className:"text-slate-300",children:"FIFO"})," (First In, First Out) structure. Elements are added at the ",e.jsx("strong",{className:"text-slate-300",children:"rear"})," and removed from the ",e.jsx("strong",{className:"text-slate-300",children:"front"}),"."]}),e.jsx("div",{className:"mt-2 flex flex-wrap gap-1.5",children:["FIFO","Enqueue O(1)","Dequeue O(1)","Peek O(1)"].map(a=>e.jsx("span",{className:"rounded-full bg-violet-500/10 px-2 py-0.5 text-[10px] font-medium text-violet-400 ring-1 ring-violet-500/20",children:a},a))})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Operations"}),e.jsx("input",{type:"number",value:i,onChange:a=>o(a.target.value),onKeyDown:q,placeholder:"Enter value...",className:"w-full rounded-lg bg-slate-800/60 px-3 py-2 text-sm text-slate-200 placeholder-slate-600 outline-none ring-1 ring-slate-700/50 focus:ring-indigo-500/50 transition-all"}),e.jsxs("div",{className:"mt-3 grid grid-cols-2 gap-2",children:[e.jsxs("button",{onClick:C,className:"flex items-center justify-center gap-1.5 rounded-lg bg-gradient-to-r from-emerald-500/80 to-green-500/80 px-3 py-2 text-xs font-semibold text-white shadow-lg shadow-emerald-500/15 transition-all hover:brightness-110 active:scale-[0.98]",children:[e.jsx(K,{size:14})," Enqueue"]}),e.jsxs("button",{onClick:P,disabled:d.length===0,className:"flex items-center justify-center gap-1.5 rounded-lg bg-gradient-to-r from-rose-500/80 to-pink-500/80 px-3 py-2 text-xs font-semibold text-white shadow-lg shadow-rose-500/15 transition-all hover:brightness-110 active:scale-[0.98] disabled:opacity-40 disabled:cursor-not-allowed",children:[e.jsx(U,{size:14})," Dequeue"]}),e.jsxs("button",{onClick:w,disabled:d.length===0,className:"flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-amber-300 transition-all hover:bg-slate-700/60 disabled:opacity-40 disabled:cursor-not-allowed",children:[e.jsx(W,{size:14})," Peek Front"]}),e.jsxs("button",{onClick:j,disabled:d.length===0,className:"flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-slate-400 transition-all hover:bg-slate-700/60 disabled:opacity-40 disabled:cursor-not-allowed",children:[e.jsx(X,{size:14})," Clear"]})]}),e.jsxs("button",{onClick:u,className:"mt-2 w-full flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300",children:[e.jsx(B,{size:12})," Random Queue"]}),e.jsxs("button",{onClick:()=>N(!g),className:`mt-2 w-full flex items-center justify-center gap-1.5 rounded-lg px-3 py-2 text-xs font-medium transition-all ${g?"bg-indigo-500/15 text-indigo-300 ring-1 ring-indigo-500/30":"bg-slate-800/60 text-slate-400 hover:bg-slate-700/60"}`,children:[g?e.jsx(J,{size:12}):e.jsx(Y,{size:12}),g?"Sound On":"Sound Off"]})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Animation Speed"}),e.jsx("div",{className:"flex gap-1",children:ne.map(a=>e.jsx("button",{onClick:()=>p(a.value),className:`flex-1 rounded-lg px-2 py-1.5 text-xs font-medium transition-all duration-200 ${y===a.value?"bg-violet-500/20 text-violet-300 ring-1 ring-violet-500/40":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50 hover:text-slate-300"}`,children:a.label},a.value))})]}),n.length>0&&e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Step Through"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("button",{onClick:v,disabled:!z||b,className:"flex-1 flex items-center justify-center gap-1 rounded-lg bg-slate-800/60 px-3 py-2.5 text-sm font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300 disabled:opacity-30 disabled:cursor-not-allowed",children:[e.jsx(Z,{size:16})," Prev"]}),e.jsxs("button",{onClick:k,disabled:!$||b,className:"flex-1 flex items-center justify-center gap-1 rounded-lg bg-slate-800/60 px-3 py-2.5 text-sm font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300 disabled:opacity-30 disabled:cursor-not-allowed",children:["Next ",e.jsx(ee,{size:16})]})]}),e.jsxs("div",{className:"mt-2 flex items-center justify-between",children:[e.jsx("span",{className:"text-xs text-slate-500",children:"Step"}),e.jsxs("span",{className:"text-sm font-mono font-semibold text-indigo-400",children:[Math.max(0,m+1)," / ",n.length]})]})]}),x.length>0&&e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"History"}),e.jsx("div",{className:"max-h-36 overflow-y-auto space-y-1",children:x.map((a,f)=>e.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[e.jsx("span",{className:"font-mono text-slate-600 w-4 text-right",children:f+1}),e.jsx("span",{className:a.startsWith("Enqueue")?"text-emerald-400":a.startsWith("Dequeue")?"text-rose-400":a.startsWith("Peek")?"text-amber-400":"text-slate-400",children:a})]},f))})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Legend"}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-emerald-500"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Enqueue (rear)"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-rose-500"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Dequeue (front)"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-amber-400"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Peek"})]})]})]})]})}function fe(){const r=se();return e.jsxs("div",{className:"flex flex-1 flex-col md:flex-row gap-4 md:gap-6 overflow-auto p-4 md:p-6",children:[e.jsx("div",{className:"order-last md:order-first flex md:flex-1 flex-col items-center justify-center gap-3 min-h-[40vh] md:min-h-0 max-h-[55vh] md:max-h-none overflow-hidden",children:e.jsx(ae,{queue:r.displayQueue,currentStep:r.currentStep})}),e.jsx(re,{hook:r})]})}export{fe as default}; diff --git a/docs/assets/RubiksCubeGamePage-DGHevFh5.js b/docs/assets/RubiksCubeGamePage-DGHevFh5.js new file mode 100644 index 0000000..533bb0e --- /dev/null +++ b/docs/assets/RubiksCubeGamePage-DGHevFh5.js @@ -0,0 +1 @@ +import{c as Oe,r as o,j as e,h as ze}from"./index-BfWfBQOp.js";import{S as xe}from"./shuffle-Ri9xSsK2.js";import{S as pe,B as Ve}from"./skip-forward-DUFQw-PC.js";import{R as _e}from"./rotate-ccw-EKzY5q_W.js";import{V as Ge,a as Xe}from"./volume-x-ChIHiT28.js";import{g as Ye}from"./audioContext-NbgqvQGz.js";import{T as qe}from"./trophy-CUioHXrM.js";const We=[["path",{d:"m21.64 3.64-1.28-1.28a1.21 1.21 0 0 0-1.72 0L2.36 18.64a1.21 1.21 0 0 0 0 1.72l1.28 1.28a1.2 1.2 0 0 0 1.72 0L21.64 5.36a1.2 1.2 0 0 0 0-1.72",key:"ul74o6"}],["path",{d:"m14 7 3 3",key:"1r5n42"}],["path",{d:"M5 6v4",key:"ilb8ba"}],["path",{d:"M19 14v4",key:"blhpug"}],["path",{d:"M10 2v2",key:"7u0qdc"}],["path",{d:"M7 8H3",key:"zfb6yr"}],["path",{d:"M21 16h-4",key:"1cnmox"}],["path",{d:"M11 3H9",key:"1obp7u"}]],ge=Oe("wand-sparkles",We),z=[{id:"slow",label:"Slow",delayMs:900},{id:"normal",label:"Normal",delayMs:450},{id:"fast",label:"Fast",delayMs:160}],Ze={U:"Up",D:"Down",F:"Front",B:"Back",L:"Left",R:"Right"},He={white:"#f8fafc",yellow:"#facc15",green:"#22c55e",blue:"#3b82f6",orange:"#f97316",red:"#ef4444"},ce=["U","U'","U2","D","D'","D2","F","F'","F2","B","B'","B2","L","L'","L2","R","R'","R2"],Ke={F:"translateZ(72px)",B:"rotateY(180deg) translateZ(72px)",R:"rotateY(90deg) translateZ(72px)",L:"rotateY(-90deg) translateZ(72px)",U:"rotateX(90deg) translateZ(72px)",D:"rotateX(-90deg) translateZ(72px)"},Qe=["F","R","U","L","D","B"],be={x:-24,y:38},ee=18;function Je({cube:t,solved:s,onMove:a}){const[l,r]=o.useState(be),[c,S]=o.useState(null),d=o.useCallback((i,C)=>{r(h=>({x:he(h.x+i),y:h.y+C}))},[]),x=o.useCallback(()=>{r(be)},[]),f=o.useCallback(i=>{i.currentTarget.setPointerCapture(i.pointerId),S({pointerId:i.pointerId,startX:i.clientX,startY:i.clientY,rotation:l})},[l]),v=o.useCallback(i=>{if(!c||c.pointerId!==i.pointerId)return;const C=i.clientX-c.startX,h=i.clientY-c.startY;r({x:he(c.rotation.x-h*.35),y:c.rotation.y+C*.35})},[c]),p=o.useCallback(i=>{!c||c.pointerId!==i.pointerId||(i.currentTarget.hasPointerCapture(i.pointerId)&&i.currentTarget.releasePointerCapture(i.pointerId),S(null))},[c]);return e.jsxs("div",{className:"rounded-2xl border border-slate-700/50 bg-slate-900/60 p-4 md:p-5 backdrop-blur-sm",children:[e.jsxs("div",{className:"mb-4 flex items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-bold text-white",children:"Cube State"}),e.jsx("p",{className:"text-[11px] text-slate-500",children:"Drag the 3D cube to rotate the view"})]}),e.jsx("span",{className:`rounded-full px-2.5 py-1 text-[10px] font-semibold ring-1 ${s?"bg-emerald-500/15 text-emerald-300 ring-emerald-500/30":"bg-amber-500/15 text-amber-300 ring-amber-500/30"}`,children:s?"Solved":"Scrambled"})]}),e.jsx("div",{className:"flex min-h-[290px] touch-none cursor-grab items-center justify-center overflow-hidden rounded-xl bg-slate-950/40 ring-1 ring-slate-800/60 active:cursor-grabbing",role:"img","aria-label":"Interactive 3D Rubik's Cube view. Drag to rotate the cube.",onPointerDown:f,onPointerMove:v,onPointerUp:p,onPointerCancel:p,children:e.jsxs("div",{className:"relative h-56 w-56",style:{perspective:"900px"},children:[e.jsx("div",{className:`absolute left-1/2 top-1/2 h-36 w-36 ${c?"":"transition-transform duration-500"}`,style:{transformStyle:"preserve-3d",transform:`translate(-50%, -50%) rotateX(${l.x}deg) rotateY(${l.y}deg) rotateZ(0deg)`},children:Qe.map(i=>e.jsxs("div",{className:"absolute left-0 top-0 grid h-36 w-36 grid-cols-3 gap-1 rounded-xl border border-slate-950/70 bg-slate-950/90 p-1.5 shadow-2xl",style:{transform:Ke[i],backfaceVisibility:"hidden"},"aria-label":`${Ze[i]} face`,children:[t[i].map((C,h)=>e.jsx("div",{className:"rounded-md border border-slate-950/50 shadow-inner transition-colors duration-300",style:{backgroundColor:He[C]}},`${i}-${h}`)),e.jsx("span",{className:"pointer-events-none absolute left-2 top-1 text-[10px] font-black text-slate-950/50",children:i})]},i))}),e.jsx("div",{className:"absolute bottom-2 left-1/2 h-8 w-40 -translate-x-1/2 rounded-full bg-black/30 blur-xl"})]})}),e.jsxs("div",{className:"mt-3 flex flex-wrap items-center justify-between gap-2",children:[e.jsxs("span",{className:"text-[10px] text-slate-500",children:["View angle: X ",Math.round(l.x),"deg / Y ",Math.round(l.y),"deg"]}),e.jsxs("div",{className:"flex flex-wrap gap-1.5",children:[e.jsx(W,{label:"Up",onClick:()=>d(-ee,0)}),e.jsx(W,{label:"Down",onClick:()=>d(ee,0)}),e.jsx(W,{label:"Left",onClick:()=>d(0,-ee)}),e.jsx(W,{label:"Right",onClick:()=>d(0,ee)}),e.jsx(W,{label:"Reset View",onClick:x})]})]}),e.jsxs("div",{className:"mt-5",children:[e.jsxs("div",{className:"mb-2 flex items-center justify-between",children:[e.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-wider text-slate-500",children:"Quick Turns"}),e.jsx("span",{className:"text-[10px] text-slate-600",children:"Clockwise / inverse / double"})]}),e.jsx("div",{className:"grid grid-cols-6 gap-1.5 sm:grid-cols-9",children:ce.map(i=>e.jsx("button",{onClick:()=>a(i),className:"rounded-lg bg-slate-800/70 px-2 py-1.5 text-[11px] font-semibold text-slate-300 ring-1 ring-slate-700/40 transition-all hover:bg-indigo-500/15 hover:text-indigo-300 hover:ring-indigo-500/30",children:i},i))})]})]})}function he(t){return Math.max(-75,Math.min(75,t))}function W({label:t,onClick:s}){return e.jsx("button",{onClick:s,className:"rounded-md bg-slate-800/70 px-2 py-1 text-[10px] font-semibold text-slate-400 ring-1 ring-slate-700/40 transition-all hover:bg-indigo-500/15 hover:text-indigo-300 hover:ring-indigo-500/30",children:t})}const et=o.memo(Je),tt={U:"white",D:"yellow",F:"green",B:"blue",L:"orange",R:"red"},de=["U","D","F","B","L","R"],st={U:[["F",[0,1,2]],["R",[0,1,2]],["B",[0,1,2]],["L",[0,1,2]]],D:[["F",[6,7,8]],["L",[6,7,8]],["B",[6,7,8]],["R",[6,7,8]]],F:[["U",[6,7,8]],["R",[0,3,6]],["D",[2,1,0]],["L",[8,5,2]]],B:[["U",[2,1,0]],["L",[0,3,6]],["D",[6,7,8]],["R",[8,5,2]]],L:[["U",[0,3,6]],["F",[0,3,6]],["D",[0,3,6]],["B",[8,5,2]]],R:[["U",[8,5,2]],["B",[0,3,6]],["D",[8,5,2]],["F",[8,5,2]]]};function U(){return de.reduce((t,s)=>(t[s]=Array(9).fill(tt[s]),t),{})}function ke(t){return de.reduce((s,a)=>(s[a]=[...t[a]],s),{})}function te(t){return de.every(s=>t[s].every(a=>a===t[s][4]))}function Z(t,s){return s.reduce((a,l)=>se(a,l),t)}function se(t,s){const a=s[0],l=s.endsWith("2")?2:s.endsWith("'")?3:1;let r=ke(t);for(let c=0;c{const r=ct(l,s.length);return{move:a,phase:r,description:`${r}: apply ${a} as part of the inverse solve sequence.`}})}function at(t,s){const a=ke(t);a[s]=ot(t[s]);const l=st[s],r=l.map(([c,S])=>S.map(d=>t[c][d]));return l.forEach(([c,S],d)=>{const x=r[(d+l.length-1)%l.length];S.forEach((f,v)=>{a[c][f]=x[v]})}),a}function ot(t){return[t[6],t[3],t[0],t[7],t[4],t[1],t[8],t[5],t[2]]}function rt(t){const s=[];for(const a of t){const l=s[s.length-1];if(!l||l[0]!==a[0]){s.push(a);continue}const r=(ve(l)+ve(a))%4;s.pop(),r!==0&&s.push(it(a[0],r))}return s}function ve(t){return t.endsWith("2")?2:t.endsWith("'")?3:1}function it(t,s){return s===2?`${t}2`:s===3?`${t}'`:t}function ct(t,s){if(s<=4)return["Cross","F2L","2-Look OLL","2-Look PLL"][t%4];const a=t/s;return a<.25?"Cross":a<.62?"F2L":a<.82?"2-Look OLL":"2-Look PLL"}const dt=["U","D","F","B","L","R"],fe=[{id:"starter-cross",title:"Starter Scramble",description:"A short scramble for practicing move notation and inverse solving.",scramble:["R","U","R'","U'"],targetMoves:4},{id:"six-move",title:"Six Move Sprint",description:"Solve a slightly longer scramble with clean inverse turns.",scramble:["F","R","U","R'","U'","F'"],targetMoves:6},{id:"middle-layer",title:"Middle Layer Drill",description:"A medium scramble that touches side faces and top-layer turns.",scramble:["L","U2","F","R'","D","B2","L'"],targetMoves:7},{id:"full-cube",title:"Full Cube Challenge",description:"A longer scramble that rewards using the solver and reading move notation.",scramble:["R","U","F2","L'","D","B","R2","U'","F","D'"],targetMoves:10}];function Ne(t){const s=[];let a="";for(;s.length0?t.join(" "):"None"}function we(t){const s=t.trim().toUpperCase().replace("’","'").replace(/I$/,"'");if(!s)return null;const a=s[0],l=s.slice(1);return!dt.includes(a)||l!==""&&l!=="'"&&l!=="2"?null:`${a}${l}`}function ut(t){const s=t.split(/[\s,]+/).map(l=>l.trim()).filter(Boolean);if(s.length===0)return null;const a=s.map(we);return a.some(l=>l===null)?null:a}function mt(t,s=25){const a=Math.max(1,Math.min(t,100)),l=Array.from({length:a},()=>{const d=Ne(s);return{scramble:d,solutionLength:le(d).length}}),r=l.reduce((d,x)=>x.solutionLengthx.solutionLength>d.solutionLength?x:d,l[0]),S=l.reduce((d,x)=>d+x.solutionLength,0)/l.length;return{runs:a,best:r,worst:c,averageLength:S}}function xt({mode:t,message:s,moveHistory:a,scrambleMoves:l,solution:r,solutionIndex:c,solutionDone:S,solverPlaybackMode:d,solverSpeed:x,manualMove:f,customScramble:v,simulationRuns:p,simulationResult:i,guidedStep:C,guidedScript:h,challenges:w,selectedChallenge:k,challengeStarted:ne,challengeMoves:H,challengeSolved:N,soundEnabled:V,onManualMoveChange:g,onCustomScrambleChange:ae,onSimulationRunsChange:j,onApplyManualMove:K,onScramble:Q,onApplyCustomScramble:$,onSimulateSolves:G,onGenerateSolution:_,onStepSolution:J,onAutoSolve:D,onSolverSpeedChange:A,onUndo:oe,onReset:L,onNextGuidedStep:X,onSelectChallenge:F,onStartChallenge:M,onToggleSound:Y}){const u=Math.max(0,z.findIndex(b=>b.id===x)),re=z[u]??z[1];return e.jsxs("aside",{className:"w-full space-y-4 md:w-80 md:shrink-0",children:[e.jsxs(B,{title:"Status",children:[e.jsx("p",{className:"text-xs leading-relaxed text-slate-300",children:s}),e.jsxs("div",{className:"mt-3 grid grid-cols-2 gap-2",children:[e.jsx(O,{label:"Moves",value:a.length}),e.jsx(O,{label:"Solution",value:r.length>0?`${c}/${r.length}`:"-"})]})]}),t==="guided"&&e.jsxs(B,{title:"Guided Mode",children:[e.jsx("p",{className:"text-[11px] leading-relaxed text-slate-400",children:"Learn notation, scrambling, and CFOP-inspired phase labels step by step."}),e.jsx("p",{className:"mt-2 text-[10px] leading-relaxed text-slate-500",children:"Reference style: Cross → F2L → 2-Look OLL → 2-Look PLL."}),e.jsxs("div",{className:"mt-3 rounded-xl border border-amber-500/20 bg-amber-500/5 p-3",children:[e.jsxs("div",{className:"text-[10px] font-semibold uppercase tracking-wider text-amber-300",children:["Step ",C+1," / ",h.length]}),e.jsx("p",{className:"mt-1 text-xs leading-relaxed text-slate-300",children:h[C]})]}),e.jsx("button",{onClick:X,className:"mt-3 w-full rounded-lg bg-amber-500/20 px-3 py-2 text-xs font-semibold text-amber-300 ring-1 ring-amber-500/40 hover:bg-amber-500/30",children:"Continue Guided Step"})]}),t==="freeplay"&&e.jsxs(B,{title:"Freeplay Mode",children:[e.jsx(je,{value:f,onChange:g,onApply:K}),e.jsxs("div",{className:"mt-3",children:[e.jsx("label",{className:"text-[11px] text-slate-400",children:"Custom scramble"}),e.jsx("textarea",{value:v,onChange:b=>ae(b.target.value),rows:2,placeholder:"R U R' U' or Ri U R U2",className:"mt-1 w-full resize-none rounded-lg bg-slate-950/70 px-3 py-2 text-xs font-mono text-slate-200 ring-1 ring-slate-700/50 outline-none focus:ring-cyan-500/50"}),e.jsx("button",{onClick:$,className:"mt-2 w-full rounded-lg bg-violet-500/20 px-3 py-2 text-xs font-semibold text-violet-300 ring-1 ring-violet-500/40 hover:bg-violet-500/30",children:"Apply Custom Scramble"})]}),e.jsxs("div",{className:"mt-3 grid grid-cols-2 gap-2",children:[e.jsx(T,{onClick:()=>Q(12),icon:e.jsx(xe,{size:13}),label:"12-Move Scramble"}),e.jsx(T,{onClick:()=>Q(25),icon:e.jsx(xe,{size:13}),label:"25-Move Scramble"}),e.jsx(T,{onClick:_,icon:e.jsx(ge,{size:13}),label:"Find Solution"}),e.jsx(T,{onClick:D,icon:e.jsx(pe,{size:13}),label:"Auto Run"}),e.jsx(T,{onClick:oe,label:"Undo"}),e.jsx(T,{onClick:L,icon:e.jsx(_e,{size:13}),label:"Reset"})]}),e.jsxs("div",{className:"mt-3 rounded-xl border border-slate-700/40 bg-slate-950/40 p-3",children:[e.jsx("label",{className:"text-[11px] text-slate-400",children:"Simulation runs"}),e.jsxs("div",{className:"mt-1 flex gap-2",children:[e.jsx("input",{type:"number",min:1,max:100,value:p,onChange:b=>j(Number(b.target.value)||1),className:"min-w-0 flex-1 rounded-lg bg-slate-950/70 px-3 py-2 text-sm font-mono text-slate-200 ring-1 ring-slate-700/50"}),e.jsx("button",{onClick:G,className:"rounded-lg bg-slate-800/70 px-3 py-2 text-xs font-semibold text-slate-300 ring-1 ring-slate-700/50 hover:bg-slate-700/70",children:"Run"})]})]})]}),t==="challenge"&&e.jsxs(B,{title:"Challenge Mode",children:[e.jsx("div",{className:"space-y-2",children:w.map(b=>e.jsxs("button",{onClick:()=>F(b),className:`w-full rounded-lg px-3 py-2 text-left ring-1 transition-all ${k.id===b.id?"bg-rose-500/15 text-rose-200 ring-rose-500/40":"bg-slate-800/50 text-slate-400 ring-slate-700/40 hover:bg-slate-700/50"}`,children:[e.jsx("div",{className:"text-xs font-semibold",children:b.title}),e.jsx("div",{className:"mt-0.5 text-[10px] text-slate-500",children:b.description})]},b.id))}),e.jsx("button",{onClick:()=>M(k),className:"mt-3 w-full rounded-lg bg-rose-500/20 px-3 py-2 text-xs font-semibold text-rose-300 ring-1 ring-rose-500/40 hover:bg-rose-500/30",children:"Start Challenge"}),ne&&e.jsxs("div",{className:"mt-3 space-y-3",children:[e.jsx(je,{value:f,onChange:g,onApply:K}),e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsx(O,{label:"Your Moves",value:H}),e.jsx(O,{label:"Target",value:k.targetMoves})]}),N&&e.jsxs("div",{className:"rounded-lg bg-emerald-500/10 px-3 py-2 text-xs text-emerald-300 ring-1 ring-emerald-500/30",children:["Solved in ",H," moves."]})]})]}),e.jsxs(B,{title:"Solver",children:[e.jsxs("div",{className:"space-y-2 text-[11px] text-slate-400",children:[e.jsxs("p",{children:[e.jsx("span",{className:"text-slate-500",children:"Scramble:"})," ",R(l)]}),e.jsxs("p",{children:[e.jsx("span",{className:"text-slate-500",children:"History:"})," ",R(a.slice(-12))]})]}),e.jsxs("div",{className:"mt-3 rounded-xl border border-slate-700/40 bg-slate-950/40 p-3",children:[e.jsxs("div",{className:"mb-2 flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-wider text-slate-500",children:"Playback"}),e.jsx("span",{className:"text-[10px] text-slate-500",children:re.label})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsx(Se,{label:"Manual Step",active:d==="manual",disabled:S||r.length===0,onClick:J}),e.jsx(Se,{label:"Auto",active:d==="auto",disabled:S||r.length===0&&a.length===0,onClick:D})]}),e.jsx("input",{type:"range",min:0,max:z.length-1,step:1,value:u,onChange:b=>{const m=z[Number(b.target.value)]?.id;m&&A(m)},className:"mt-3 w-full accent-indigo-400","aria-label":"Solver auto playback speed"}),e.jsx("div",{className:"mt-1 flex justify-between",children:z.map(b=>e.jsx("span",{className:`text-[9px] uppercase tracking-wide ${b.id===x?"text-indigo-300":"text-slate-600"}`,children:b.label},b.id))})]}),r.length>0&&e.jsx("div",{className:"mt-3 max-h-28 overflow-y-auto rounded-lg bg-slate-950/50 p-2",children:r.map((b,m)=>e.jsxs("div",{className:`flex items-center gap-2 rounded px-2 py-1 text-[11px] ${mY(!V),className:`inline-flex w-full items-center justify-center gap-2 rounded-lg px-3 py-2 text-xs font-semibold ring-1 ${V?"bg-indigo-500/15 text-indigo-300 ring-indigo-500/30":"bg-slate-800/70 text-slate-400 ring-slate-700/40"}`,children:[V?e.jsx(Ge,{size:14}):e.jsx(Xe,{size:14}),V?"Sound On":"Sound Off"]})})]})}function B({title:t,children:s}){return e.jsxs("section",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"mb-3 text-[11px] font-semibold uppercase tracking-wider text-slate-400",children:t}),s]})}function O({label:t,value:s}){return e.jsxs("div",{className:"rounded-lg bg-slate-800/50 px-2.5 py-2 ring-1 ring-slate-700/40",children:[e.jsx("div",{className:"text-[10px] text-slate-500",children:t}),e.jsx("div",{className:"text-sm font-mono text-slate-100",children:s})]})}function T({label:t,icon:s,disabled:a,onClick:l}){return e.jsxs("button",{onClick:l,disabled:a,className:"inline-flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/70 px-3 py-2 text-[11px] font-semibold text-slate-300 ring-1 ring-slate-700/50 hover:bg-slate-700/70 disabled:cursor-not-allowed disabled:opacity-40",children:[s,t]})}function Se({label:t,active:s,disabled:a,onClick:l}){return e.jsx("button",{onClick:l,disabled:a,className:`rounded-lg px-3 py-2 text-[11px] font-semibold ring-1 transition-all disabled:cursor-not-allowed disabled:opacity-40 ${s?"bg-indigo-500/20 text-indigo-300 ring-indigo-500/40":"bg-slate-800/70 text-slate-300 ring-slate-700/50 hover:bg-slate-700/70"}`,children:t})}function je({value:t,onChange:s,onApply:a}){return e.jsxs("div",{children:[e.jsx("label",{className:"text-[11px] text-slate-400",children:"Move notation"}),e.jsxs("div",{className:"mt-1 flex gap-2",children:[e.jsx("input",{value:t,onChange:l=>s(l.target.value),onKeyDown:l=>{l.key==="Enter"&&a()},placeholder:"R, U', F2",className:"min-w-0 flex-1 rounded-lg bg-slate-950/70 px-3 py-2 text-sm font-mono text-slate-200 ring-1 ring-slate-700/50 outline-none focus:ring-cyan-500/50"}),e.jsx("button",{onClick:a,className:"rounded-lg bg-cyan-500/20 px-3 py-2 text-xs font-semibold text-cyan-300 ring-1 ring-cyan-500/40 hover:bg-cyan-500/30",children:"Apply"})]})]})}const pt=o.memo(xt);function gt(){const t=o.useRef(!0),[s,a]=o.useState(!0),l=o.useCallback(()=>Ye(),[]),r=o.useCallback((v,p,i="sine",C=.045)=>{if(!t.current)return;const h=l();if(!h)return;const w=h.createOscillator(),k=h.createGain();w.type=i,w.frequency.setValueAtTime(v,h.currentTime),k.gain.setValueAtTime(C,h.currentTime),k.gain.exponentialRampToValueAtTime(.001,h.currentTime+p),w.connect(k),k.connect(h.destination),w.start(h.currentTime),w.stop(h.currentTime+p)},[l]),c=o.useCallback(v=>{const p=[261.63,293.66,329.63,392,440,523.25];r(p[v%p.length],.08,"triangle",.035)},[r]),S=o.useCallback(()=>{r(196,.12,"sawtooth",.03),setTimeout(()=>r(246.94,.12,"sawtooth",.03),80)},[r]),d=o.useCallback(()=>{[392,493.88,587.33,783.99].forEach((v,p)=>{setTimeout(()=>r(v,.12,"sine",.05),p*75)})},[r]),x=o.useCallback(()=>{r(164.81,.18,"sawtooth",.035)},[r]),f=o.useCallback(v=>{t.current=v,a(v)},[]);return{soundEnabled:s,toggleSound:f,playMove:c,playScramble:S,playSolved:d,playError:x}}const ye=["Start from a solved cube and watch what a single R turn does.","Scramble the cube with a short sequence.","Ask the solver for the inverse sequence.","Step through solution moves and watch the cube return to solved state."];function Ce(t){return z.find(s=>s.id===t)?.delayMs??450}function bt(){const[t,s]=o.useState("guided"),[a,l]=o.useState(U),[r,c]=o.useState([]),[S,d]=o.useState([]),[x,f]=o.useState([]),[v,p]=o.useState(0),[i,C]=o.useState("R"),[h,w]=o.useState("R U R' U'"),[k,ne]=o.useState(10),[H,N]=o.useState(null),[V,g]=o.useState("Choose a mode and start turning the cube."),[ae,j]=o.useState("manual"),[K,Q]=o.useState("normal"),[$,G]=o.useState(0),[_,J]=o.useState(fe[0]),[D,A]=o.useState(!1),[oe,L]=o.useState(0),[X,F]=o.useState(!1),M=o.useRef(null),Y=o.useRef("normal"),u=gt(),re=o.useMemo(()=>te(a),[a]),b=x.length>0&&v>=x.length,m=o.useCallback(()=>{M.current&&(window.clearInterval(M.current),M.current=null)},[]);o.useEffect(()=>m,[m]);const Me=o.useCallback(n=>{Y.current=n,Q(n)},[]),Re=o.useCallback(()=>{m(),l(U()),c([]),d([]),f([]),p(0),N(null),j("manual"),G(0),A(!1),L(0),F(!1),g("Cube reset to solved state.")},[m]),Le=o.useCallback(n=>{s(n),m(),l(U()),c([]),d([]),f([]),p(0),N(null),j("manual"),G(0),A(!1),L(0),F(!1),g(n==="guided"?"Guided mode: follow the walkthrough to understand cube moves and solving.":n==="freeplay"?"Freeplay mode: scramble, turn, and solve however you like.":"Challenge mode: solve the scramble in as few moves as possible.")},[m]),q=o.useCallback((n,y=!0)=>{m(),j("manual"),l(E=>{const I=se(E,n);return y&&(c(P=>[...P,n]),t==="challenge"&&D&&!X&&(L(P=>P+1),te(I)&&(F(!0),g("Challenge solved! Compare your move count with the target."),u.playSolved()))),I}),f([]),p(0),N(null),u.playMove(n.charCodeAt(0))},[X,D,m,t,u]),Fe=o.useCallback((n=12)=>{m();const y=Ne(n);l(Z(U(),y)),c(y),d(y),f([]),p(0),j("manual"),A(!1),L(0),F(!1),g(`Scrambled with: ${R(y)}`),u.playScramble()},[m,u]),Ue=o.useCallback(()=>{m();const n=ut(h);if(!n){g("Invalid scramble. Use moves like: R U R' U' or Ri U R U2."),u.playError();return}l(Z(U(),n)),c(n),d(n),f([]),p(0),N(null),j("manual"),A(!1),L(0),F(!1),g(`Custom scramble applied: ${R(n)}`),u.playScramble()},[m,h,u]),Te=o.useCallback((n=_)=>{m(),J(n),l(Z(U(),n.scramble)),c(n.scramble),d(n.scramble),f([]),p(0),N(null),j("manual"),A(!0),L(0),F(!1),g(`Challenge started. Scramble: ${R(n.scramble)}`),u.playScramble()},[m,_,u]),$e=o.useCallback(()=>{m();const n=le(r);f(n),p(0),N(null),j("manual"),g(n.length>0?`Solver found ${n.length} inverse move${n.length===1?"":"s"}.`:"Cube is already solved."),n.length===0&&u.playSolved()},[m,r,u]),ie=o.useCallback(()=>{m(),j("manual");const n=x[v];n&&(l(y=>{const E=se(y,n.move);return te(E)?(g("Solved! The inverse sequence returned the cube to its original state."),u.playSolved()):g(n.description),E}),p(y=>y+1),u.playMove(v))},[m,x,v,u]),De=o.useCallback(()=>{m();const n=x.length>0?x:le(r),y=x.length>0?v:0;if(n.length===0){f([]),p(0),j("manual"),g("Cube is already solved."),u.playSolved();return}if(y>=n.length){j("manual"),g("Solution playback is already complete.");return}x.length===0&&(f(n),p(0)),N(null),j("auto"),g(`Auto-solving ${n.length-y} remaining move${n.length-y===1?"":"s"}.`);const E=()=>{p(I=>{const P=n[I];if(!P)return M.current=null,j("manual"),I;l(Be=>{const me=se(Be,P.move);return te(me)?(g("Auto-solve complete."),u.playSolved()):(g(P.description),u.playMove(I)),me});const ue=I+1;return ue{const n=we(i);if(!n){g("Invalid move. Use notation like R, U', F2, or L'."),u.playError();return}q(n),g(`Applied ${n}.`)},[q,i,u]),Ee=o.useCallback(()=>{const n=mt(k);N(n),g(`Ran ${n.runs} simulated solves. Best: ${n.best.solutionLength} moves, worst: ${n.worst.solutionLength} moves.`)},[k]),Ie=o.useCallback(()=>{const n=r.slice(0,-1);c(n),l(Z(U(),n)),f([]),p(0),j("manual"),g("Undid the last recorded move.")},[r]),Pe=o.useCallback(()=>{if($===0)q("R"),g("R turns the right face clockwise. Notice the side stickers move too.");else if($===1){const n=["R","U","R'","U'"];l(Z(U(),n)),c(n),d(n),g(`Short scramble applied: ${R(n)}`),u.playScramble()}else if($===2){const n=le(r);f(n),p(0),g(`The solver reverses the scramble: ${R(n.map(y=>y.move))}`)}else ie();G(n=>Math.min(n+1,ye.length-1))},[$,q,r,u,ie]);return{mode:t,cube:a,solved:re,moveHistory:r,scrambleMoves:S,solution:x,solutionIndex:v,solutionDone:b,solverPlaybackMode:ae,solverSpeed:K,setSolverSpeed:Me,manualMove:i,setManualMove:C,customScramble:h,setCustomScramble:w,simulationRuns:k,setSimulationRuns:ne,simulationResult:H,message:V,guidedStep:$,guidedScript:ye,selectedChallenge:_,setSelectedChallenge:J,challenges:fe,challengeStarted:D,challengeMoves:oe,challengeSolved:X,soundEnabled:u.soundEnabled,toggleSound:u.toggleSound,switchMode:Le,resetCube:Re,makeMove:q,runScramble:Fe,runCustomScramble:Ue,generateSolution:$e,stepSolution:ie,autoSolve:De,applyManualMove:Ae,undoLastMove:Ie,startChallenge:Te,nextGuidedStep:Pe,simulateSolves:Ee}}const ht=[{id:"guided",label:"Guided Mode",icon:e.jsx(Ve,{size:14})},{id:"freeplay",label:"Freeplay Mode",icon:e.jsx(ze,{size:14})},{id:"challenge",label:"Challenge Mode",icon:e.jsx(qe,{size:14})}];function Nt(){const t=bt();return e.jsxs("div",{className:"flex flex-1 flex-col overflow-hidden",children:[e.jsx("div",{className:"shrink-0 border-b border-slate-700/50 bg-slate-900/40 px-4 pt-3 backdrop-blur-sm md:px-6",children:e.jsx("div",{className:"flex gap-1 overflow-x-auto",children:ht.map(s=>e.jsxs("button",{onClick:()=>t.switchMode(s.id),className:`flex items-center gap-1.5 whitespace-nowrap rounded-t-lg px-4 py-2.5 text-xs font-medium transition-all md:text-sm ${t.mode===s.id?"bg-slate-800/80 text-indigo-300 border border-b-0 border-slate-700/50 -mb-px":"text-slate-500 hover:bg-slate-800/30 hover:text-slate-300"}`,children:[s.icon,s.label]},s.id))})}),e.jsx("div",{className:"flex-1 overflow-y-auto p-4 md:p-6",children:e.jsxs("div",{className:"mx-auto flex max-w-6xl flex-col gap-4 md:flex-row md:gap-6",children:[e.jsxs("main",{className:"order-last flex min-w-0 flex-1 flex-col gap-4 md:order-first",children:[e.jsxs("section",{className:"rounded-2xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm md:p-5",children:[e.jsxs("div",{className:"flex flex-col gap-2 md:flex-row md:items-start md:justify-between",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-bold text-white md:text-xl",children:"Rubik's Cube Solver"}),e.jsx("p",{className:"mt-1 text-xs leading-relaxed text-slate-400",children:"Manipulate a 3D Rubik's Cube, generate or enter scrambles, and watch a CFOP-inspired solve sequence step by step."})]}),e.jsx("div",{className:"rounded-full bg-violet-500/10 px-3 py-1 text-[10px] font-semibold text-violet-300 ring-1 ring-violet-500/30",children:"3D Cube"})]}),e.jsx("div",{className:"mt-3 rounded-xl bg-indigo-500/5 px-3 py-2 ring-1 ring-indigo-500/15",children:e.jsxs("p",{className:"text-[11px] leading-relaxed text-slate-300",children:["Move notation: ",e.jsx("span",{className:"font-mono text-cyan-300",children:"R"})," turns a face clockwise,",e.jsx("span",{className:"font-mono text-cyan-300",children:" R'"})," turns it counter-clockwise, and",e.jsx("span",{className:"font-mono text-cyan-300",children:" R2"})," turns it twice. The inverse shorthand",e.jsx("span",{className:"font-mono text-cyan-300",children:" Ri"})," is also accepted."]})})]}),e.jsx(et,{cube:t.cube,solved:t.solved,onMove:t.makeMove})]}),e.jsx(pt,{mode:t.mode,message:t.message,moveHistory:t.moveHistory,scrambleMoves:t.scrambleMoves,solution:t.solution,solutionIndex:t.solutionIndex,solutionDone:t.solutionDone,solverPlaybackMode:t.solverPlaybackMode,solverSpeed:t.solverSpeed,manualMove:t.manualMove,customScramble:t.customScramble,simulationRuns:t.simulationRuns,simulationResult:t.simulationResult,guidedStep:t.guidedStep,guidedScript:t.guidedScript,challenges:t.challenges,selectedChallenge:t.selectedChallenge,challengeStarted:t.challengeStarted,challengeMoves:t.challengeMoves,challengeSolved:t.challengeSolved,soundEnabled:t.soundEnabled,onManualMoveChange:t.setManualMove,onCustomScrambleChange:t.setCustomScramble,onSimulationRunsChange:t.setSimulationRuns,onApplyManualMove:t.applyManualMove,onScramble:t.runScramble,onApplyCustomScramble:t.runCustomScramble,onSimulateSolves:t.simulateSolves,onGenerateSolution:t.generateSolution,onStepSolution:t.stepSolution,onAutoSolve:t.autoSolve,onSolverSpeedChange:t.setSolverSpeed,onUndo:t.undoLastMove,onReset:t.resetCube,onNextGuidedStep:t.nextGuidedStep,onSelectChallenge:t.setSelectedChallenge,onStartChallenge:t.startChallenge,onToggleSound:t.toggleSound})]})})]})}export{Nt as default}; diff --git a/docs/assets/SortingPage--_1K-mN2.js b/docs/assets/SortingPage--_1K-mN2.js new file mode 100644 index 0000000..fabb5c9 --- /dev/null +++ b/docs/assets/SortingPage--_1K-mN2.js @@ -0,0 +1,11 @@ +import{r as n,j as e,d as _}from"./index-BfWfBQOp.js";import{V as H,a as L}from"./volume-x-ChIHiT28.js";import{S as Q}from"./square-BSu6WBc6.js";import{S as W}from"./shuffle-Ri9xSsK2.js";import{r as X}from"./index-iw_6MvvU.js";import{g as J}from"./audioContext-NbgqvQGz.js";function K(s,d,o,y){return o&&(s===o[0]||s===o[1])?"bg-rose-500 shadow-lg shadow-rose-500/30":d&&(s===d[0]||s===d[1])?"bg-amber-400 shadow-lg shadow-amber-400/20":y.includes(s)?"bg-emerald-500":"bg-indigo-400/80"}function Y({array:s,comparing:d,swapping:o,sortedIndices:y}){const g=Math.max(...s,1),x=Math.max(2,Math.min(20,Math.floor(900/s.length)-1));return e.jsx("div",{className:"flex h-[500px] items-end justify-center gap-[1px] rounded-xl border border-slate-700/50 bg-slate-950/80 p-6 backdrop-blur-sm shadow-2xl",children:s.map((a,r)=>{const h=a/g*100,t=K(r,d,o,y);return e.jsx("div",{className:`transition-all duration-75 rounded-t-sm ${t}`,style:{height:`${h}%`,width:`${x}px`}},r)})})}const Z=n.memo(Y),ee={slow:100,medium:30,fast:8,instant:0},R={bubble:{name:"Bubble Sort",description:"Repeatedly swaps adjacent elements if they are in the wrong order. Simple but inefficient for large datasets.",timeComplexity:"O(n²)",spaceComplexity:"O(1)",stable:!0},selection:{name:"Selection Sort",description:"Finds the minimum element and places it at the beginning. Performs well on small arrays.",timeComplexity:"O(n²)",spaceComplexity:"O(1)",stable:!1},insertion:{name:"Insertion Sort",description:"Builds the sorted array one element at a time by inserting each into its correct position.",timeComplexity:"O(n²)",spaceComplexity:"O(1)",stable:!0},quick:{name:"Quick Sort",description:"Divides the array using a pivot and recursively sorts the partitions. Very efficient in practice.",timeComplexity:"O(n log n)",spaceComplexity:"O(log n)",stable:!1},heap:{name:"Heap Sort",description:"Builds a max-heap then repeatedly extracts the maximum to build the sorted array.",timeComplexity:"O(n log n)",spaceComplexity:"O(1)",stable:!1},merge:{name:"Merge Sort",description:"Divides the array in half, recursively sorts, then merges. Guarantees consistent performance.",timeComplexity:"O(n log n)",spaceComplexity:"O(n)",stable:!0}},te=["bubble","selection","insertion","quick","heap","merge"],se=["slow","medium","fast","instant"];function ae({algorithm:s,setAlgorithm:d,speed:o,setSpeed:y,arraySize:g,changeArraySize:x,isRunning:a,isFinished:r,currentStep:h,totalSteps:t,soundEnabled:u,onToggleSound:i,onVisualize:f,onStop:c,onGenerateNewArray:S}){const p=R[s];return e.jsxs("div",{className:"flex flex-col gap-5 w-full md:w-72 shrink-0 overflow-y-auto max-h-full pr-1",children:[e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Algorithm"}),e.jsx("div",{className:"grid grid-cols-2 gap-2",children:te.map(l=>e.jsx("button",{onClick:()=>!a&&d(l),disabled:a,className:` + rounded-lg px-3 py-2 text-sm font-medium transition-all duration-200 + ${s===l?"bg-indigo-500/20 text-indigo-300 ring-1 ring-indigo-500/40 shadow-lg shadow-indigo-500/10":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50 hover:text-slate-300"} + disabled:opacity-50 disabled:cursor-not-allowed + `,children:R[l].name},l))}),e.jsxs("div",{className:"mt-3 rounded-lg bg-slate-800/40 p-3",children:[e.jsx("p",{className:"text-xs text-slate-400 leading-relaxed",children:p.description}),e.jsxs("div",{className:"mt-2 flex flex-wrap gap-2",children:[e.jsxs("span",{className:"inline-flex items-center rounded-full bg-violet-500/10 px-2 py-0.5 text-[10px] font-medium text-violet-400 ring-1 ring-violet-500/20",children:["Time: ",p.timeComplexity]}),e.jsxs("span",{className:"inline-flex items-center rounded-full bg-cyan-500/10 px-2 py-0.5 text-[10px] font-medium text-cyan-400 ring-1 ring-cyan-500/20",children:["Space: ",p.spaceComplexity]}),p.stable&&e.jsx("span",{className:"inline-flex items-center rounded-full bg-emerald-500/10 px-2 py-0.5 text-[10px] font-medium text-emerald-400 ring-1 ring-emerald-500/20",children:"Stable"})]})]})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400",children:"Speed"}),e.jsxs("button",{onClick:()=>i(!u),className:` + flex items-center gap-1.5 rounded-lg px-2 py-1 text-xs font-medium transition-all duration-200 + ${u?"bg-emerald-500/15 text-emerald-400 ring-1 ring-emerald-500/30":"bg-slate-800/50 text-slate-500 hover:text-slate-400"} + `,title:u?"Mute sound":"Unmute sound",children:[u?e.jsx(H,{size:12}):e.jsx(L,{size:12}),u?"Sound On":"Sound Off"]})]}),e.jsx("div",{className:"flex gap-1",children:se.map(l=>e.jsx("button",{onClick:()=>y(l),className:` + flex-1 rounded-lg px-2 py-1.5 text-xs font-medium capitalize transition-all duration-200 + ${o===l?"bg-violet-500/20 text-violet-300 ring-1 ring-violet-500/40":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50 hover:text-slate-300"} + `,children:l},l))})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400",children:"Array Size"}),e.jsx("span",{className:"text-xs font-mono text-slate-400",children:g})]}),e.jsx("input",{type:"range",min:"10",max:"150",value:g,onChange:l=>!a&&x(Number(l.target.value)),disabled:a,className:"w-full accent-indigo-500 disabled:opacity-50"}),e.jsxs("div",{className:"flex justify-between mt-1",children:[e.jsx("span",{className:"text-[10px] text-slate-600",children:"10"}),e.jsx("span",{className:"text-[10px] text-slate-600",children:"150"})]})]}),e.jsxs("div",{className:"flex flex-col gap-2",children:[a?e.jsxs("button",{onClick:c,className:"flex items-center justify-center gap-2 rounded-xl bg-gradient-to-r from-rose-500 to-pink-500 px-4 py-3 text-sm font-semibold text-white shadow-lg shadow-rose-500/25 transition-all duration-200 hover:brightness-110 active:scale-[0.98]",children:[e.jsx(Q,{size:16}),"Stop"]}):e.jsxs("button",{onClick:f,className:"flex items-center justify-center gap-2 rounded-xl bg-gradient-to-r from-indigo-500 to-violet-500 px-4 py-3 text-sm font-semibold text-white shadow-lg shadow-indigo-500/25 transition-all duration-200 hover:shadow-xl hover:shadow-indigo-500/30 hover:brightness-110 active:scale-[0.98]",children:[e.jsx(_,{size:16}),"Visualize ",p.name]}),e.jsxs("button",{onClick:S,disabled:a,className:"flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300 disabled:opacity-50 disabled:cursor-not-allowed",children:[e.jsx(W,{size:12}),"Generate New Array"]})]}),(a||r)&&e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Statistics"}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-xs text-slate-500",children:"Operations"}),e.jsxs("span",{className:"text-sm font-mono font-semibold text-indigo-400",children:[h," / ",t]})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-xs text-slate-500",children:"Array Size"}),e.jsx("span",{className:"text-sm font-mono font-semibold text-amber-400",children:g})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-xs text-slate-500",children:"Status"}),e.jsx("span",{className:`text-xs font-semibold ${r?"text-emerald-400":"text-violet-400"}`,children:r?"Sorted":"Sorting..."})]})]})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Legend"}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-indigo-400/80"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Unsorted"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-amber-400"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Comparing"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-rose-500"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Swapping"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-emerald-500"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Sorted"})]})]})]})]})}const ne={slow:.15,medium:.08,fast:.04,instant:0},le={slow:.07,medium:.05,fast:.035,instant:0};function re(){const s=n.useRef(!0),d=n.useCallback(()=>J(),[]),o=n.useCallback((x,a,r,h)=>{if(!s.current||r==="instant")return;const t=d();if(!t)return;const u=ne[r],i=le[r],f=x/a,c=200,p=c+f*(800-c),l=t.createOscillator(),b=t.createGain();h==="compare"?l.type="sine":h==="swap"?l.type="triangle":l.type="sine",l.frequency.setValueAtTime(p,t.currentTime);const v=h==="sorted"?i*1.5:i;b.gain.setValueAtTime(v,t.currentTime),b.gain.exponentialRampToValueAtTime(.001,t.currentTime+u),l.connect(b),b.connect(t.destination),l.start(t.currentTime),l.stop(t.currentTime+u)},[d]),y=n.useCallback(x=>{if(!s.current)return;const a=d();if(!a)return;const r=200,h=800;for(let t=0;t{s.current=x},[]);return{playTone:o,playCompleteSweep:y,setEnabled:g}}function V(s){return Array.from({length:s},()=>Math.floor(Math.random()*95)+5)}function ie(){const[s,d]=n.useState("bubble"),[o,y]=n.useState("fast"),[g,x]=n.useState(50),[a,r]=n.useState(()=>V(50)),[h,t]=n.useState(null),[u,i]=n.useState(null),[f,c]=n.useState([]),[S,p]=n.useState(!1),[l,b]=n.useState(!1),[v,w]=n.useState(0),[E,C]=n.useState(0),[F,G]=n.useState(!0),k=n.useRef([]),{playTone:A,playCompleteSweep:T,setEnabled:q}=re(),$=n.useCallback(m=>{G(m),q(m)},[q]),B=n.useCallback(()=>{r(V(g)),t(null),i(null),c([]),b(!1),w(0),C(0)},[g]),P=n.useCallback(m=>{x(m),r(V(m)),t(null),i(null),c([]),b(!1),w(0),C(0)},[]),O=n.useCallback(()=>{k.current.forEach(m=>clearTimeout(m)),k.current=[],p(!1),t(null),i(null)},[]),D=n.useCallback(()=>{O(),b(!1),t(null),i(null),c([]),w(0);const m=X(s,a);if(C(m.length),m.length===0){b(!0);return}const M=ee[o],I=Math.max(...a);if(p(!0),M===0){const N=m[m.length-1];r(N.array),c(N.sorted),t(null),i(null),w(m.length),p(!1),b(!0),T(N.array.length);return}for(let N=0;N{const j=m[N];if(r(j.array),t(j.comparing),i(j.swapping),c(j.sorted),w(N+1),j.comparing){const z=j.comparing[0];A(j.array[z],I,o,"compare")}if(j.swapping){const z=j.swapping[0];A(j.array[z],I,o,"swap")}N===m.length-1&&(p(!1),b(!0),t(null),i(null),T(j.array.length))},M*N);k.current.push(U)}},[s,a,o,O,A,T]);return{algorithm:s,setAlgorithm:d,speed:o,setSpeed:y,arraySize:g,changeArraySize:P,array:a,comparing:h,swapping:u,sortedIndices:f,isRunning:S,isFinished:l,currentStep:v,totalSteps:E,soundEnabled:F,toggleSound:$,generateNewArray:B,visualize:D,stopVisualization:O}}function pe(){const{algorithm:s,setAlgorithm:d,speed:o,setSpeed:y,arraySize:g,changeArraySize:x,array:a,comparing:r,swapping:h,sortedIndices:t,isRunning:u,isFinished:i,currentStep:f,totalSteps:c,soundEnabled:S,toggleSound:p,generateNewArray:l,visualize:b,stopVisualization:v}=ie();return e.jsxs("div",{className:"flex flex-1 flex-col md:flex-row gap-4 md:gap-6 overflow-auto p-4 md:p-6",children:[e.jsx("div",{className:"order-last md:order-first flex md:flex-1 flex-col items-center justify-center gap-3 min-h-[40vh] md:min-h-0 max-h-[50vh] md:max-h-none overflow-auto",children:e.jsx(Z,{array:a,comparing:r,swapping:h,sortedIndices:t})}),e.jsx(ae,{algorithm:s,setAlgorithm:d,speed:o,setSpeed:y,arraySize:g,changeArraySize:x,isRunning:u,isFinished:i,currentStep:f,totalSteps:c,soundEnabled:S,onToggleSound:p,onVisualize:b,onStop:v,onGenerateNewArray:l})]})}export{pe as default}; diff --git a/docs/assets/StackPage-1vXSCZRz.js b/docs/assets/StackPage-1vXSCZRz.js new file mode 100644 index 0000000..8a9a4da --- /dev/null +++ b/docs/assets/StackPage-1vXSCZRz.js @@ -0,0 +1,5 @@ +import{r as l,j as e,E as W}from"./index-BfWfBQOp.js";import{u as _}from"./useDSSound-BMrOIkPj.js";import{P as X}from"./plus-BEk43_MF.js";import{T as q}from"./trash-2-RJG3j28z.js";import{R as B}from"./rotate-ccw-EKzY5q_W.js";import{S as J}from"./shuffle-Ri9xSsK2.js";import{V as Q,a as U}from"./volume-x-ChIHiT28.js";import{C as Y,a as Z}from"./chevron-right-CNA9GG_w.js";import"./audioContext-NbgqvQGz.js";let P=1;const ee=[{id:P++,value:3},{id:P++,value:7},{id:P++,value:1}];function te(){const[i,d]=l.useState(ee),[n,u]=l.useState([]),[r,o]=l.useState(-1),[b,j]=l.useState(""),[k,v]=l.useState([]),[h,T]=l.useState(400),[y,p]=l.useState(!1),x=l.useRef(null),w=l.useRef(h),f=l.useRef(!1),{soundEnabled:$,toggleSound:z,playInsert:m,playDelete:N,playAccess:S,playTraverse:I}=_(),a=l.useRef(()=>{});l.useEffect(()=>{w.current=h},[h]),l.useEffect(()=>{if(!f.current||n.length===0)return;f.current=!1,x.current&&clearTimeout(x.current),p(!0);let t=0;const s=()=>{if(t>=n.length-1){p(!1);return}t++,o(t),a.current(t,n),x.current=setTimeout(s,w.current)};x.current=setTimeout(s,w.current)},[n]);const g=l.useCallback((t,s)=>{const c=s[t];c&&(c.highlightColor==="green"?m():c.highlightColor==="red"?N():c.highlightColor==="yellow"&&I(t,s.length))},[m,N,I]);l.useEffect(()=>{a.current=g},[g]);const O=r>=0&&n[r]?n[r].stack:i,L=r>=0?n[r]:null,C=t=>v(s=>[t,...s].slice(0,20)),M=l.useCallback(t=>{const s={id:P++,value:t},c=[];d(E=>{c.push({description:`Pushing ${t} onto the stack...`,stack:E,highlightIndex:null,highlightColor:null});const R=[...E,s];return c.push({description:`${t} placed on top of the stack. Stack size: ${R.length}`,stack:R,highlightIndex:R.length-1,highlightColor:"green"}),u(c),o(0),f.current=!0,m(),C(`Push ${t}`),R})},[m]),H=l.useCallback(()=>{d(t=>{if(t.length===0)return t;const s=t[t.length-1],c=[{description:`Peeking at top element: ${s.value}`,stack:t,highlightIndex:t.length-1,highlightColor:"yellow"},{description:`Popping ${s.value} from the top of the stack.`,stack:t,highlightIndex:t.length-1,highlightColor:"red"},{description:`${s.value} removed. Stack size: ${t.length-1}`,stack:t.slice(0,-1),highlightIndex:null,highlightColor:null}];return u(c),o(0),f.current=!0,N(),C(`Pop → ${s.value}`),t.slice(0,-1)})},[N]),V=l.useCallback(()=>{d(t=>{if(t.length===0)return t;const s=t[t.length-1],c=[{description:"Peek: reading the top element without removing it.",stack:t,highlightIndex:t.length-1,highlightColor:"yellow"},{description:`Top element is ${s.value}.`,stack:t,highlightIndex:t.length-1,highlightColor:"yellow"}];return u(c),o(0),f.current=!0,S(),C(`Peek → ${s.value}`),t})},[S]),A=l.useCallback(()=>{d([]),u([]),o(-1),C("Clear stack")},[]),G=l.useCallback(()=>{const t=Math.floor(Math.random()*5)+3,s=Array.from({length:t},()=>({id:P++,value:Math.floor(Math.random()*90)+1}));d(s),u([]),o(-1),C("Random stack")},[]),D=l.useCallback(()=>{o(t=>{const s=Math.min(t+1,n.length-1);return g(s,n),s})},[n,g]),F=l.useCallback(()=>{o(t=>Math.max(t-1,0))},[]),K=l.useCallback(()=>{if(y){p(!1),x.current&&clearTimeout(x.current);return}p(!0);let t=r;const s=()=>{if(t>=n.length-1){p(!1);return}t++,o(t),g(t,n),x.current=setTimeout(s,h)};x.current=setTimeout(s,h)},[y,r,n,h,g]);return{stack:i,displayStack:O,steps:n,stepIndex:r,currentStep:L,inputValue:b,setInputValue:j,history:k,speed:h,setSpeed:T,isPlaying:y,push:M,pop:H,peek:V,clear:A,generateRandom:G,nextStep:D,prevStep:F,autoPlay:K,soundEnabled:$,toggleSound:z,canGoNext:r0}}const se={green:"border-emerald-400 bg-emerald-500/20 text-emerald-300",red:"border-rose-400 bg-rose-500/20 text-rose-300",yellow:"border-amber-400 bg-amber-500/20 text-amber-300"};function le({stack:i,currentStep:d}){const n=i.slice(-12),u=d?.highlightIndex??null,r=d?.highlightColor??null;return e.jsxs("div",{className:"flex flex-col items-center justify-end w-full h-full min-h-[300px] md:min-h-[400px] gap-1 pb-6",children:[i.length===0&&e.jsxs("div",{className:"flex flex-col items-center justify-center gap-2 text-slate-600",children:[e.jsx("div",{className:"w-32 h-24 border-2 border-dashed border-slate-700 rounded-lg flex items-center justify-center",children:e.jsx("span",{className:"text-xs",children:"Empty Stack"})}),e.jsx("div",{className:"w-32 border-b-2 border-slate-600"})]}),e.jsx("div",{className:"flex flex-col-reverse items-center gap-1.5 w-full max-w-[200px]",children:n.map((o,b)=>{const j=i.length-n.length+b,k=j===u,v=j===i.length-1;return e.jsxs("div",{className:"relative flex items-center gap-2 w-full",children:[v&&e.jsx("span",{className:"absolute -right-14 text-xs font-mono text-indigo-400 whitespace-nowrap",children:"← top"}),e.jsx("div",{className:` + flex-1 flex items-center justify-center rounded-lg border-2 h-12 font-bold text-lg + transition-all duration-300 + ${k&&r?se[r]:"border-slate-600 bg-slate-800/60 text-slate-200"} + `,children:o.value})]},o.id)})}),i.length>0&&e.jsx("div",{className:"w-full max-w-[200px] border-b-4 border-slate-500 rounded mt-1"}),d?.description&&e.jsx("div",{className:"mt-4 w-full max-w-sm rounded-lg bg-slate-800/60 px-4 py-2 text-center text-xs text-indigo-300 leading-relaxed",children:d.description}),e.jsxs("div",{className:"mt-2 text-xs text-slate-500 font-mono",children:["size = ",i.length]})]})}const ae=[{label:"Slow",value:700},{label:"Med",value:350},{label:"Fast",value:120}];function ne({hook:i}){const{stack:d,steps:n,stepIndex:u,inputValue:r,setInputValue:o,history:b,speed:j,setSpeed:k,isPlaying:v,push:h,pop:T,peek:y,clear:p,generateRandom:x,nextStep:w,prevStep:f,canGoNext:$,canGoPrev:z,soundEnabled:m,toggleSound:N}=i,S=()=>{const a=parseInt(r);isNaN(a)||(h(a),o(""))},I=a=>{a.key==="Enter"&&S()};return e.jsxs("div",{className:"flex flex-col gap-4 w-full md:w-72 shrink-0 overflow-y-auto max-h-full pr-1",children:[e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-sm font-bold text-indigo-300 mb-1",children:"Stack"}),e.jsxs("p",{className:"text-xs text-slate-400 leading-relaxed",children:["A ",e.jsx("strong",{className:"text-slate-300",children:"LIFO"})," (Last In, First Out) structure. Elements are pushed onto and popped from the same end — the ",e.jsx("strong",{className:"text-slate-300",children:"top"}),"."]}),e.jsx("div",{className:"mt-2 flex flex-wrap gap-1.5",children:["LIFO","Push O(1)","Pop O(1)","Peek O(1)"].map(a=>e.jsx("span",{className:"rounded-full bg-violet-500/10 px-2 py-0.5 text-[10px] font-medium text-violet-400 ring-1 ring-violet-500/20",children:a},a))})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Operations"}),e.jsx("input",{type:"number",value:r,onChange:a=>o(a.target.value),onKeyDown:I,placeholder:"Enter value...",className:"w-full rounded-lg bg-slate-800/60 px-3 py-2 text-sm text-slate-200 placeholder-slate-600 outline-none ring-1 ring-slate-700/50 focus:ring-indigo-500/50 transition-all"}),e.jsxs("div",{className:"mt-3 grid grid-cols-2 gap-2",children:[e.jsxs("button",{onClick:S,className:"flex items-center justify-center gap-1.5 rounded-lg bg-gradient-to-r from-emerald-500/80 to-green-500/80 px-3 py-2 text-xs font-semibold text-white shadow-lg shadow-emerald-500/15 transition-all hover:brightness-110 active:scale-[0.98]",children:[e.jsx(X,{size:14})," Push"]}),e.jsxs("button",{onClick:T,disabled:d.length===0,className:"flex items-center justify-center gap-1.5 rounded-lg bg-gradient-to-r from-rose-500/80 to-pink-500/80 px-3 py-2 text-xs font-semibold text-white shadow-lg shadow-rose-500/15 transition-all hover:brightness-110 active:scale-[0.98] disabled:opacity-40 disabled:cursor-not-allowed",children:[e.jsx(q,{size:14})," Pop"]}),e.jsxs("button",{onClick:y,disabled:d.length===0,className:"flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-amber-300 transition-all hover:bg-slate-700/60 disabled:opacity-40 disabled:cursor-not-allowed",children:[e.jsx(W,{size:14})," Peek"]}),e.jsxs("button",{onClick:p,disabled:d.length===0,className:"flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-slate-400 transition-all hover:bg-slate-700/60 disabled:opacity-40 disabled:cursor-not-allowed",children:[e.jsx(B,{size:14})," Clear"]})]}),e.jsxs("button",{onClick:x,className:"mt-2 w-full flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300",children:[e.jsx(J,{size:12})," Random Stack"]}),e.jsxs("button",{onClick:()=>N(!m),className:`mt-2 w-full flex items-center justify-center gap-1.5 rounded-lg px-3 py-2 text-xs font-medium transition-all ${m?"bg-indigo-500/15 text-indigo-300 ring-1 ring-indigo-500/30":"bg-slate-800/60 text-slate-400 hover:bg-slate-700/60"}`,children:[m?e.jsx(Q,{size:12}):e.jsx(U,{size:12}),m?"Sound On":"Sound Off"]})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Animation Speed"}),e.jsx("div",{className:"flex gap-1",children:ae.map(a=>e.jsx("button",{onClick:()=>k(a.value),className:`flex-1 rounded-lg px-2 py-1.5 text-xs font-medium transition-all duration-200 ${j===a.value?"bg-violet-500/20 text-violet-300 ring-1 ring-violet-500/40":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50 hover:text-slate-300"}`,children:a.label},a.value))})]}),n.length>0&&e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Step Through"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("button",{onClick:f,disabled:!z||v,className:"flex-1 flex items-center justify-center gap-1 rounded-lg bg-slate-800/60 px-3 py-2.5 text-sm font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300 disabled:opacity-30 disabled:cursor-not-allowed",children:[e.jsx(Y,{size:16})," Prev"]}),e.jsxs("button",{onClick:w,disabled:!$||v,className:"flex-1 flex items-center justify-center gap-1 rounded-lg bg-slate-800/60 px-3 py-2.5 text-sm font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300 disabled:opacity-30 disabled:cursor-not-allowed",children:["Next ",e.jsx(Z,{size:16})]})]}),e.jsxs("div",{className:"mt-2 flex items-center justify-between",children:[e.jsx("span",{className:"text-xs text-slate-500",children:"Step"}),e.jsxs("span",{className:"text-sm font-mono font-semibold text-indigo-400",children:[Math.max(0,u+1)," / ",n.length]})]})]}),b.length>0&&e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"History"}),e.jsx("div",{className:"max-h-36 overflow-y-auto space-y-1",children:b.map((a,g)=>e.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[e.jsx("span",{className:"font-mono text-slate-600 w-4 text-right",children:g+1}),e.jsx("span",{className:a.startsWith("Push")?"text-emerald-400":a.startsWith("Pop")?"text-rose-400":a.startsWith("Peek")?"text-amber-400":"text-slate-400",children:a})]},g))})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Legend"}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-emerald-500"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Push"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-rose-500"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Pop"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-amber-400"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Peek"})]})]})]})]})}function ge(){const i=te();return e.jsxs("div",{className:"flex flex-1 flex-col md:flex-row gap-4 md:gap-6 overflow-auto p-4 md:p-6",children:[e.jsx("div",{className:"order-last md:order-first flex md:flex-1 flex-col items-center justify-center gap-3 min-h-[40vh] md:min-h-0 max-h-[55vh] md:max-h-none overflow-hidden",children:e.jsx(le,{stack:i.displayStack,currentStep:i.currentStep})}),e.jsx(ne,{hook:i})]})}export{ge as default}; diff --git a/docs/assets/SudokuPage-Bwx9E4N_.js b/docs/assets/SudokuPage-Bwx9E4N_.js new file mode 100644 index 0000000..33047b6 --- /dev/null +++ b/docs/assets/SudokuPage-Bwx9E4N_.js @@ -0,0 +1,13 @@ +import{c as R,r as m,j as e}from"./index-BfWfBQOp.js";import{C as Y,a as ee}from"./chevron-right-CNA9GG_w.js";import{Z as te}from"./zap-CxtzYT6S.js";import{S as se}from"./shuffle-Ri9xSsK2.js";import{R as re}from"./rotate-ccw-EKzY5q_W.js";const le=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],ne=R("circle-check",le);const oe=[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]],ae=R("loader-circle",oe);const ie=[["rect",{width:"18",height:"11",x:"3",y:"11",rx:"2",ry:"2",key:"1w4ew1"}],["path",{d:"M7 11V7a5 5 0 0 1 10 0v4",key:"fwvmzm"}]],ce=R("lock",ie);const de=[["path",{d:"M13 21h8",key:"1jsn5i"}],["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",key:"1a8usu"}]],ue=R("pen-line",de);const xe=[["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",key:"1a8usu"}],["path",{d:"m15 5 4 4",key:"1mk7zo"}]],me=R("pencil",xe),I={4:{label:"4×4",boxRows:2,boxCols:2,difficulty:"Easy"},9:{label:"9×9",boxRows:3,boxCols:3,difficulty:"Standard"},16:{label:"16×16",boxRows:4,boxCols:4,difficulty:"Hard"}};function E(s){return I[s]}function fe(s){return s===4?"w-16 h-16 text-2xl":s===9?"w-12 h-12 text-lg":"w-8 h-8 text-[11px]"}function pe(s,t){return s===null?"":t<=9?String(s):s.toString(16).toUpperCase()}function be({grid:s,gridSize:t,isEditing:n,selectedCell:r,onCellClick:l,onCellValueChange:o}){const{boxRows:i,boxCols:a}=E(t),d=fe(t),c=m.useRef(null),h=m.useCallback(b=>{if(!n||!r)return;const{row:p,col:f}=r;if(b.key==="Backspace"||b.key==="Delete"||b.key==="0"){o(p,f,null);return}if(b.key==="ArrowUp"&&p>0){l(p-1,f);return}if(b.key==="ArrowDown"&&p0){l(p,f-1);return}if(b.key==="ArrowRight"&&f=1&&x<=t&&o(p,f,x)}else{const x=parseInt(b.key,16);!isNaN(x)&&x>=1&&x<=t&&o(p,f,x)}},[n,r,t,l,o]);m.useEffect(()=>(window.addEventListener("keydown",h),()=>window.removeEventListener("keydown",h)),[h]),m.useEffect(()=>{n&&r&&c.current&&c.current.focus()},[n,r]);const g=m.useCallback(b=>{if(!n||!r)return;const p=b.currentTarget.value;if(b.currentTarget.value="",!p)return;const f=p.slice(-1);if(f==="0"){o(r.row,r.col,null);return}if(t<=9){const x=parseInt(f);!isNaN(x)&&x>=1&&x<=t&&o(r.row,r.col,x)}else{const x=parseInt(f,16);!isNaN(x)&&x>=1&&x<=t&&o(r.row,r.col,x)}},[n,r,t,o]),S=m.useCallback((b,p)=>{n&&(l(b,p),setTimeout(()=>c.current?.focus(),0))},[n,l]);return e.jsxs("div",{className:"relative",children:[n&&e.jsx("input",{ref:c,type:"text",inputMode:"numeric",autoComplete:"off",className:"absolute opacity-0 w-0 h-0 pointer-events-none",onInput:g,"aria-label":"Sudoku cell input"}),e.jsx("div",{className:"inline-grid rounded-xl border-2 border-slate-500/60 bg-slate-950/80 backdrop-blur-sm shadow-2xl overflow-hidden",style:{gridTemplateColumns:`repeat(${t}, 1fr)`},children:s.map((b,p)=>b.map((f,x)=>{const N=(x+1)%a===0&&xS(p,x),className:` + ${d} flex items-center justify-center + border border-slate-800/40 + ${N?"border-r-2 border-r-slate-500/60":""} + ${k?"border-b-2 border-b-slate-500/60":""} + ${w} ${C} + transition-all duration-150 select-none + ${n?"cursor-pointer hover:bg-slate-800/60":""} + `,children:pe(f.value,t)},`${p}-${x}`)}))})]})}const he=m.memo(be),ge=[4,9,16];function ve({gridSize:s,stepIndex:t,totalSteps:n,isSolved:r,isGenerating:l,isEditing:o,canGoNext:i,canGoPrev:a,evaluationResult:d,onGenerate:c,onNextStep:h,onPrevStep:g,onSolveComplete:S,onEvaluate:b,onReset:p,onStartCustom:f,onEditCurrent:x,onLockCustom:N}){return e.jsxs("div",{className:"flex flex-col gap-5 w-full md:w-72 shrink-0 overflow-y-auto max-h-full pr-1",children:[e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Grid Size"}),e.jsx("div",{className:"flex gap-2",children:ge.map(k=>{const j=I[k];return e.jsxs("button",{onClick:()=>c(k),disabled:l,className:` + flex-1 flex flex-col items-center gap-1 rounded-lg px-3 py-3 transition-all duration-200 + ${s===k?"bg-indigo-500/20 text-indigo-300 ring-1 ring-indigo-500/40 shadow-lg shadow-indigo-500/10":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50 hover:text-slate-300"} + disabled:opacity-50 disabled:cursor-not-allowed + `,children:[e.jsx("span",{className:"text-sm font-semibold",children:j.label}),e.jsx("span",{className:"text-[10px] opacity-70",children:j.difficulty})]},k)})})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Custom Puzzle"}),o?e.jsxs("div",{className:"space-y-2",children:[e.jsxs("p",{className:"text-xs text-amber-300/80 leading-relaxed",children:["Click a cell, then type a number (1–",s,"). Use arrow keys to navigate. Press Backspace to clear."]}),e.jsxs("button",{onClick:N,className:"w-full flex items-center justify-center gap-2 rounded-lg bg-emerald-500/15 px-3 py-2.5 text-sm font-medium text-emerald-300 ring-1 ring-emerald-500/30 transition-all hover:bg-emerald-500/25",children:[e.jsx(ce,{size:14}),"Lock Puzzle & Solve"]}),e.jsxs("button",{onClick:b,className:"w-full flex items-center justify-center gap-2 rounded-lg bg-indigo-500/15 px-3 py-2.5 text-sm font-medium text-indigo-300 ring-1 ring-indigo-500/30 transition-all hover:bg-indigo-500/25",children:[e.jsx(ne,{size:14}),"Evaluate"]}),d&&e.jsxs("div",{className:`rounded-lg px-3 py-2 text-xs font-medium text-center ${d==="correct"?"bg-emerald-500/15 text-emerald-300 ring-1 ring-emerald-500/30":d==="incomplete"?"bg-amber-500/15 text-amber-300 ring-1 ring-amber-500/30":"bg-rose-500/15 text-rose-300 ring-1 ring-rose-500/30"}`,children:[d==="correct"&&"Solved correctly!",d==="incomplete"&&"Some cells are still empty.",d==="errors"&&"There are conflicts in your solution."]})]}):e.jsxs("div",{className:"space-y-2",children:[e.jsxs("button",{onClick:f,disabled:l,className:"w-full flex items-center justify-center gap-2 rounded-lg bg-amber-500/15 px-3 py-2.5 text-sm font-medium text-amber-300 ring-1 ring-amber-500/30 transition-all hover:bg-amber-500/25 disabled:opacity-50 disabled:cursor-not-allowed",children:[e.jsx(ue,{size:14}),"Start From Blank"]}),e.jsxs("button",{onClick:x,disabled:l,className:"w-full flex items-center justify-center gap-2 rounded-lg bg-sky-500/15 px-3 py-2.5 text-sm font-medium text-sky-300 ring-1 ring-sky-500/30 transition-all hover:bg-sky-500/25 disabled:opacity-50 disabled:cursor-not-allowed",children:[e.jsx(me,{size:14}),"Edit Current Puzzle"]})]})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"About"}),e.jsxs("div",{className:"rounded-lg bg-slate-800/40 p-3",children:[e.jsx("p",{className:"text-xs text-slate-400 leading-relaxed",children:"Uses a backtracking algorithm to solve the puzzle. Step through each decision the solver makes — placing a number (green) or backtracking when stuck (red)."}),e.jsxs("div",{className:"mt-2 flex gap-2",children:[e.jsx("span",{className:"inline-flex items-center rounded-full bg-violet-500/10 px-2 py-0.5 text-[10px] font-medium text-violet-400 ring-1 ring-violet-500/20",children:"Backtracking"}),e.jsx("span",{className:"inline-flex items-center rounded-full bg-cyan-500/10 px-2 py-0.5 text-[10px] font-medium text-cyan-400 ring-1 ring-cyan-500/20",children:"Constraint Propagation"})]})]})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Step Controls"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("button",{onClick:g,disabled:!a||l,className:"flex-1 flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2.5 text-sm font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300 disabled:opacity-30 disabled:cursor-not-allowed",children:[e.jsx(Y,{size:16}),"Prev"]}),e.jsxs("button",{onClick:h,disabled:!i||r||l,className:"flex-1 flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2.5 text-sm font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300 disabled:opacity-30 disabled:cursor-not-allowed",children:["Next",e.jsx(ee,{size:16})]})]}),n>0&&e.jsxs("div",{className:"mt-3 flex items-center justify-between",children:[e.jsx("span",{className:"text-xs text-slate-500",children:"Step"}),e.jsxs("span",{className:"text-sm font-mono font-semibold text-indigo-400",children:[Math.max(0,t+1)," / ",n]})]})]}),e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("button",{onClick:S,disabled:r||l,className:"flex items-center justify-center gap-2 rounded-xl bg-gradient-to-r from-indigo-500 to-violet-500 px-4 py-3 text-sm font-semibold text-white shadow-lg shadow-indigo-500/25 transition-all duration-200 hover:shadow-xl hover:shadow-indigo-500/30 hover:brightness-110 active:scale-[0.98] disabled:opacity-50 disabled:cursor-not-allowed",children:l?e.jsxs(e.Fragment,{children:[e.jsx(ae,{size:16,className:"animate-spin"}),"Generating..."]}):e.jsxs(e.Fragment,{children:[e.jsx(te,{size:16}),"Solve Complete"]})}),e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsxs("button",{onClick:()=>c(s),disabled:l,className:"flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300 disabled:opacity-50 disabled:cursor-not-allowed",children:[e.jsx(se,{size:12}),"New Puzzle"]}),e.jsxs("button",{onClick:p,disabled:l,className:"flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300 disabled:opacity-50 disabled:cursor-not-allowed",children:[e.jsx(re,{size:12}),"Reset"]})]})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Status"}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-xs text-slate-500",children:"Grid"}),e.jsx("span",{className:"text-sm font-mono font-semibold text-slate-300",children:I[s].label})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-xs text-slate-500",children:"State"}),e.jsx("span",{className:`text-xs font-semibold ${r?"text-emerald-400":t>=0?"text-violet-400":"text-slate-500"}`,children:r?"Solved!":t>=0?"Stepping...":"Ready"})]})]})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Legend"}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-slate-900/60 ring-1 ring-slate-700"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Empty Cell"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-white/20"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Original Clue"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-emerald-500/25 ring-1 ring-emerald-400/50"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Placing Number"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-rose-500/20 ring-1 ring-rose-400/40"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Backtracking"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-indigo-400/40"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Solver Filled"})]})]})]})]})}function je(s,t,n,r,l){for(let c=0;c[...t])}function ye(s,t){const n=$(s),r=[];function l(){const o=ke(n,t);if(!o)return r.push({grid:$(n),row:-1,col:-1,value:null,action:"solved"}),!0;const[i,a]=o;for(let d=1;d<=t;d++)if(je(n,i,a,d,t)){if(n[i][a]=d,r.push({grid:$(n),row:i,col:a,value:d,action:"place"}),l())return!0;n[i][a]=null,r.push({grid:$(n),row:i,col:a,value:null,action:"remove"})}return!1}return l(),r}function G(s,t,n,r,l){for(let c=0;c0;n--){const r=Math.floor(Math.random()*(n+1));[t[n],t[r]]=[t[r],t[n]]}return t}function Ne(s){const t=Array.from({length:s},()=>Array(s).fill(null));function n(r){if(r===s*s)return!0;const l=Math.floor(r/s),o=r%s,i=F(Array.from({length:s},(a,d)=>d+1));for(const a of i)if(G(t,l,o,a,s)){if(t[l][o]=a,n(r+1))return!0;t[l][o]=null}return!1}return n(0)?t:null}function we(s,t,n){let r=0;function l(){if(r>=n)return;let o=-1,i=-1;e:for(let a=0;a=n))return}return l(),r}const Se={4:6,9:30,16:100},Ce={4:!0,9:!0,16:!1};function A(s){const t=Ne(s);if(!t)throw new Error("Failed to generate sudoku grid");const n=t.map(c=>[...c]),r=s*s,l=Se[s],o=r-l,i=Ce[s],a=F(Array.from({length:r},(c,h)=>h));let d=0;for(const c of a){if(d>=o)break;const h=Math.floor(c/s),g=c%s,S=n[h][g];if(n[h][g]=null,i){const b=n.map(p=>[...p]);if(we(b,s,2)!==1){n[h][g]=S;continue}}d++}return{puzzle:n,solution:t}}function Pe(s,t){for(let l=0;ll.map((i,a)=>({value:i,isOriginal:t[o][a]!==null,isHighlighted:r?r.row===o&&r.col===a:!1,isError:!1,isCurrent:n?n.row===o&&n.col===a:!1})))}function Re(){const[s,t]=m.useState(9),[n,r]=m.useState(()=>{const{puzzle:u}=A(9);return u}),[l,o]=m.useState(()=>n.map(u=>[...u])),[i,a]=m.useState([]),[d,c]=m.useState(-1),[h,g]=m.useState(!1),[S,b]=m.useState(null),[p,f]=m.useState(!1),[x,N]=m.useState(!1),[k,j]=m.useState(null),w=d>=0&&dw&&w.action!=="solved"?B(w.grid,l,w,k):B(n,l,void 0,k),[n,l,w,k]),T=m.useCallback(u=>{f(!0),t(u),a([]),c(-1),g(!1),N(!1),j(null),setTimeout(()=>{const{puzzle:v}=A(u);r(v),o(v.map(y=>[...y])),f(!1)},10)},[]),U=m.useCallback(()=>{const u=Array.from({length:s},()=>Array(s).fill(null));r(u),o(u.map(v=>[...v])),a([]),c(-1),g(!1),N(!0),j(null)},[s]),O=m.useCallback(()=>{a([]),c(-1),g(!1),N(!0),j(null)},[]),D=m.useCallback(()=>{o(n.map(u=>[...u])),N(!1),j(null),a([]),c(-1),g(!1)},[n]),V=m.useCallback((u,v,y)=>{x&&(b(null),r(P=>{const L=P.map(X=>[...X]);return L[u][v]=y,L}))},[x]),H=m.useCallback((u,v)=>{j(y=>y&&y.row===u&&y.col===v?null:{row:u,col:v})},[]),M=m.useCallback(()=>{if(i.length>0)return i;const u=ye(l,s);return a(u),u},[i,l,s]),Z=m.useCallback(()=>{const u=M();u.length!==0&&c(v=>{const y=v+1;if(y>=u.length)return v;const P=u[y];return P.action==="solved"?(r(P.grid),g(!0)):r(P.grid),y})},[M]),K=m.useCallback(()=>{d<=0||c(u=>{const v=u-1;if(v<0)return r(l.map(P=>[...P])),-1;const y=i[v];return r(y.grid),g(!1),v})},[d,i,l]),q=m.useCallback(()=>{const u=M();if(u.length===0)return;const v=u[u.length-1];r(v.grid),c(u.length-1),g(v.action==="solved")},[M]),Q=m.useCallback(()=>{const u=Pe(n,s);b(u),u==="correct"&&(g(!0),N(!1),j(null))},[n,s]),W=m.useCallback(()=>{r(l.map(u=>[...u])),a([]),c(-1),g(!1),N(!1),j(null),b(null)},[l]),_=i.length,z=d<_-1||i.length===0&&!h,J=d>0;return{gridSize:s,grid:C,stepIndex:d,totalSteps:_,isSolved:h,isGenerating:p,isEditing:x,selectedCell:k,canGoNext:z,canGoPrev:J,generate:T,nextStep:Z,prevStep:K,evaluationResult:S,solveComplete:q,evaluate:Q,reset:W,startCustomPuzzle:U,editCurrentPuzzle:O,lockCustomPuzzle:D,setCellValue:V,selectCell:H}}function Le(){const{gridSize:s,grid:t,stepIndex:n,totalSteps:r,isSolved:l,isGenerating:o,isEditing:i,selectedCell:a,canGoNext:d,canGoPrev:c,generate:h,nextStep:g,prevStep:S,solveComplete:b,reset:p,startCustomPuzzle:f,editCurrentPuzzle:x,lockCustomPuzzle:N,setCellValue:k,selectCell:j,evaluationResult:w,evaluate:C}=Re();return e.jsxs("div",{className:"flex flex-1 flex-col md:flex-row gap-4 md:gap-6 overflow-auto p-4 md:p-6",children:[e.jsxs("div",{className:"order-last md:order-first flex md:flex-1 flex-col items-center justify-center gap-3 min-h-[40vh] md:min-h-0 max-h-[50vh] md:max-h-none overflow-auto",children:[e.jsx(he,{grid:t,gridSize:s,isEditing:i,selectedCell:a,onCellClick:j,onCellValueChange:k}),i&&e.jsx("p",{className:"text-xs text-amber-300/60 animate-pulse",children:"Editing mode — click cells and type numbers"})]}),e.jsx(ve,{gridSize:s,stepIndex:n,totalSteps:r,isSolved:l,isGenerating:o,isEditing:i,canGoNext:d,canGoPrev:c,evaluationResult:w,onGenerate:h,onNextStep:g,onPrevStep:S,onSolveComplete:b,onEvaluate:C,onReset:p,onStartCustom:f,onEditCurrent:x,onLockCustom:N})]})}export{Le as default}; diff --git a/docs/assets/TreeTraversalPage-DDkYMql2.js b/docs/assets/TreeTraversalPage-DDkYMql2.js new file mode 100644 index 0000000..5f02ebd --- /dev/null +++ b/docs/assets/TreeTraversalPage-DDkYMql2.js @@ -0,0 +1,11 @@ +import{r as a,j as e}from"./index-BfWfBQOp.js";import{V as oe,a as ce}from"./volume-x-ChIHiT28.js";import{C as de,a as ue}from"./chevron-right-CNA9GG_w.js";import{P as xe}from"./play-WRQgdyAG.js";import{S as me}from"./square-BSu6WBc6.js";import{S as fe}from"./shuffle-Ri9xSsK2.js";import{R as pe}from"./rotate-ccw-EKzY5q_W.js";import{g as he}from"./audioContext-NbgqvQGz.js";let H=0;function J(t){return{id:H++,value:t,left:null,right:null,x:0,y:0}}function L(t,s){return t?(Math.random()<.5?t.left=L(t.left,s):t.right=L(t.right,s),t):J(s)}function _(t){if(H=0,t<=0)return null;const s=Array.from({length:t},(r,m)=>m+1);for(let r=s.length-1;r>0;r--){const m=Math.floor(Math.random()*(r+1));[s[r],s[m]]=[s[m],s[r]]}let n=null;for(const r of s)n?n=L(n,r):n=J(r);return n&&q(n,0,0,300),n}function q(t,s,n,r){t&&(t.x=n,t.y=s*70,q(t.left,s+1,n-r,r*.55),q(t.right,s+1,n+r,r*.55))}function K(t){const s=[];function n(r){r&&(s.push(r),n(r.left),n(r.right))}return n(t),s}function ge(t){const s=[];function n(r){r&&(r.left&&(s.push({from:r,to:r.left}),n(r.left)),r.right&&(s.push({from:r,to:r.right}),n(r.right)))}return n(t),s}function be({root:t,visitedIds:s,processedIds:n,currentId:r,processOrder:m}){const v=a.useMemo(()=>K(t),[t]),c=a.useMemo(()=>ge(t),[t]),x=Math.min(...v.map(l=>l.x),0)-40,i=Math.max(...v.map(l=>l.x),0)+40,f=Math.max(...v.map(l=>l.y),0)+40,d=i-x+80,u=f+80;return t?e.jsx("div",{className:"flex-1 w-full rounded-xl border border-slate-700/50 bg-slate-950/80 p-4 shadow-2xl backdrop-blur-sm overflow-auto",children:e.jsxs("svg",{viewBox:`${x-40} -20 ${d} ${u}`,className:"w-full h-full",preserveAspectRatio:"xMidYMid meet",children:[c.map((l,p)=>e.jsx("line",{x1:l.from.x,y1:l.from.y,x2:l.to.x,y2:l.to.y,stroke:n.has(l.from.id)&&n.has(l.to.id)?"#818cf8":s.has(l.from.id)&&s.has(l.to.id)?"#64748b":"#334155",strokeWidth:2,strokeOpacity:.6},p)),v.map(l=>{const p=l.id===r,S=n.has(l.id),y=s.has(l.id),k=m.indexOf(l.id);let j="#1e293b",N="#475569",w="#94a3b8";return p?(j="#fbbf24",N="#f59e0b",w="#1e293b"):S?(j="#6366f1",N="#818cf8",w="#ffffff"):y&&(j="#334155",N="#64748b",w="#cbd5e1"),e.jsxs("g",{children:[e.jsx("circle",{cx:l.x,cy:l.y,r:22,fill:j,stroke:N,strokeWidth:2.5,className:"transition-all duration-200"}),e.jsx("text",{x:l.x,y:l.y+1,textAnchor:"middle",dominantBaseline:"central",fill:w,fontSize:12,fontWeight:600,fontFamily:"ui-monospace, monospace",children:l.value}),k>=0&&e.jsx("text",{x:l.x+18,y:l.y-18,textAnchor:"middle",dominantBaseline:"central",fill:"#a5b4fc",fontSize:9,fontWeight:700,fontFamily:"ui-monospace, monospace",children:k+1})]},l.id)})]})}):e.jsx("div",{className:"flex flex-1 w-full h-full items-center justify-center rounded-xl border border-slate-700/50 bg-slate-950/80 text-slate-500",children:"No tree generated"})}const D={inorder:{name:"In-Order",description:"Visits left subtree, then root, then right subtree. Produces sorted output for BSTs.",order:"Left → Root → Right"},preorder:{name:"Pre-Order",description:"Visits root first, then left subtree, then right subtree. Useful for copying trees.",order:"Root → Left → Right"},postorder:{name:"Post-Order",description:"Visits left subtree, then right subtree, then root. Useful for deleting trees.",order:"Left → Right → Root"},levelorder:{name:"Level-Order",description:"Visits nodes level by level from top to bottom, left to right. Also known as BFS.",order:"Top → Bottom, Left → Right"}},ve=["inorder","preorder","postorder","levelorder"],je=[{label:"Slow",value:600},{label:"Medium",value:300},{label:"Fast",value:100}];function Ne({traversalType:t,setTraversalType:s,nodeCount:n,stepIndex:r,totalSteps:m,processOrder:v,isPlaying:c,isFinished:x,speed:i,setSpeed:f,soundEnabled:d,onToggleSound:u,canGoNext:l,canGoPrev:p,onGenerate:S,onNextStep:y,onPrevStep:k,onPlay:j,onStop:N,onReset:w}){const g=D[t];return e.jsxs("div",{className:"flex flex-col gap-5 w-full md:w-72 shrink-0 overflow-y-auto max-h-full pr-1",children:[e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Traversal"}),e.jsx("div",{className:"grid grid-cols-2 gap-2",children:ve.map(h=>e.jsx("button",{onClick:()=>s(h),disabled:c,className:` + rounded-lg px-3 py-2 text-sm font-medium transition-all duration-200 + ${t===h?"bg-indigo-500/20 text-indigo-300 ring-1 ring-indigo-500/40 shadow-lg shadow-indigo-500/10":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50 hover:text-slate-300"} + disabled:opacity-50 disabled:cursor-not-allowed + `,children:D[h].name},h))}),e.jsxs("div",{className:"mt-3 rounded-lg bg-slate-800/40 p-3",children:[e.jsx("p",{className:"text-xs text-slate-400 leading-relaxed",children:g.description}),e.jsx("span",{className:"mt-2 inline-flex items-center rounded-full bg-violet-500/10 px-2 py-0.5 text-[10px] font-medium text-violet-400 ring-1 ring-violet-500/20",children:g.order})]})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Speed"}),e.jsx("div",{className:"flex gap-1",children:je.map(h=>e.jsx("button",{onClick:()=>f(h.value),className:` + flex-1 rounded-lg px-2 py-1.5 text-xs font-medium transition-all duration-200 + ${i===h.value?"bg-violet-500/20 text-violet-300 ring-1 ring-violet-500/40":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50 hover:text-slate-300"} + `,children:h.label},h.value))}),e.jsxs("button",{onClick:()=>u(!d),className:` + mt-3 w-full flex items-center justify-center gap-2 rounded-lg px-3 py-2 text-xs font-medium transition-all duration-200 + ${d?"bg-indigo-500/15 text-indigo-300 ring-1 ring-indigo-500/30":"bg-slate-800/50 text-slate-500 ring-1 ring-slate-700/30"} + `,children:[d?e.jsx(oe,{size:14}):e.jsx(ce,{size:14}),d?"Sound On":"Sound Off"]})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400",children:"Nodes"}),e.jsx("span",{className:"text-xs font-mono text-slate-400",children:n})]}),e.jsx("input",{type:"range",min:"3",max:"31",value:n,onChange:h=>!c&&S(Number(h.target.value)),disabled:c,className:"w-full accent-indigo-500 disabled:opacity-50"}),e.jsxs("div",{className:"flex justify-between mt-1",children:[e.jsx("span",{className:"text-[10px] text-slate-600",children:"3"}),e.jsx("span",{className:"text-[10px] text-slate-600",children:"31"})]})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Controls"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("button",{onClick:k,disabled:!p||c,className:"flex-1 flex items-center justify-center gap-1 rounded-lg bg-slate-800/60 px-3 py-2.5 text-sm font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300 disabled:opacity-30 disabled:cursor-not-allowed",children:[e.jsx(de,{size:16}),"Prev"]}),c?e.jsxs("button",{onClick:N,className:"flex-1 flex items-center justify-center gap-1 rounded-lg bg-gradient-to-r from-rose-500 to-pink-500 px-3 py-2.5 text-sm font-semibold text-white shadow-lg shadow-rose-500/25 transition-all hover:brightness-110",children:[e.jsx(me,{size:14}),"Stop"]}):e.jsxs("button",{onClick:j,disabled:x,className:"flex-1 flex items-center justify-center gap-1 rounded-lg bg-gradient-to-r from-indigo-500 to-violet-500 px-3 py-2.5 text-sm font-semibold text-white shadow-lg shadow-indigo-500/25 transition-all hover:brightness-110 disabled:opacity-50 disabled:cursor-not-allowed",children:[e.jsx(xe,{size:14}),"Play"]}),e.jsxs("button",{onClick:y,disabled:!l||c||x,className:"flex-1 flex items-center justify-center gap-1 rounded-lg bg-slate-800/60 px-3 py-2.5 text-sm font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300 disabled:opacity-30 disabled:cursor-not-allowed",children:["Next",e.jsx(ue,{size:16})]})]}),m>0&&e.jsxs("div",{className:"mt-3 flex items-center justify-between",children:[e.jsx("span",{className:"text-xs text-slate-500",children:"Step"}),e.jsxs("span",{className:"text-sm font-mono font-semibold text-indigo-400",children:[Math.max(0,r+1)," / ",m]})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsxs("button",{onClick:()=>S(),disabled:c,className:"flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300 disabled:opacity-50 disabled:cursor-not-allowed",children:[e.jsx(fe,{size:12}),"New Tree"]}),e.jsxs("button",{onClick:w,disabled:c,className:"flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300 disabled:opacity-50 disabled:cursor-not-allowed",children:[e.jsx(pe,{size:12}),"Reset"]})]}),v.length>0&&e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Visit Order"}),e.jsx("div",{className:"flex flex-wrap gap-1.5",children:v.map((h,T)=>e.jsx("span",{className:"inline-flex items-center justify-center rounded-md bg-indigo-500/15 px-2 py-1 text-xs font-mono font-semibold text-indigo-300 ring-1 ring-indigo-500/20",children:h},T))})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Legend"}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-amber-400"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Current Node"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-indigo-500"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Processed"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-slate-600"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Visited"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-5 rounded-sm bg-slate-800 ring-1 ring-slate-600"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Unvisited"})]})]})]})]})}function B(t,s){t&&(s.push({nodeId:t.id,action:"visit"}),B(t.left,s),s.push({nodeId:t.id,action:"process"}),B(t.right,s))}function E(t,s){t&&(s.push({nodeId:t.id,action:"visit"}),s.push({nodeId:t.id,action:"process"}),E(t.left,s),E(t.right,s))}function F(t,s){t&&(s.push({nodeId:t.id,action:"visit"}),F(t.left,s),F(t.right,s),s.push({nodeId:t.id,action:"process"}))}function ye(t,s){if(!t)return;const n=[t];for(;n.length>0;){const r=n.shift();s.push({nodeId:r.id,action:"visit"}),s.push({nodeId:r.id,action:"process"}),r.left&&n.push(r.left),r.right&&n.push(r.right)}}function we(t,s){const n=[];switch(s){case"inorder":B(t,n);break;case"preorder":E(t,n);break;case"postorder":F(t,n);break;case"levelorder":ye(t,n);break}return n}function Se(){const t=a.useRef(!0),s=a.useCallback(()=>he(),[]),n=a.useCallback(x=>{t.current=x},[]),r=a.useCallback((x,i,f="sine",d=.12)=>{if(!t.current)return;const u=s();if(!u)return;const l=u.createOscillator(),p=u.createGain();l.type=f,l.frequency.value=x,p.gain.setValueAtTime(d,u.currentTime),p.gain.exponentialRampToValueAtTime(.001,u.currentTime+i),l.connect(p),p.connect(u.destination),l.start(),l.stop(u.currentTime+i)},[s]),m=a.useCallback((x,i)=>{const d=200+Math.min(x/Math.max(i,1),1)*600;r(d,.12,"sine",.08)},[r]),v=a.useCallback((x,i)=>{const d=300+Math.min(x/Math.max(i,1),1)*700;r(d,.18,"triangle",.12)},[r]),c=a.useCallback(x=>{if(!t.current)return;const i=s();if(!i)return;const f=Math.min(x,20);for(let d=0;d_(15)),[c,x]=a.useState([]),[i,f]=a.useState(-1),[d,u]=a.useState(new Set),[l,p]=a.useState(new Set),[S,y]=a.useState(null),[k,j]=a.useState(!1),[N,w]=a.useState(300),g=a.useRef(null),[h,T]=a.useState([]),[P,Q]=a.useState(!0),{playVisitTone:G,playProcessTone:$,playCompleteSweep:W,setEnabled:U}=Se(),Z=a.useCallback(o=>{Q(o),U(o)},[U]),ee=a.useCallback(o=>{const b=o??n;o!==void 0&&r(o);const M=_(b);v(M),x([]),f(-1),u(new Set),p(new Set),y(null),T([]),g.current&&(clearInterval(g.current),g.current=null),j(!1)},[n]),V=a.useCallback(()=>{if(c.length>0)return c;const o=we(m,t);return x(o),o},[c,m,t]),R=a.useCallback((o,b,M=!0)=>{const X=new Set,Y=new Set,A=[];for(let C=0;C<=b;C++){const I=o[C];X.add(I.nodeId),I.action==="process"&&(Y.add(I.nodeId),A.includes(I.nodeId)||A.push(I.nodeId))}if(u(X),p(Y),y(o[b].nodeId),T(A),M){const C=o[b],I=m?K(m).length:1;C.action==="visit"?G(C.nodeId,I):C.action==="process"&&$(C.nodeId,I)}},[m,G,$]),te=a.useCallback(()=>{const o=V();o.length!==0&&f(b=>{const M=Math.min(b+1,o.length-1);return R(o,M,!0),M})},[V,R]),se=a.useCallback(()=>{if(i<=0){f(-1),u(new Set),p(new Set),y(null),T([]);return}f(o=>{const b=o-1;return R(c,b,!1),b})},[i,c,R]),z=a.useCallback(()=>{g.current&&(clearInterval(g.current),g.current=null),j(!1)},[]),re=a.useCallback(()=>{const o=V();if(o.length===0)return;j(!0);let b=i;g.current=window.setInterval(()=>{if(b++,b>=o.length){g.current&&clearInterval(g.current),g.current=null,j(!1),W(o.length);return}f(b),R(o,b,!0)},N)},[V,i,N,R,W]),O=a.useCallback(()=>{z(),x([]),f(-1),u(new Set),p(new Set),y(null),T([])},[z]),ne=a.useCallback(o=>{O(),s(o)},[O]),le=i=0,ie=c.length>0&&i===c.length-1;return{traversalType:t,setTraversalType:ne,nodeCount:n,root:m,stepIndex:i,totalSteps:c.length,visitedIds:d,processedIds:l,currentId:S,processOrder:h,isPlaying:k,isFinished:ie,speed:N,setSpeed:w,soundEnabled:P,toggleSound:Z,canGoNext:le,canGoPrev:ae,generateNew:ee,nextStep:te,prevStep:se,play:re,stopPlaying:z,reset:O}}function Oe(){const{traversalType:t,setTraversalType:s,nodeCount:n,root:r,stepIndex:m,totalSteps:v,visitedIds:c,processedIds:x,currentId:i,processOrder:f,isPlaying:d,isFinished:u,speed:l,setSpeed:p,soundEnabled:S,toggleSound:y,canGoNext:k,canGoPrev:j,generateNew:N,nextStep:w,prevStep:g,play:h,stopPlaying:T,reset:P}=ke();return e.jsxs("div",{className:"flex flex-1 flex-col md:flex-row gap-4 md:gap-6 overflow-auto p-4 md:p-6",children:[e.jsx("div",{className:"order-last md:order-first flex md:flex-1 flex-col items-center justify-center gap-3 min-h-[40vh] md:min-h-0 max-h-[50vh] md:max-h-none overflow-auto",children:e.jsx(be,{root:r,visitedIds:c,processedIds:x,currentId:i,processOrder:f})}),e.jsx(Ne,{traversalType:t,setTraversalType:s,nodeCount:n,stepIndex:m,totalSteps:v,processOrder:f,isPlaying:d,isFinished:u,speed:l,setSpeed:p,soundEnabled:S,onToggleSound:y,canGoNext:k,canGoPrev:j,onGenerate:N,onNextStep:w,onPrevStep:g,onPlay:h,onStop:T,onReset:P})]})}export{Oe as default}; diff --git a/docs/assets/TriePage-3KlcWkEC.js b/docs/assets/TriePage-3KlcWkEC.js new file mode 100644 index 0000000..a31d78e --- /dev/null +++ b/docs/assets/TriePage-3KlcWkEC.js @@ -0,0 +1,4 @@ +import{c as B,r as d,j as e,e as D,X as K}from"./index-BfWfBQOp.js";import{C as Q,a as H}from"./chevron-right-CNA9GG_w.js";import{P as J}from"./play-WRQgdyAG.js";import{S as U}from"./square-BSu6WBc6.js";import{R as Z}from"./rotate-ccw-EKzY5q_W.js";import{P as ee}from"./plus-BEk43_MF.js";import{V as te,a as se}from"./volume-x-ChIHiT28.js";import{g as ne}from"./audioContext-NbgqvQGz.js";const re=[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]],ae=B("refresh-cw",re);function ie({layout:a,matchedNodeIds:r,currentStepNodeId:o}){const{viewBox:u,edges:l}=d.useMemo(()=>{if(a.length===0)return{viewBox:"0 0 100 100",edges:[]};let s=1/0,n=-1/0,t=1/0,i=-1/0;for(const g of a)s=Math.min(s,g.x),n=Math.max(n,g.x),t=Math.min(t,g.y),i=Math.max(i,g.y);const h=40,x=`${s-h} ${t-h} ${n-s+h*2} ${i-t+h*2}`,c=new Map;for(const g of a)c.set(g.id,g);const m=[];for(const g of a)if(g.parentId&&c.has(g.parentId)){const y=c.get(g.parentId),S=r.has(g.id)&&r.has(y.id);m.push({x1:y.x,y1:y.y,x2:g.x,y2:g.y,highlighted:S})}return{viewBox:x,edges:m}},[a,r]);return a.length===0?e.jsx("div",{className:"flex flex-1 w-full min-h-[200px] items-center justify-center rounded-xl border border-slate-700/50 bg-slate-950/80 text-slate-500 text-sm",children:"Add words to build the trie"}):e.jsx("div",{className:"flex-1 w-full min-h-[200px] rounded-xl border border-slate-700/50 bg-slate-950/80 p-2 shadow-2xl backdrop-blur-sm overflow-hidden",children:e.jsxs("svg",{viewBox:u,className:"w-full h-full",preserveAspectRatio:"xMidYMid meet",children:[l.map((s,n)=>e.jsx("line",{x1:s.x1,y1:s.y1,x2:s.x2,y2:s.y2,stroke:s.highlighted?"#818cf8":"#334155",strokeWidth:s.highlighted?2.5:1.5,strokeOpacity:s.highlighted?1:.5},n)),a.map(s=>{const n=r.has(s.id),t=o===s.id,i=s.depth===0;let h="#1e293b",x="#475569",c="#94a3b8";t?(h="#312e81",x="#818cf8",c="#e0e7ff"):n&&(h="#1e1b4b",x="#6366f1",c="#c7d2fe"),s.isEndOfWord&&!t&&(x=n?"#34d399":"#059669");const m=i?16:14;return e.jsxs("g",{children:[e.jsx("circle",{cx:s.x,cy:s.y,r:m,fill:h,stroke:x,strokeWidth:t?3:2}),t&&e.jsx("circle",{cx:s.x,cy:s.y,r:m+4,fill:"none",stroke:"#818cf8",strokeWidth:1.5,strokeOpacity:.4,className:"animate-pulse"}),e.jsx("text",{x:s.x,y:s.y,textAnchor:"middle",dominantBaseline:"central",fill:c,fontSize:i?10:12,fontWeight:700,fontFamily:"ui-monospace, monospace",children:i?"root":s.char}),s.isEndOfWord&&e.jsx("circle",{cx:s.x+m-2,cy:s.y-m+2,r:4,fill:"#34d399",stroke:"#064e3b",strokeWidth:1})]},s.id)})]})})}function oe({words:a,searchMode:r,setSearchMode:o,query:u,setQuery:l,steps:s,stepIndex:n,searchResults:t,isPlaying:i,canGoNext:h,canGoPrev:x,onSearch:c,onNextStep:m,onPrevStep:g,onPlay:y,onStop:S,onReset:W,newWord:v,setNewWord:M,onAddWord:T,onRemoveWord:N,onLoadSample:C,soundEnabled:k,onToggleSound:P}){const w=n>=0&&ne.jsx("button",{onClick:()=>o(p),className:` + flex-1 rounded-lg px-3 py-2.5 text-sm font-medium transition-all duration-200 + ${r===p?"bg-indigo-500/20 text-indigo-300 ring-1 ring-indigo-500/40 shadow-lg shadow-indigo-500/10":"bg-slate-800/50 text-slate-400 hover:bg-slate-700/50 hover:text-slate-300"} + `,children:p==="prefix"?"Prefix":"Full Word"},p))})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Search"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("input",{type:"text",value:u,onChange:p=>l(p.target.value),onKeyDown:p=>p.key==="Enter"&&c(),placeholder:r==="prefix"?"Type a prefix...":"Type a word...",className:"flex-1 rounded-lg bg-slate-800/60 px-3 py-2 text-sm text-white placeholder-slate-500 outline-none ring-1 ring-slate-700/50 focus:ring-indigo-500/50"}),e.jsx("button",{onClick:c,disabled:!u.trim(),className:"flex items-center justify-center rounded-lg bg-indigo-500/20 px-3 py-2 text-indigo-300 ring-1 ring-indigo-500/40 transition-all hover:bg-indigo-500/30 disabled:opacity-40 disabled:cursor-not-allowed",children:e.jsx(D,{size:16})})]})]}),s.length>0&&e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Steps"}),e.jsxs("div",{className:"flex gap-2 mb-3",children:[e.jsxs("button",{onClick:g,disabled:!x||i,className:"flex-1 flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-sm font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300 disabled:opacity-30 disabled:cursor-not-allowed",children:[e.jsx(Q,{size:16})," Prev"]}),i?e.jsx("button",{onClick:S,className:"flex items-center justify-center rounded-lg bg-rose-500/15 px-3 py-2 text-rose-300 ring-1 ring-rose-500/30 transition-all hover:bg-rose-500/25",children:e.jsx(U,{size:14})}):e.jsx("button",{onClick:y,disabled:s.length===0,className:"flex items-center justify-center rounded-lg bg-emerald-500/15 px-3 py-2 text-emerald-300 ring-1 ring-emerald-500/30 transition-all hover:bg-emerald-500/25 disabled:opacity-30 disabled:cursor-not-allowed",children:e.jsx(J,{size:16})}),e.jsxs("button",{onClick:m,disabled:!h||i,className:"flex-1 flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-sm font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300 disabled:opacity-30 disabled:cursor-not-allowed",children:["Next ",e.jsx(H,{size:16})]})]}),e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("span",{className:"text-xs text-slate-500",children:"Step"}),e.jsxs("span",{className:"text-sm font-mono font-semibold text-indigo-400",children:[Math.max(0,n+1)," / ",s.length]})]}),w&&e.jsx("div",{className:`rounded-lg px-3 py-2 text-xs font-medium ${w.action==="match"||w.action==="prefix-match"?"bg-emerald-500/15 text-emerald-300 ring-1 ring-emerald-500/30":w.action==="not-found"?"bg-rose-500/15 text-rose-300 ring-1 ring-rose-500/30":"bg-slate-800/60 text-slate-300 ring-1 ring-slate-700/50"}`,children:w.description}),e.jsxs("button",{onClick:W,className:"mt-2 w-full flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300",children:[e.jsx(Z,{size:12})," Clear Search"]})]}),t.length>0&&e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsxs("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:["Results (",t.length,")"]}),e.jsx("div",{className:"flex flex-wrap gap-1.5 max-h-32 overflow-y-auto",children:t.map(p=>e.jsx("span",{className:"rounded-full bg-emerald-500/10 px-2.5 py-0.5 text-[11px] font-medium text-emerald-300 ring-1 ring-emerald-500/20",children:p},p))})]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsxs("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:["Words (",a.length,")"]}),e.jsxs("div",{className:"flex gap-2 mb-3",children:[e.jsx("input",{type:"text",value:v,onChange:p=>M(p.target.value),onKeyDown:p=>p.key==="Enter"&&T(),placeholder:"Add a word...",className:"flex-1 rounded-lg bg-slate-800/60 px-3 py-2 text-sm text-white placeholder-slate-500 outline-none ring-1 ring-slate-700/50 focus:ring-indigo-500/50"}),e.jsx("button",{onClick:T,disabled:!v.trim(),className:"flex items-center justify-center rounded-lg bg-emerald-500/15 px-3 py-2 text-emerald-300 ring-1 ring-emerald-500/30 transition-all hover:bg-emerald-500/25 disabled:opacity-40 disabled:cursor-not-allowed",children:e.jsx(ee,{size:16})})]}),e.jsx("div",{className:"flex flex-wrap gap-1.5 max-h-40 overflow-y-auto",children:a.map(p=>e.jsxs("span",{className:"group inline-flex items-center gap-1 rounded-full bg-slate-800/60 px-2.5 py-0.5 text-[11px] font-medium text-slate-400 ring-1 ring-slate-700/40",children:[p,e.jsx("button",{onClick:()=>N(p),className:"opacity-0 group-hover:opacity-100 transition-opacity text-slate-500 hover:text-rose-400",children:e.jsx(K,{size:10})})]},p))}),e.jsxs("button",{onClick:C,className:"mt-3 w-full flex items-center justify-center gap-1.5 rounded-lg bg-slate-800/60 px-3 py-2 text-xs font-medium text-slate-400 transition-all hover:bg-slate-700/60 hover:text-slate-300",children:[e.jsx(ae,{size:12})," Load Sample Words"]})]}),e.jsxs("button",{onClick:P,className:`flex items-center justify-center gap-2 rounded-xl px-4 py-2.5 text-sm font-medium transition-all ${k?"bg-indigo-500/15 text-indigo-300 ring-1 ring-indigo-500/30 hover:bg-indigo-500/25":"bg-slate-800/60 text-slate-500 ring-1 ring-slate-700/40 hover:bg-slate-700/60"}`,children:[k?e.jsx(te,{size:16}):e.jsx(se,{size:16}),k?"Sound On":"Sound Off"]}),e.jsxs("div",{className:"rounded-xl border border-slate-700/50 bg-slate-900/60 p-4 backdrop-blur-sm",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400 mb-3",children:"Legend"}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-3 rounded-full bg-slate-700 ring-1 ring-slate-500"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Normal Node"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-3 rounded-full bg-indigo-900 ring-1 ring-indigo-500"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Matched Path"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"h-3 w-3 rounded-full bg-indigo-900 ring-2 ring-indigo-400"}),e.jsx("span",{className:"text-xs text-slate-400",children:"Current Step"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"relative h-3 w-3 rounded-full bg-slate-700 ring-1 ring-emerald-500",children:e.jsx("div",{className:"absolute -top-0.5 -right-0.5 h-1.5 w-1.5 rounded-full bg-emerald-400"})}),e.jsx("span",{className:"text-xs text-slate-400",children:"End of Word"})]})]})]})]})}let F=0;function X(a,r){return{id:`node-${F++}`,char:a,children:new Map,isEndOfWord:!1,depth:r}}function le(){F=0}function ce(a,r){let o=a;for(let u=0;uc[0].localeCompare(m[0]));for(const[,c]of h){const m=u;s(c,n.id),i.push((m+u-1)/2)}const x=i.reduce((c,m)=>c+m,0)/i.length;r.push({id:n.id,char:n.char,isEndOfWord:n.isEndOfWord,x:x*l,y:n.depth*70,parentId:t,depth:n.depth})}return s(a,null),r}const $=["apple","app","ape","apply","bat","ball","ban","cat","car","card","care","dog","do","dot"];function O(a){le();const r=X("",0);for(const o of a)ce(r,o);return r}function he(){const[a,r]=d.useState($),[o,u]=d.useState(()=>O($)),[l,s]=d.useState("prefix"),[n,t]=d.useState(""),[i,h]=d.useState([]),[x,c]=d.useState(-1),[m,g]=d.useState(new Set),[y,S]=d.useState([]),[W,v]=d.useState(!1),[M,T]=d.useState(500),[N,C]=d.useState(""),k=d.useMemo(()=>xe(o),[o]),P=x>=0&&x{if(!n.trim())return;const f=n.trim().toLowerCase(),{result:b,steps:q}=l==="word"?de(o,f):ue(o,f);h(q),c(-1),g(new Set(b.matchedPath)),S(b.matches),v(!1)},[n,l,o]),p=d.useCallback(()=>{c(f=>f{c(f=>f>0?f-1:f)},[]),E=d.useCallback(()=>{i.length!==0&&(v(!0),c(0))},[i]),R=d.useCallback(()=>{v(!1)},[]),j=d.useCallback(()=>{h([]),c(-1),g(new Set),S([]),v(!1)},[]),z=d.useCallback(()=>{const f=N.trim().toLowerCase();if(!f||a.includes(f))return;const b=[...a,f];r(b),u(O(b)),C(""),j()},[N,a,j]),A=d.useCallback(f=>{const b=a.filter(q=>q!==f);r(b),u(O(b)),j()},[a,j]),G=d.useCallback(()=>{r($),u(O($)),C(""),j()},[j]),V=x0;return{words:a,root:o,layout:k,searchMode:l,setSearchMode:s,query:n,setQuery:t,steps:i,stepIndex:x,currentStepNodeId:P,matchedNodeIds:m,searchResults:y,isPlaying:W,speed:M,setSpeed:T,canGoNext:V,canGoPrev:I,search:w,nextStep:p,prevStep:L,play:E,stopPlaying:R,resetSearch:j,newWord:N,setNewWord:C,addWord:z,removeWord:A,loadSampleWords:G}}const _=[261.63,293.66,329.63,392,440,523.25,587.33,659.25];function me(){const a=d.useRef(!0),r=d.useCallback(()=>ne(),[]),o=d.useCallback(t=>{a.current=t},[]),u=d.useCallback(()=>a.current,[]),l=d.useCallback(t=>{if(!a.current)return;const i=r();if(!i)return;const h=_[t%_.length],x=i.createOscillator(),c=i.createGain();x.type="sine",x.frequency.value=h,c.gain.setValueAtTime(.08,i.currentTime),c.gain.exponentialRampToValueAtTime(.001,i.currentTime+.15),x.connect(c),c.connect(i.destination),x.start(),x.stop(i.currentTime+.15)},[r]),s=d.useCallback(()=>{if(!a.current)return;const t=r();if(!t)return;[523.25,659.25,783.99].forEach((h,x)=>{const c=t.createOscillator(),m=t.createGain();c.type="sine",c.frequency.value=h,m.gain.setValueAtTime(.1,t.currentTime+x*.1),m.gain.exponentialRampToValueAtTime(.001,t.currentTime+x*.1+.15),c.connect(m),m.connect(t.destination),c.start(t.currentTime+x*.1),c.stop(t.currentTime+x*.1+.15)})},[r]),n=d.useCallback(()=>{if(!a.current)return;const t=r();if(!t)return;const i=t.createOscillator(),h=t.createGain();i.type="sine",i.frequency.value=350,i.frequency.setValueAtTime(350,t.currentTime),i.frequency.linearRampToValueAtTime(220,t.currentTime+.25),h.gain.setValueAtTime(.08,t.currentTime),h.gain.exponentialRampToValueAtTime(.001,t.currentTime+.3),i.connect(h),h.connect(t.destination),i.start(),i.stop(t.currentTime+.3)},[r]);return{playTraverseTone:l,playMatchTone:s,playNotFoundTone:n,setEnabled:o,isEnabled:u}}function we(){const{words:a,layout:r,searchMode:o,setSearchMode:u,query:l,setQuery:s,steps:n,stepIndex:t,currentStepNodeId:i,matchedNodeIds:h,searchResults:x,isPlaying:c,speed:m,setSpeed:g,canGoNext:y,canGoPrev:S,search:W,nextStep:v,prevStep:M,play:T,stopPlaying:N,resetSearch:C,newWord:k,setNewWord:P,addWord:w,removeWord:p,loadSampleWords:L}=he(),{playTraverseTone:E,playMatchTone:R,playNotFoundTone:j,setEnabled:z}=me(),[A,G]=d.useState(!0),V=()=>{const b=!A;G(b),z(b)},I=d.useRef(t);d.useEffect(()=>{if(t<0||t===I.current){I.current=t;return}I.current=t;const b=n[t];b&&(b.action==="visit"?E(b.char?b.char.charCodeAt(0)%8:0):b.action==="match"||b.action==="prefix-match"?R():b.action==="not-found"&&j())},[t,n,E,R,j]);const f=d.useRef(null);return d.useEffect(()=>{if(!c){f.current&&clearTimeout(f.current);return}if(!y){N();return}return f.current=setTimeout(()=>{v()},m),()=>{f.current&&clearTimeout(f.current)}},[c,t,y,m,v,N]),e.jsxs("div",{className:"flex flex-1 flex-col md:flex-row gap-4 md:gap-6 overflow-auto p-4 md:p-6",children:[e.jsx(oe,{words:a,searchMode:o,setSearchMode:u,query:l,setQuery:s,steps:n,stepIndex:t,searchResults:x,isPlaying:c,speed:m,setSpeed:g,canGoNext:y,canGoPrev:S,onSearch:W,onNextStep:v,onPrevStep:M,onPlay:T,onStop:N,onReset:C,newWord:k,setNewWord:P,onAddWord:w,onRemoveWord:p,onLoadSample:L,soundEnabled:A,onToggleSound:V}),e.jsx("div",{className:"order-last md:order-first flex md:flex-1 flex-col items-center justify-center gap-3 min-h-[40vh] md:min-h-0 max-h-[50vh] md:max-h-none overflow-auto",children:e.jsx(ie,{layout:r,matchedNodeIds:h,currentStepNodeId:i})})]})}export{we as default}; diff --git a/docs/assets/WorldMapGamePage-B75VoKQY.js b/docs/assets/WorldMapGamePage-B75VoKQY.js new file mode 100644 index 0000000..7c700ed --- /dev/null +++ b/docs/assets/WorldMapGamePage-B75VoKQY.js @@ -0,0 +1 @@ +import{c as te,r as b,j as t,P as se}from"./index-BfWfBQOp.js";import{S as ae}from"./shuffle-Ri9xSsK2.js";import{C as oe,a as ne}from"./chevron-right-CNA9GG_w.js";import{P as re}from"./play-WRQgdyAG.js";import{R as ie}from"./route-CNnmHrEb.js";import{V as le,a as ce}from"./volume-x-ChIHiT28.js";import{g as de}from"./audioContext-NbgqvQGz.js";const ue=[["path",{d:"M19.07 4.93A10 10 0 0 0 6.99 3.34",key:"z3du51"}],["path",{d:"M4 6h.01",key:"oypzma"}],["path",{d:"M2.29 9.62A10 10 0 1 0 21.31 8.35",key:"qzzz0"}],["path",{d:"M16.24 7.76A6 6 0 1 0 8.23 16.67",key:"1yjesh"}],["path",{d:"M12 18h.01",key:"mhygvu"}],["path",{d:"M17.99 11.66A6 6 0 0 1 15.77 16.67",key:"1u2y91"}],["circle",{cx:"12",cy:"12",r:"2",key:"1c9p78"}],["path",{d:"m13.41 10.59 5.66-5.66",key:"mhq4k0"}]],he=te("radar",ue),pe=[{name:"North America",path:"M45 82C82 46 145 49 196 75C229 59 287 72 331 102C366 126 369 165 337 188C312 207 287 210 264 235C232 268 178 250 149 222C118 192 78 187 56 150C38 119 28 99 45 82Z",fill:"#14532d"},{name:"Greenland",path:"M285 42C332 20 390 35 404 75C388 111 325 119 286 92C267 78 265 55 285 42Z",fill:"#475569"},{name:"Central America",path:"M246 230C277 232 307 242 329 263C307 276 273 267 246 249C232 240 232 231 246 230Z",fill:"#166534"},{name:"South America",path:"M308 264C352 270 383 315 372 374C364 424 334 474 296 483C281 443 259 405 264 359C269 314 281 281 308 264Z",fill:"#15803d"},{name:"Europe",path:"M438 122C470 96 535 91 575 117C602 137 593 166 558 176C522 186 489 177 454 165C427 156 416 139 438 122Z",fill:"#0f766e"},{name:"Africa",path:"M498 202C553 184 612 223 627 283C640 336 608 409 552 425C514 397 484 340 482 283C480 244 482 216 498 202Z",fill:"#166534"},{name:"Middle East",path:"M572 188C615 178 657 196 674 226C648 245 603 239 580 217C568 206 565 194 572 188Z",fill:"#3f6212"},{name:"Asia",path:"M600 111C683 52 842 83 927 168C910 223 836 246 775 229C728 216 703 257 655 244C611 232 566 159 600 111Z",fill:"#164e63"},{name:"Southeast Asia",path:"M728 252C772 247 824 281 833 322C800 335 755 317 728 287C714 271 714 258 728 252Z",fill:"#0f766e"},{name:"Australia",path:"M794 350C850 316 932 335 949 394C897 437 813 426 774 381C760 365 771 354 794 350Z",fill:"#15803d"},{name:"New Zealand",path:"M958 420C979 425 987 448 970 461C951 456 941 432 958 420Z",fill:"#15803d"}],xe=["M186 78C184 128 197 172 230 214","M126 172C171 164 216 173 260 190","M231 237C262 244 292 252 323 263","M303 280C329 305 342 335 335 374","M336 312C350 304 362 304 376 318","M451 140C482 132 515 134 548 149","M496 171C501 144 518 124 545 111","M529 196C540 236 540 277 530 321","M565 223C594 250 611 286 617 329","M591 190C613 203 639 212 671 221","M638 130C675 145 713 153 754 153","M690 184C729 192 768 201 808 216","M757 238C759 278 770 303 807 320","M835 153C841 191 832 219 808 236","M831 365C861 384 892 394 928 396"],me=[{text:"CANADA",x:160,y:118},{text:"UNITED STATES",x:190,y:178},{text:"MEXICO",x:250,y:222},{text:"BRAZIL",x:338,y:336},{text:"ARGENTINA",x:315,y:424},{text:"EUROPE",x:507,y:139},{text:"NORTH AFRICA",x:548,y:246},{text:"SOUTH AFRICA",x:560,y:390},{text:"MIDDLE EAST",x:632,y:210},{text:"INDIA",x:710,y:232},{text:"CHINA",x:779,y:173},{text:"JAPAN",x:890,y:161},{text:"SOUTHEAST ASIA",x:770,y:295},{text:"AUSTRALIA",x:860,y:390}];function ge({airports:s,routes:i,source:n,destination:l,currentStep:o,plan:u,flightProgress:c,onSelectSource:x,onSelectDestination:m}){const h=b.useMemo(()=>new Map(s.map(a=>[a.code,a])),[s]),j=new Set(o?.visited??[]),y=new Set((o?.frontier??[]).map(a=>a.code)),S=o?.route?.length?o.route:u.path,g=new Set(S.slice(0,-1).map((a,d)=>[a,S[d+1]].sort().join("-"))),p=o?.relaxedRoute?[o.relaxedRoute.from,o.relaxedRoute.to].sort().join("-"):null,k=b.useMemo(()=>{if(!c)return null;const a=h.get(c.from),d=h.get(c.to);if(!a||!d)return null;const f=Math.sin(c.progress*Math.PI)*-44;return{x:a.x+(d.x-a.x)*c.progress,y:a.y+(d.y-a.y)*c.progress+f,angle:Math.atan2(d.y-a.y,d.x-a.x)*(180/Math.PI)}},[h,c]);return t.jsxs("div",{className:"relative min-h-[620px] flex-1 overflow-hidden rounded-[1.75rem] border border-slate-700/50 bg-slate-950/90 shadow-2xl shadow-black/40",children:[t.jsx("div",{className:"absolute inset-0 bg-[radial-gradient(circle_at_18%_22%,rgba(14,165,233,0.16),transparent_28%),radial-gradient(circle_at_78%_72%,rgba(59,130,246,0.12),transparent_30%)]"}),t.jsxs("div",{className:"absolute left-5 top-5 z-20 rounded-2xl border border-slate-700/60 bg-slate-950/85 p-4 shadow-xl shadow-black/30 backdrop-blur-sm",children:[t.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-[0.24em] text-sky-400",children:"Global Air Traffic Network"}),t.jsxs("div",{className:"mt-2 flex gap-4 text-xs text-slate-300",children:[t.jsxs("span",{children:[t.jsx("strong",{className:"font-mono text-white",children:s.length})," airports"]}),t.jsxs("span",{children:[t.jsx("strong",{className:"font-mono text-white",children:i.length})," routes"]}),t.jsxs("span",{children:[t.jsx("strong",{className:"font-mono text-white",children:u.path.length||0})," hops"]})]})]}),o&&t.jsxs("div",{className:"absolute bottom-5 left-5 z-20 max-w-md rounded-2xl border border-slate-700/60 bg-slate-950/90 p-4 shadow-xl shadow-black/35 backdrop-blur-sm",children:[t.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-[0.24em] text-indigo-300",children:"Algorithm Radar"}),t.jsx("p",{className:"mt-1 text-xs leading-relaxed text-slate-300",children:o.description}),o.frontier.length>0&&t.jsx("div",{className:"mt-3 flex flex-wrap gap-1.5",children:o.frontier.slice(0,7).map(a=>t.jsxs("span",{className:"rounded-full bg-sky-500/10 px-2 py-1 text-[10px] font-mono font-semibold text-sky-300 ring-1 ring-sky-500/25",children:[a.code,": ",Number.isFinite(a.priority)?a.priority:"∞"]},`${a.code}-${a.priority}`))})]}),t.jsxs("svg",{viewBox:"0 0 1000 520",className:"relative z-10 h-full w-full",preserveAspectRatio:"xMidYMid meet",children:[t.jsxs("defs",{children:[t.jsxs("filter",{id:"world-glow",x:"-40%",y:"-40%",width:"180%",height:"180%",children:[t.jsx("feGaussianBlur",{stdDeviation:"4",result:"blur"}),t.jsxs("feMerge",{children:[t.jsx("feMergeNode",{in:"blur"}),t.jsx("feMergeNode",{in:"SourceGraphic"})]})]}),t.jsx("filter",{id:"world-shadow",x:"-60%",y:"-60%",width:"220%",height:"220%",children:t.jsx("feDropShadow",{dx:"0",dy:"8",stdDeviation:"6",floodColor:"#020617",floodOpacity:"0.7"})}),t.jsxs("linearGradient",{id:"ocean",x1:"0",x2:"1",y1:"0",y2:"1",children:[t.jsx("stop",{offset:"0%",stopColor:"#07111f"}),t.jsx("stop",{offset:"55%",stopColor:"#082f49"}),t.jsx("stop",{offset:"100%",stopColor:"#020617"})]})]}),t.jsx("rect",{width:"1000",height:"520",rx:"28",fill:"url(#ocean)"}),[130,260,390].map(a=>t.jsx("path",{d:`M0 ${a}H1000`,stroke:"#38bdf8",strokeOpacity:"0.1",strokeDasharray:"7 10"},`lat-${a}`)),[125,250,375,500,625,750,875].map(a=>t.jsx("path",{d:`M${a} 0V520`,stroke:"#38bdf8",strokeOpacity:"0.08",strokeDasharray:"7 10"},`lon-${a}`)),t.jsx("path",{d:"M0 260H1000",stroke:"#67e8f9",strokeOpacity:"0.2",strokeDasharray:"8 9"}),t.jsx("path",{d:"M500 0V520",stroke:"#67e8f9",strokeOpacity:"0.14",strokeDasharray:"8 9"}),t.jsx("g",{filter:"url(#world-shadow)",children:pe.map(a=>t.jsx("path",{d:a.path,fill:a.fill,fillOpacity:"0.78",stroke:"#a7f3d0",strokeOpacity:"0.42",strokeWidth:"1.8"},a.name))}),t.jsx("g",{children:xe.map(a=>t.jsx("path",{d:a,fill:"none",stroke:"#d1fae5",strokeOpacity:"0.22",strokeWidth:"1",strokeDasharray:"4 5"},a))}),t.jsx("g",{children:me.map(a=>t.jsx("text",{x:a.x,y:a.y,textAnchor:"middle",fontSize:"11",fontWeight:"800",letterSpacing:"1.4",fill:"#e2e8f0",fillOpacity:"0.28",children:a.text},a.text))}),i.map(a=>{const d=h.get(a.source),f=h.get(a.destination);if(!d||!f)return null;const M=[a.source,a.destination].sort().join("-"),N=g.has(M),L=M===p,D=L?"#facc15":N?"#22c55e":"#334155",R=Math.min(120,Math.abs(d.x-f.x)*.12+28),I=(d.x+f.x)/2,K=(d.y+f.y)/2-R;return t.jsx("g",{children:t.jsx("path",{d:`M${d.x},${d.y} Q${I},${K} ${f.x},${f.y}`,fill:"none",stroke:D,strokeWidth:N||L?3:1.2,strokeOpacity:N||L?.92:.24,strokeDasharray:N?void 0:"5 8",filter:N||L?"url(#world-glow)":void 0})},a.id)}),s.map(a=>{const d=a.code===n,f=a.code===l,M=j.has(a.code),N=y.has(a.code),L=o?.airportCode===a.code,D=d||f||L||N||M||a.hubScore>=92,R=d?"#fde047":f?"#fb923c":L?"#38bdf8":M?"#22c55e":N?"#a78bfa":"#94a3b8";return t.jsxs("g",{className:"cursor-pointer",children:[t.jsxs("title",{children:[a.code," - ",a.city,", ",a.country]}),t.jsx("circle",{cx:a.x,cy:a.y,r:d||f?12:8,fill:"#020617",stroke:"#0f172a",strokeWidth:7,filter:"url(#world-shadow)"}),t.jsx("circle",{cx:a.x,cy:a.y,r:d||f?9:6,fill:R,fillOpacity:d||f||M||N||L?.96:.58,stroke:R,strokeWidth:L?4:2,onClick:I=>{I.shiftKey?m(a.code):x(a.code)}}),D&&t.jsx("text",{x:a.x,y:a.y-14,textAnchor:"middle",fontSize:"10",fontWeight:"800",fontFamily:"ui-monospace, monospace",fill:R,children:a.code})]},a.code)}),k&&t.jsxs("g",{transform:`translate(${k.x} ${k.y}) rotate(${k.angle})`,filter:"url(#world-glow)",children:[t.jsx("path",{d:"M-14 -5L18 0L-14 5L-8 0Z",fill:"#f8fafc",stroke:"#38bdf8",strokeWidth:"1.2"}),t.jsx("path",{d:"M-5 -3L-12 -13L2 -4Z",fill:"#bae6fd",opacity:"0.9"}),t.jsx("path",{d:"M-5 3L-12 13L2 4Z",fill:"#bae6fd",opacity:"0.9"})]})]}),t.jsxs("div",{className:"absolute bottom-5 right-5 z-20 hidden rounded-2xl border border-slate-700/60 bg-slate-950/85 p-4 text-[10px] text-slate-400 shadow-xl shadow-black/30 backdrop-blur-sm sm:block",children:[t.jsx("div",{className:"mb-2 font-semibold uppercase tracking-[0.24em] text-slate-500",children:"Tip"}),"Click an airport to set origin. Shift-click to set destination."]})]})}const O={dijkstra:{label:"Dijkstra",description:"Finds the lowest total travel time by relaxing routes through a priority queue.",metric:"Shortest time"},astar:{label:"A* Search",description:"Uses distance-to-destination as a heuristic to guide the priority queue.",metric:"Guided shortest path"},bfs:{label:"BFS",description:"Ignores weights and searches by fewest airport connections.",metric:"Fewest stops"},greedy:{label:"Greedy",description:"Always flies toward the airport geographically closest to the destination.",metric:"Nearest-looking route"}},fe=["dijkstra","astar","bfs","greedy"];function be({airports:s,scenarios:i,source:n,destination:l,algorithm:o,plan:u,currentStep:c,stepIndex:x,totalSteps:m,phase:h,isPlaying:j,soundEnabled:y,onSourceChange:S,onDestinationChange:g,onAlgorithmChange:p,onLoadScenario:k,onPlanRoute:a,onStepBack:d,onStepForward:f,onPlay:M,onFly:N,onToggleSound:L}){return t.jsxs("aside",{className:"flex w-full shrink-0 flex-col gap-4 overflow-y-auto xl:w-88",children:[t.jsxs("section",{className:"rounded-2xl border border-sky-500/20 bg-slate-950/75 p-4 shadow-2xl shadow-black/30 backdrop-blur-sm",children:[t.jsxs("div",{className:"mb-3 flex items-center gap-3",children:[t.jsx("div",{className:"flex h-10 w-10 items-center justify-center rounded-xl bg-sky-500/15 text-sky-300 ring-1 ring-sky-500/30",children:t.jsx(se,{size:18})}),t.jsxs("div",{children:[t.jsx("h3",{className:"text-sm font-bold text-white",children:"World Flight Planner"}),t.jsx("p",{className:"text-[10px] text-slate-500",children:"Airport-code simulator inspired by public airport datasets."})]})]}),t.jsx("p",{className:"text-xs leading-relaxed text-slate-400",children:"Pick countries through their major airport codes, then compare how different algorithms choose routes across global hubs."})]}),t.jsxs("section",{className:"rounded-2xl border border-slate-700/50 bg-slate-950/75 p-4 shadow-xl shadow-black/20 backdrop-blur-sm",children:[t.jsx("h3",{className:"mb-3 text-xs font-semibold uppercase tracking-wider text-slate-400",children:"Travel Request"}),t.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[t.jsx(X,{label:"Origin",value:n,airports:s,onChange:S}),t.jsx(X,{label:"Destination",value:l,airports:s,onChange:g})]}),t.jsxs("button",{onClick:a,className:"mt-3 flex w-full items-center justify-center gap-2 rounded-xl bg-sky-500/15 px-3 py-2 text-xs font-semibold text-sky-300 ring-1 ring-sky-500/30 transition hover:bg-sky-500/25",children:[t.jsx(he,{size:13})," Recalculate route"]})]}),t.jsxs("section",{className:"rounded-2xl border border-slate-700/50 bg-slate-950/75 p-4 shadow-xl shadow-black/20 backdrop-blur-sm",children:[t.jsx("h3",{className:"mb-3 text-xs font-semibold uppercase tracking-wider text-slate-400",children:"Algorithms"}),t.jsx("div",{className:"grid gap-2",children:fe.map(D=>t.jsxs("button",{onClick:()=>p(D),className:`rounded-xl p-3 text-left transition ${o===D?"bg-indigo-500/15 text-indigo-200 ring-1 ring-indigo-500/35":"bg-slate-900/70 text-slate-400 ring-1 ring-slate-800/80 hover:bg-slate-800/80"}`,children:[t.jsxs("span",{className:"flex items-center justify-between text-xs font-bold",children:[O[D].label,t.jsx("span",{className:"text-[9px] uppercase tracking-wider opacity-60",children:O[D].metric})]}),t.jsx("span",{className:"mt-1 block text-[10px] leading-snug opacity-75",children:O[D].description})]},D))})]}),t.jsxs("section",{className:"rounded-2xl border border-slate-700/50 bg-slate-950/75 p-4 shadow-xl shadow-black/20 backdrop-blur-sm",children:[t.jsx("h3",{className:"mb-3 text-xs font-semibold uppercase tracking-wider text-slate-400",children:"Preset Missions"}),t.jsx("div",{className:"grid gap-2",children:i.map(D=>t.jsxs("button",{onClick:()=>k(D.id),className:"rounded-xl bg-slate-900/70 p-3 text-left ring-1 ring-slate-800/80 transition hover:bg-slate-800/80",children:[t.jsxs("span",{className:"flex items-center gap-2 text-xs font-bold text-slate-200",children:[t.jsx(ae,{size:12})," ",D.title]}),t.jsx("span",{className:"mt-1 block text-[10px] leading-snug text-slate-500",children:D.description})]},D.id))})]}),t.jsxs("section",{className:"rounded-2xl border border-emerald-500/20 bg-slate-950/75 p-4 shadow-xl shadow-black/20 backdrop-blur-sm",children:[t.jsxs("div",{className:"mb-3 flex items-center justify-between",children:[t.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400",children:"Flight Plan"}),t.jsx("span",{className:"rounded-full bg-emerald-500/10 px-2 py-0.5 text-[9px] font-bold uppercase tracking-wider text-emerald-300 ring-1 ring-emerald-500/25",children:h})]}),t.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[t.jsx(H,{label:"Distance",value:`${u.totalDistanceKm.toLocaleString()} km`}),t.jsx(H,{label:"Duration",value:`${u.totalDurationHours}h`}),t.jsx(H,{label:"Stops",value:u.stops.toString()}),t.jsx(H,{label:"Est. Cost",value:`$${u.totalCostUsd.toLocaleString()}`})]}),t.jsxs("div",{className:"mt-3 rounded-xl bg-slate-900/70 p-3 ring-1 ring-slate-800/80",children:[t.jsx("p",{className:"mb-2 text-[10px] font-semibold uppercase tracking-wider text-slate-500",children:"Route"}),t.jsx("div",{className:"flex flex-wrap gap-1",children:u.path.map((D,R)=>t.jsx("span",{className:"rounded-md bg-emerald-500/10 px-1.5 py-0.5 text-[10px] font-mono font-semibold text-emerald-300 ring-1 ring-emerald-500/20",children:D},`${D}-${R}`))})]})]}),t.jsxs("section",{className:"rounded-2xl border border-slate-700/50 bg-slate-950/75 p-4 shadow-xl shadow-black/20 backdrop-blur-sm",children:[t.jsx("h3",{className:"mb-3 text-xs font-semibold uppercase tracking-wider text-slate-400",children:"Simulation"}),t.jsxs("div",{className:"mb-3 flex items-center justify-between text-[10px] text-slate-500",children:[t.jsx("span",{children:"Step"}),t.jsxs("span",{className:"font-mono text-indigo-300",children:[Math.min(x+1,m)," / ",m]})]}),t.jsxs("div",{className:"grid grid-cols-3 gap-2",children:[t.jsxs("button",{onClick:d,disabled:x<=0,className:"flex items-center justify-center gap-1 rounded-xl bg-slate-900/70 px-2 py-2 text-xs text-slate-400 ring-1 ring-slate-800/80 disabled:opacity-30",children:[t.jsx(oe,{size:13})," Back"]}),t.jsxs("button",{onClick:M,className:"flex items-center justify-center gap-1 rounded-xl bg-indigo-500/15 px-2 py-2 text-xs font-semibold text-indigo-300 ring-1 ring-indigo-500/30",children:[t.jsx(re,{size:13})," ",j?"Pause":"Play"]}),t.jsxs("button",{onClick:f,disabled:x>=m-1,className:"flex items-center justify-center gap-1 rounded-xl bg-slate-900/70 px-2 py-2 text-xs text-slate-400 ring-1 ring-slate-800/80 disabled:opacity-30",children:["Next ",t.jsx(ne,{size:13})]})]}),t.jsxs("button",{onClick:N,className:"mt-2 flex w-full items-center justify-center gap-2 rounded-xl bg-emerald-500/15 px-3 py-2 text-xs font-semibold text-emerald-300 ring-1 ring-emerald-500/30 transition hover:bg-emerald-500/25",children:[t.jsx(ie,{size:13})," Animate airplane"]}),c&&t.jsx("p",{className:"mt-3 text-xs leading-relaxed text-slate-400",children:c.description})]}),t.jsxs("section",{className:"rounded-2xl border border-slate-700/50 bg-slate-950/75 p-4 shadow-xl shadow-black/20 backdrop-blur-sm",children:[t.jsx("h3",{className:"mb-3 text-xs font-semibold uppercase tracking-wider text-slate-400",children:"Audio"}),t.jsxs("button",{onClick:()=>L(!y),className:`flex w-full items-center justify-center gap-2 rounded-xl px-3 py-2 text-xs font-semibold ring-1 transition ${y?"bg-sky-500/15 text-sky-300 ring-sky-500/30 hover:bg-sky-500/25":"bg-slate-900/70 text-slate-400 ring-slate-800/80 hover:bg-slate-800/80"}`,children:[y?t.jsx(le,{size:13}):t.jsx(ce,{size:13}),y?"Sound On":"Sound Off"]}),t.jsx("p",{className:"mt-2 text-[10px] leading-relaxed text-slate-500",children:"Radar pings mark search steps, with takeoff, waypoint, and arrival tones during flight."})]})]})}function X({label:s,value:i,airports:n,onChange:l}){return t.jsxs("label",{className:"block",children:[t.jsx("span",{className:"mb-1 block text-[10px] font-semibold uppercase tracking-wider text-slate-500",children:s}),t.jsx("select",{value:i,onChange:o=>l(o.target.value),className:"w-full rounded-xl border border-slate-700 bg-slate-900 px-3 py-2 text-xs font-mono text-slate-200 outline-none ring-sky-500/20 focus:ring-2",children:n.map(o=>t.jsxs("option",{value:o.code,children:[o.code," - ",o.city]},o.code))})]})}function H({label:s,value:i}){return t.jsxs("div",{className:"rounded-xl bg-slate-900/70 p-3 ring-1 ring-slate-800/80",children:[t.jsx("div",{className:"text-[9px] font-semibold uppercase tracking-wider text-slate-500",children:s}),t.jsx("div",{className:"mt-1 font-mono text-sm font-black text-white",children:i})]})}function Ae(s,i){return{x:(s+180)/360*1e3,y:(90-i)/180*520}}function r(s,i,n,l,o,u,c){return{code:s,city:i,country:n,region:l,lat:o,lon:u,hubScore:c,...Ae(u,o)}}const F=[r("ATL","Atlanta","United States","North America",33.6407,-84.4277,98),r("ORD","Chicago","United States","North America",41.9742,-87.9073,96),r("DFW","Dallas-Fort Worth","United States","North America",32.8998,-97.0403,94),r("JFK","New York","United States","North America",40.6413,-73.7781,96),r("LAX","Los Angeles","United States","North America",33.9416,-118.4085,94),r("MIA","Miami","United States","North America",25.7959,-80.287,88),r("SEA","Seattle","United States","North America",47.4502,-122.3088,84),r("SFO","San Francisco","United States","North America",37.6213,-122.379,90),r("YVR","Vancouver","Canada","North America",49.1967,-123.1815,76),r("YYZ","Toronto","Canada","North America",43.6777,-79.6248,78),r("MEX","Mexico City","Mexico","North America",19.4361,-99.0719,76),r("BOG","Bogota","Colombia","South America",4.7016,-74.1469,78),r("LIM","Lima","Peru","South America",-12.0219,-77.1143,76),r("EZE","Buenos Aires","Argentina","South America",-34.8222,-58.5358,74),r("GRU","Sao Paulo","Brazil","South America",-23.4356,-46.4731,84),r("SCL","Santiago","Chile","South America",-33.3928,-70.7858,72),r("AMS","Amsterdam","Netherlands","Europe",52.3105,4.7683,93),r("ARN","Stockholm","Sweden","Europe",59.6498,17.9238,70),r("ATH","Athens","Greece","Europe",37.9364,23.9445,72),r("BCN","Barcelona","Spain","Europe",41.2974,2.0833,76),r("BRU","Brussels","Belgium","Europe",50.9014,4.4844,74),r("CPH","Copenhagen","Denmark","Europe",55.618,12.6561,74),r("LHR","London","United Kingdom","Europe",51.47,-.4543,98),r("CDG","Paris","France","Europe",49.0097,2.5479,94),r("DUB","Dublin","Ireland","Europe",53.4264,-6.2499,70),r("FCO","Rome","Italy","Europe",41.8003,12.2389,78),r("FRA","Frankfurt","Germany","Europe",50.0379,8.5622,96),r("HEL","Helsinki","Finland","Europe",60.3172,24.9633,70),r("LIS","Lisbon","Portugal","Europe",38.7742,-9.1342,70),r("MAD","Madrid","Spain","Europe",40.4983,-3.5676,82),r("MUC","Munich","Germany","Europe",48.3538,11.7861,84),r("VIE","Vienna","Austria","Europe",48.1103,16.5697,76),r("WAW","Warsaw","Poland","Europe",52.1657,20.9671,70),r("ZRH","Zurich","Switzerland","Europe",47.4581,8.5555,82),r("IST","Istanbul","Turkey","Europe/Asia",41.2753,28.7519,92),r("ADD","Addis Ababa","Ethiopia","Africa",8.9779,38.7993,82),r("CMN","Casablanca","Morocco","Africa",33.3675,-7.58997,74),r("CAI","Cairo","Egypt","Africa",30.112,31.4003,70),r("CPT","Cape Town","South Africa","Africa",-33.9715,18.6021,70),r("LOS","Lagos","Nigeria","Africa",6.5774,3.3212,72),r("JNB","Johannesburg","South Africa","Africa",-26.1337,28.242,80),r("NBO","Nairobi","Kenya","Africa",-1.3192,36.9278,68),r("AUH","Abu Dhabi","United Arab Emirates","Middle East",24.433,54.6511,82),r("DXB","Dubai","United Arab Emirates","Middle East",25.2532,55.3657,99),r("DOH","Doha","Qatar","Middle East",25.2731,51.6081,88),r("JED","Jeddah","Saudi Arabia","Middle East",21.6796,39.1565,78),r("RUH","Riyadh","Saudi Arabia","Middle East",24.9576,46.6988,76),r("TLV","Tel Aviv","Israel","Middle East",32.0114,34.8867,74),r("BKK","Bangkok","Thailand","Asia",13.69,100.7501,88),r("BLR","Bengaluru","India","Asia",13.1986,77.7066,76),r("BOM","Mumbai","India","Asia",19.0896,72.8656,84),r("CAN","Guangzhou","China","Asia",23.3924,113.2988,86),r("CGK","Jakarta","Indonesia","Asia",-6.1256,106.6559,82),r("DEL","Delhi","India","Asia",28.5562,77.1,86),r("HKG","Hong Kong","China","Asia",22.308,113.9185,92),r("SIN","Singapore","Singapore","Asia",1.3644,103.9915,96),r("ICN","Seoul","South Korea","Asia",37.4602,126.4407,94),r("KUL","Kuala Lumpur","Malaysia","Asia",2.7456,101.7072,82),r("MNL","Manila","Philippines","Asia",14.5086,121.0194,78),r("PEK","Beijing","China","Asia",40.0799,116.6031,90),r("PVG","Shanghai","China","Asia",31.1443,121.8083,92),r("TPE","Taipei","Taiwan","Asia",25.0797,121.2342,82),r("HND","Tokyo","Japan","Asia",35.5494,139.7798,95),r("BNE","Brisbane","Australia","Oceania",-27.3842,153.1175,70),r("MEL","Melbourne","Australia","Oceania",-37.669,144.841,78),r("PER","Perth","Australia","Oceania",-31.9403,115.9672,72),r("SYD","Sydney","Australia","Oceania",-33.9399,151.1753,84),r("AKL","Auckland","New Zealand","Oceania",-37.0082,174.785,66)],V=new Map(F.map(s=>[s.code,s]));function ye(s,i){const l=h=>h*Math.PI/180,o=l(i.lat-s.lat),u=l(i.lon-s.lon),c=l(s.lat),x=l(i.lat),m=Math.sin(o/2)**2+Math.cos(c)*Math.cos(x)*Math.sin(u/2)**2;return Math.round(2*6371*Math.asin(Math.sqrt(m)))}function e(s,i){const n=V.get(s),l=V.get(i);if(!n||!l)throw new Error(`Unknown airport route: ${s}-${i}`);const o=ye(n,l);return{id:`${s}-${i}`,source:s,destination:i,distanceKm:o,durationHours:Math.round((o/870+.65)*10)/10,costUsd:Math.round(o*.11+140)}}const B=[e("ATL","DFW"),e("ATL","JFK"),e("ATL","LAX"),e("ATL","MIA"),e("ATL","ORD"),e("ATL","YYZ"),e("ORD","DFW"),e("ORD","JFK"),e("ORD","LAX"),e("ORD","SEA"),e("ORD","SFO"),e("ORD","YYZ"),e("DFW","LAX"),e("DFW","MEX"),e("DFW","MIA"),e("DFW","SFO"),e("JFK","LAX"),e("JFK","YYZ"),e("JFK","LHR"),e("JFK","CDG"),e("JFK","AMS"),e("JFK","FRA"),e("JFK","MEX"),e("JFK","MIA"),e("JFK","SFO"),e("JFK","MAD"),e("JFK","DUB"),e("JFK","GRU"),e("LAX","HND"),e("LAX","ICN"),e("LAX","PVG"),e("LAX","SIN"),e("LAX","SYD"),e("LAX","MEX"),e("LAX","SFO"),e("LAX","SEA"),e("LAX","YVR"),e("YYZ","LHR"),e("YYZ","AMS"),e("YYZ","FRA"),e("YYZ","YVR"),e("MIA","BOG"),e("MIA","GRU"),e("MIA","LIM"),e("MIA","MEX"),e("SEA","YVR"),e("SEA","HND"),e("SEA","ICN"),e("SFO","HKG"),e("SFO","HND"),e("SFO","ICN"),e("SFO","SIN"),e("YVR","HND"),e("YVR","ICN"),e("MEX","BOG"),e("MEX","GRU"),e("MEX","LIM"),e("MEX","SCL"),e("BOG","GRU"),e("BOG","LIM"),e("BOG","MAD"),e("LIM","EZE"),e("LIM","SCL"),e("LIM","GRU"),e("EZE","GRU"),e("EZE","MAD"),e("EZE","SCL"),e("GRU","SCL"),e("GRU","MAD"),e("GRU","LIS"),e("GRU","CDG"),e("GRU","JNB"),e("SCL","AKL"),e("AMS","BRU"),e("AMS","CPH"),e("AMS","DUB"),e("AMS","FRA"),e("AMS","LHR"),e("AMS","ZRH"),e("ARN","CPH"),e("ARN","HEL"),e("ARN","LHR"),e("ATH","FCO"),e("ATH","IST"),e("ATH","VIE"),e("BCN","FCO"),e("BCN","LHR"),e("BCN","MAD"),e("BRU","CDG"),e("BRU","FRA"),e("CPH","FRA"),e("CPH","HEL"),e("CPH","LHR"),e("LHR","CDG"),e("LHR","MAD"),e("LHR","FRA"),e("LHR","ZRH"),e("LHR","DUB"),e("LHR","FCO"),e("LHR","DXB"),e("LHR","DOH"),e("LHR","SIN"),e("CDG","MAD"),e("CDG","FRA"),e("CDG","FCO"),e("CDG","IST"),e("CDG","DXB"),e("DUB","LIS"),e("FCO","IST"),e("FCO","MAD"),e("FRA","IST"),e("FRA","MUC"),e("FRA","VIE"),e("FRA","ZRH"),e("FRA","DXB"),e("HEL","WAW"),e("LIS","MAD"),e("MAD","CMN"),e("MAD","CAI"),e("MAD","DOH"),e("MUC","VIE"),e("MUC","ZRH"),e("VIE","WAW"),e("VIE","IST"),e("WAW","IST"),e("ZRH","VIE"),e("IST","ADD"),e("IST","CAI"),e("IST","DXB"),e("IST","DOH"),e("IST","TLV"),e("ADD","CAI"),e("ADD","JNB"),e("ADD","NBO"),e("ADD","DXB"),e("CMN","CAI"),e("CMN","LIS"),e("CMN","LOS"),e("CAI","JNB"),e("CAI","NBO"),e("CAI","JED"),e("CAI","RUH"),e("CAI","TLV"),e("CPT","JNB"),e("CPT","ADD"),e("CPT","DXB"),e("LOS","ADD"),e("LOS","JNB"),e("JNB","NBO"),e("JNB","SYD"),e("JNB","DXB"),e("NBO","DXB"),e("NBO","DOH"),e("AUH","BOM"),e("AUH","DEL"),e("AUH","JED"),e("AUH","LHR"),e("AUH","SIN"),e("DXB","DOH"),e("DXB","AUH"),e("DXB","DEL"),e("DXB","BOM"),e("DXB","BKK"),e("DXB","SIN"),e("DXB","HKG"),e("DXB","SYD"),e("DOH","BOM"),e("DOH","DEL"),e("DOH","JED"),e("DOH","SIN"),e("DOH","SYD"),e("JED","RUH"),e("JED","DEL"),e("RUH","DXB"),e("TLV","ATH"),e("TLV","DXB"),e("BKK","DEL"),e("BKK","HKG"),e("BKK","KUL"),e("BKK","SIN"),e("BKK","TPE"),e("BLR","BOM"),e("BLR","DEL"),e("BLR","SIN"),e("BOM","DEL"),e("BOM","SIN"),e("BOM","LHR"),e("CAN","HKG"),e("CAN","PEK"),e("CAN","PVG"),e("CAN","SIN"),e("CGK","KUL"),e("CGK","SIN"),e("CGK","SYD"),e("DEL","SIN"),e("DEL","HND"),e("DEL","HKG"),e("DEL","ICN"),e("HKG","ICN"),e("HKG","MNL"),e("HKG","PVG"),e("HKG","SIN"),e("HKG","TPE"),e("ICN","HND"),e("ICN","PEK"),e("ICN","PVG"),e("SIN","HND"),e("SIN","KUL"),e("SIN","MNL"),e("SIN","SYD"),e("KUL","MNL"),e("KUL","PER"),e("MNL","HND"),e("PEK","HND"),e("PEK","PVG"),e("PEK","SFO"),e("PVG","HND"),e("PVG","TPE"),e("TPE","HND"),e("HND","SYD"),e("HND","BNE"),e("BNE","SYD"),e("BNE","MEL"),e("MEL","SYD"),e("MEL","AKL"),e("PER","MEL"),e("PER","SYD"),e("PER","SIN"),e("SYD","AKL")],Y=[{id:"trans-atlantic",title:"New York to Tokyo",description:"Compare westbound Pacific hops against eastbound European and Gulf hub routes.",source:"JFK",destination:"HND",algorithm:"dijkstra"},{id:"southern-cross",title:"London to Sydney",description:"Route across Europe, the Gulf, Asia, and Oceania using weighted flight times.",source:"LHR",destination:"SYD",algorithm:"astar"},{id:"africa-to-americas",title:"Johannesburg to Los Angeles",description:"Study how different algorithms connect Africa to the Americas through major hubs.",source:"JNB",destination:"LAX",algorithm:"greedy"},{id:"fewest-stops",title:"Toronto to Singapore",description:"Use BFS to minimize the number of airport connections, ignoring flight duration.",source:"YYZ",destination:"SIN",algorithm:"bfs"}];function W(s){return new Map(s.map(i=>[i.code,i]))}function G(s,i){return s.flatMap(n=>n.source===i?[{code:n.destination,route:n}]:n.destination===i?[{code:n.source,route:n}]:[])}function _(s,i,n){return s.find(l=>l.source===i&&l.destination===n||l.source===n&&l.destination===i)??null}function J(s,i,n,l,o){return o==="bfs"?Ne(s,i,n,l):o==="greedy"?Ce(s,i,n,l):Se(s,i,n,l,o)}function Se(s,i,n,l,o){const u=W(s),c={},x={},m=new Set,h=[{code:n,priority:0}],j=[];for(const g of s)c[g.code]=g.code===n?0:1/0,x[g.code]=null;for(j.push(E("init",n,`Start at ${n}. Set its travel time to 0 and every other airport to infinity.`,m,h,c,x));h.length>0;){h.sort((p,k)=>p.priority-k.priority);const g=h.shift();if(!m.has(g.code)){if(m.add(g.code),j.push(E("select",g.code,`Select ${g.code}, the airport with the best current priority.`,m,h,c,x)),g.code===l)break;for(const p of G(i,g.code)){if(m.has(p.code))continue;const k=c[g.code]+p.route.durationHours;if(k ${p.code} improves the route to ${c[p.code]}h.`,m,h,c,x,{from:g.code,to:p.code}))}else j.push(E("dead-end",p.code,`${g.code} -> ${p.code} is slower than the best known route.`,m,h,c,x,{from:g.code,to:p.code}))}}}const y=U(x,n,l),S=$(i,y);return j.push(E("done",l,`Route complete: ${y.join(" -> ")}`,m,h,c,x,void 0,y)),{steps:j,plan:S}}function Ne(s,i,n,l){const o=new Set([n]),u={},c={},x=[{code:n,priority:0}],m=[];for(const y of s)u[y.code]=null,c[y.code]=y.code===n?0:1/0;for(m.push(E("init",n,`Start BFS at ${n}. Each edge counts as one airport hop.`,o,x,c,u));x.length>0;){const y=x.shift();if(m.push(E("select",y.code,`Visit ${y.code} and enqueue all unseen connected airports.`,o,x,c,u)),y.code===l)break;for(const S of G(i,y.code))o.has(S.code)||(o.add(S.code),u[S.code]=y.code,c[S.code]=c[y.code]+1,x.push({code:S.code,priority:c[S.code]}),m.push(E("enqueue",S.code,`Add ${S.code} to the BFS queue at hop ${c[S.code]}.`,o,x,c,u,{from:y.code,to:S.code})))}const h=U(u,n,l),j=$(i,h);return m.push(E("done",l,`Fewest-stop route complete: ${h.join(" -> ")}`,o,x,c,u,void 0,h)),{steps:m,plan:j}}function Ce(s,i,n,l){const o=W(s),u=new Set,c={},x={},m=[];let h=n;for(const S of s)c[S.code]=null,x[S.code]=S.code===n?0:1/0;for(m.push(E("init",n,`Start greedy routing at ${n}. Always choose the neighbor closest to ${l}.`,u,[{code:n,priority:0}],x,c));h!==l;){u.add(h);const S=G(i,h).filter(p=>!u.has(p.code)).sort((p,k)=>T(o.get(p.code),o.get(l))-T(o.get(k.code),o.get(l)));if(m.push(E("select",h,`From ${h}, compare nearby hubs by straight-line distance to ${l}.`,u,S.map(p=>({code:p.code,priority:Math.round(T(o.get(p.code),o.get(l))*10)/10})),x,c)),S.length===0)break;const g=S[0];x[g.code]=Math.round((x[h]+g.route.durationHours)*10)/10,c[g.code]=h,m.push(E("relax",g.code,`Greedy picks ${g.code} as the closest-looking next airport.`,u,[],x,c,{from:h,to:g.code})),h=g.code}const j=U(c,n,l),y=$(i,j);return m.push(E("done",l,`Greedy route complete: ${j.join(" -> ")}`,u,[],x,c,void 0,j)),{steps:m,plan:y}}function E(s,i,n,l,o,u,c,x,m){return{type:s,airportCode:i,description:n,visited:Array.from(l),frontier:o.map(h=>({code:h.code,priority:h.priority})),distances:{...u},previous:{...c},relaxedRoute:x,route:m}}function U(s,i,n){const l=[];let o=n;for(;o&&(l.unshift(o),o!==i);)o=s[o];return l[0]===i?l:[]}function $(s,i){let n=0,l=0,o=0;for(let u=0;ude(),[]),o=b.useCallback((p,k,a="sine",d=.045)=>{if(!s.current)return;const f=l();if(!f)return;const M=f.createOscillator(),N=f.createGain();M.type=a,M.frequency.setValueAtTime(p,f.currentTime),N.gain.setValueAtTime(d,f.currentTime),N.gain.exponentialRampToValueAtTime(.001,f.currentTime+k),M.connect(N),N.connect(f.destination),M.start(f.currentTime),M.stop(f.currentTime+k)},[l]),u=b.useCallback((p,k,a,d=.04)=>{if(!s.current)return;const f=l();f&&p.forEach((M,N)=>{const L=f.createOscillator(),D=f.createGain(),R=f.currentTime+N*a*.75;L.type=k,L.frequency.setValueAtTime(M,R),D.gain.setValueAtTime(d,R),D.gain.exponentialRampToValueAtTime(.001,R+a),L.connect(D),D.connect(f.destination),L.start(R),L.stop(R+a)})},[l]),c=b.useCallback(()=>{o(523.25,.08,"triangle",.035)},[o]),x=b.useCallback(()=>{u([392,523.25,659.25],"sine",.1,.045)},[u]),m=b.useCallback(p=>{o(Z[p%Z.length],.055,"sine",.025)},[o]),h=b.useCallback(()=>{u([196,246.94,329.63,392],"triangle",.09,.04)},[u]),j=b.useCallback(p=>{o(p%2===0?587.33:659.25,.09,"triangle",.035)},[o]),y=b.useCallback(()=>{u([523.25,659.25,783.99,1046.5],"sine",.11,.05)},[u]),S=b.useCallback(()=>{o(220,.08,"sawtooth",.025)},[o]),g=b.useCallback(p=>{s.current=p,n(p)},[]);return{soundEnabled:i,toggleSound:g,playAirportSelect:c,playRoutePlanned:x,playScanStep:m,playFlightStart:h,playWaypoint:j,playArrive:y,playPause:S}}function De(){const[s,i]=b.useState("JFK"),[n,l]=b.useState("HND"),[o,u]=b.useState("dijkstra"),[c,x]=b.useState(()=>J(F,B,"JFK","HND","dijkstra")),[m,h]=b.useState(0),[j,y]=b.useState("idle"),[S,g]=b.useState(!1),[p,k]=b.useState(null),a=b.useRef(null),d=Me(),f=c.steps[m]??null,M=b.useCallback(()=>{a.current&&(window.clearInterval(a.current),a.current=null)},[]);b.useEffect(()=>M,[M]);const N=b.useCallback((A=s,C=n,w=o)=>{M();const ee=J(F,B,A,C,w);x(ee),h(0),y("planning"),g(!1),k(null),d.playRoutePlanned()},[o,M,n,d,s]),L=b.useCallback(A=>{A!==n&&(d.playAirportSelect(),i(A),N(A,n,o))},[o,n,N,d]),D=b.useCallback(A=>{A!==s&&(d.playAirportSelect(),l(A),N(s,A,o))},[o,N,d,s]),R=b.useCallback(A=>{d.playAirportSelect(),u(A),N(s,n,A)},[n,N,d,s]),I=b.useCallback(A=>{const C=Y.find(w=>w.id===A);C&&(d.playAirportSelect(),i(C.source),l(C.destination),u(C.algorithm),N(C.source,C.destination,C.algorithm))},[N,d]),K=b.useCallback(()=>{y("planning"),h(A=>{const C=Math.min(A+1,c.steps.length-1);return C!==A&&d.playScanStep(C),C})},[c.steps.length,d]),z=b.useCallback(()=>{y("planning"),h(A=>{const C=Math.max(A-1,0);return C!==A&&d.playScanStep(C),C})},[d]),P=b.useCallback(()=>{M();const A=c.plan.path;if(A.length<2)return;y("flying"),g(!0),d.playFlightStart();let C=0,w=0;k({from:A[0],to:A[1],progress:0}),a.current=window.setInterval(()=>{if(w+=.045,w>=1){if(C+=1,w=0,C>=A.length-1){M(),k(null),g(!1),y("complete"),d.playArrive();return}d.playWaypoint(C)}k({from:A[C],to:A[C+1],progress:w})},80)},[M,c.plan.path,d]),q=b.useCallback(()=>{if(S){M(),g(!1),d.playPause();return}y("planning"),g(!0),d.playScanStep(m),a.current=window.setInterval(()=>{h(A=>{if(A>=c.steps.length-1)return M(),g(!1),P(),A;const C=A+1;return d.playScanStep(C),C})},420)},[P,M,S,c.steps.length,d,m]),Q=b.useMemo(()=>{const A=f?.route??c.plan.path;return A.slice(0,-1).map((C,w)=>_(B,C,A[w+1])).filter(Boolean)},[f?.route,c.plan.path]);return{airports:F,routes:B,scenarios:Y,source:s,destination:n,algorithm:o,result:c,currentStep:f,stepIndex:m,phase:j,isPlaying:S,flightProgress:p,activeRoute:Q,soundEnabled:d.soundEnabled,toggleSound:d.toggleSound,changeSource:L,changeDestination:D,changeAlgorithm:R,loadScenario:I,planRoute:N,stepForward:K,stepBack:z,playPlanning:q,animateFlight:P}}function He(){const s=De();return t.jsxs("div",{className:"flex flex-1 flex-col overflow-hidden bg-[radial-gradient(circle_at_top_left,rgba(14,165,233,0.16),transparent_30%),radial-gradient(circle_at_bottom_right,rgba(59,130,246,0.14),transparent_28%)]",children:[t.jsx("div",{className:"border-b border-slate-800/70 bg-slate-950/75 px-4 py-3 shadow-lg shadow-black/20 backdrop-blur-sm md:px-6",children:t.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[t.jsxs("div",{children:[t.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-[0.24em] text-sky-400",children:"Airport Network Algorithms"}),t.jsx("h2",{className:"text-lg font-bold text-white",children:"World Map Flight Simulator"})]}),t.jsxs("div",{className:"ml-auto flex flex-wrap items-center gap-2",children:[t.jsx(v,{label:"Algorithm",value:O[s.algorithm].label,tone:"indigo"}),t.jsx(v,{label:"Origin",value:s.source,tone:"sky"}),t.jsx(v,{label:"Destination",value:s.destination,tone:"emerald"}),t.jsx(v,{label:"Stops",value:s.result.plan.stops.toString(),tone:"amber"})]})]})}),t.jsxs("div",{className:"flex flex-1 flex-col gap-4 overflow-auto p-4 md:p-6 xl:flex-row",children:[t.jsx(ge,{airports:s.airports,routes:s.routes,source:s.source,destination:s.destination,currentStep:s.currentStep,plan:s.result.plan,flightProgress:s.flightProgress,onSelectSource:s.changeSource,onSelectDestination:s.changeDestination}),t.jsx(be,{airports:s.airports,scenarios:s.scenarios,source:s.source,destination:s.destination,algorithm:s.algorithm,plan:s.result.plan,currentStep:s.currentStep,stepIndex:s.stepIndex,totalSteps:s.result.steps.length,phase:s.phase,isPlaying:s.isPlaying,soundEnabled:s.soundEnabled,onSourceChange:s.changeSource,onDestinationChange:s.changeDestination,onAlgorithmChange:s.changeAlgorithm,onLoadScenario:s.loadScenario,onPlanRoute:()=>s.planRoute(),onStepBack:s.stepBack,onStepForward:s.stepForward,onPlay:s.playPlanning,onFly:s.animateFlight,onToggleSound:s.toggleSound})]})]})}function v({label:s,value:i,tone:n}){const l={indigo:"bg-indigo-500/10 text-indigo-200 ring-indigo-500/25",sky:"bg-sky-500/10 text-sky-200 ring-sky-500/25",emerald:"bg-emerald-500/10 text-emerald-200 ring-emerald-500/25",amber:"bg-amber-500/10 text-amber-200 ring-amber-500/25"};return t.jsxs("div",{className:`rounded-full px-3 py-1.5 text-[10px] ring-1 ${l[n]}`,children:[t.jsx("span",{className:"mr-1 uppercase tracking-wider opacity-60",children:s}),t.jsx("span",{className:"font-mono font-bold",children:i})]})}export{He as default}; diff --git a/docs/assets/arrow-left-CkNLVmJL.js b/docs/assets/arrow-left-CkNLVmJL.js new file mode 100644 index 0000000..60babfd --- /dev/null +++ b/docs/assets/arrow-left-CkNLVmJL.js @@ -0,0 +1 @@ +import{c as o}from"./index-BfWfBQOp.js";const e=[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]],r=o("arrow-left",e);export{r as A}; diff --git a/docs/assets/audioContext-NbgqvQGz.js b/docs/assets/audioContext-NbgqvQGz.js new file mode 100644 index 0000000..9d98439 --- /dev/null +++ b/docs/assets/audioContext-NbgqvQGz.js @@ -0,0 +1 @@ +let t=null,e=!1;function u(){if(typeof window>"u")return null;const n=window;return window.AudioContext??n.webkitAudioContext??null}function o(){if(e)return null;if(!t||t.state==="closed"){const n=u();if(!n)return e=!0,null;try{t=new n}catch{return t=null,null}}return t.state!=="running"&&t.resume().catch(()=>{}),t}export{o as g}; diff --git a/docs/assets/chevron-right-CNA9GG_w.js b/docs/assets/chevron-right-CNA9GG_w.js new file mode 100644 index 0000000..4f9aa50 --- /dev/null +++ b/docs/assets/chevron-right-CNA9GG_w.js @@ -0,0 +1 @@ +import{c as o}from"./index-BfWfBQOp.js";const e=[["path",{d:"m15 18-6-6 6-6",key:"1wnfg3"}]],n=o("chevron-left",e);const t=[["path",{d:"m9 18 6-6-6-6",key:"mthhwq"}]],h=o("chevron-right",t);export{n as C,h as a}; diff --git a/docs/assets/eye-off-B7FP-9s5.js b/docs/assets/eye-off-B7FP-9s5.js new file mode 100644 index 0000000..123c916 --- /dev/null +++ b/docs/assets/eye-off-B7FP-9s5.js @@ -0,0 +1 @@ +import{c as e}from"./index-BfWfBQOp.js";const a=[["path",{d:"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49",key:"ct8e1f"}],["path",{d:"M14.084 14.158a3 3 0 0 1-4.242-4.242",key:"151rxh"}],["path",{d:"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143",key:"13bj9a"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]],t=e("eye-off",a);export{t as E}; diff --git a/docs/assets/index-BfWfBQOp.js b/docs/assets/index-BfWfBQOp.js new file mode 100644 index 0000000..36a6fa6 --- /dev/null +++ b/docs/assets/index-BfWfBQOp.js @@ -0,0 +1,32 @@ +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/AlgorithmPlaygroundPage-BZcoKA4I.js","assets/AlgorithmCodePanel-DWTIRULe.js","assets/audioContext-NbgqvQGz.js","assets/shuffle-Ri9xSsK2.js","assets/chevron-right-CNA9GG_w.js","assets/play-WRQgdyAG.js","assets/rotate-ccw-EKzY5q_W.js","assets/volume-x-ChIHiT28.js","assets/LinkedListAlgorithmsPage-4LF4-86u.js","assets/linkedListAlgo-0_WYfSZm.js","assets/arrow-left-CkNLVmJL.js","assets/LinkedListAlgoPage-wdM2t0_B.js","assets/pause-Bg-8t1oj.js","assets/GraphTraversalPage-D6V7J1Sh.js","assets/index-Cj8HB9AY.js","assets/square-BSu6WBc6.js","assets/SortingPage--_1K-mN2.js","assets/index-iw_6MvvU.js","assets/SudokuPage-Bwx9E4N_.js","assets/zap-CxtzYT6S.js","assets/TreeTraversalPage-DDkYMql2.js","assets/TriePage-3KlcWkEC.js","assets/plus-BEk43_MF.js","assets/BalancedTreePage-BIWzF7Hd.js","assets/StackPage-1vXSCZRz.js","assets/useDSSound-BMrOIkPj.js","assets/trash-2-RJG3j28z.js","assets/QueuePage-Dm9bXwaQ.js","assets/ArrayPage-BVw3oj1M.js","assets/LinkedListPage-DBaHdW5c.js","assets/AdvancedStructurePage-C3Gu2vhw.js","assets/FibonacciGamePage-yra_MIZ2.js","assets/trophy-CUioHXrM.js","assets/lightbulb-D7RWgS3V.js","assets/timer-t0ca9c1j.js","assets/DijkstraGamePage-DPGMG41Z.js","assets/map-DMi7QK0E.js","assets/route-CNnmHrEb.js","assets/eye-off-B7FP-9s5.js","assets/BattlePage-BHrGHw2_.js","assets/MahjongGamePage-CcjiTEak.js","assets/skip-forward-DUFQw-PC.js","assets/EvolutionSimulatorPage-ClEOzQ75.js","assets/RubiksCubeGamePage-DGHevFh5.js","assets/WorldMapGamePage-B75VoKQY.js","assets/GitPage-2cA3c4jf.js"])))=>i.map(i=>d[i]); +(function(){const f=document.createElement("link").relList;if(f&&f.supports&&f.supports("modulepreload"))return;for(const h of document.querySelectorAll('link[rel="modulepreload"]'))s(h);new MutationObserver(h=>{for(const m of h)if(m.type==="childList")for(const b of m.addedNodes)b.tagName==="LINK"&&b.rel==="modulepreload"&&s(b)}).observe(document,{childList:!0,subtree:!0});function o(h){const m={};return h.integrity&&(m.integrity=h.integrity),h.referrerPolicy&&(m.referrerPolicy=h.referrerPolicy),h.crossOrigin==="use-credentials"?m.credentials="include":h.crossOrigin==="anonymous"?m.credentials="omit":m.credentials="same-origin",m}function s(h){if(h.ep)return;h.ep=!0;const m=o(h);fetch(h.href,m)}})();var Us={exports:{}},wn={};var uh;function T1(){if(uh)return wn;uh=1;var c=Symbol.for("react.transitional.element"),f=Symbol.for("react.fragment");function o(s,h,m){var b=null;if(m!==void 0&&(b=""+m),h.key!==void 0&&(b=""+h.key),"key"in h){m={};for(var j in h)j!=="key"&&(m[j]=h[j])}else m=h;return h=m.ref,{$$typeof:c,type:s,key:b,ref:h!==void 0?h:null,props:m}}return wn.Fragment=f,wn.jsx=o,wn.jsxs=o,wn}var ih;function A1(){return ih||(ih=1,Us.exports=T1()),Us.exports}var d=A1(),ws={exports:{}},I={};var ch;function j1(){if(ch)return I;ch=1;var c=Symbol.for("react.transitional.element"),f=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),s=Symbol.for("react.strict_mode"),h=Symbol.for("react.profiler"),m=Symbol.for("react.consumer"),b=Symbol.for("react.context"),j=Symbol.for("react.forward_ref"),S=Symbol.for("react.suspense"),g=Symbol.for("react.memo"),N=Symbol.for("react.lazy"),T=Symbol.for("react.activity"),w=Symbol.iterator;function X(v){return v===null||typeof v!="object"?null:(v=w&&v[w]||v["@@iterator"],typeof v=="function"?v:null)}var Q={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},Y=Object.assign,H={};function K(v,U,q){this.props=v,this.context=U,this.refs=H,this.updater=q||Q}K.prototype.isReactComponent={},K.prototype.setState=function(v,U){if(typeof v!="object"&&typeof v!="function"&&v!=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,v,U,"setState")},K.prototype.forceUpdate=function(v){this.updater.enqueueForceUpdate(this,v,"forceUpdate")};function et(){}et.prototype=K.prototype;function $(v,U,q){this.props=v,this.context=U,this.refs=H,this.updater=q||Q}var xt=$.prototype=new et;xt.constructor=$,Y(xt,K.prototype),xt.isPureReactComponent=!0;var St=Array.isArray;function jt(){}var F={H:null,A:null,T:null,S:null},Dt=Object.prototype.hasOwnProperty;function $t(v,U,q){var G=q.ref;return{$$typeof:c,type:v,key:U,ref:G!==void 0?G:null,props:q}}function Ue(v,U){return $t(v.type,U,v.props)}function ve(v){return typeof v=="object"&&v!==null&&v.$$typeof===c}function Wt(v){var U={"=":"=0",":":"=2"};return"$"+v.replace(/[=:]/g,function(q){return U[q]})}var we=/\/+/g;function be(v,U){return typeof v=="object"&&v!==null&&v.key!=null?Wt(""+v.key):U.toString(36)}function Ht(v){switch(v.status){case"fulfilled":return v.value;case"rejected":throw v.reason;default:switch(typeof v.status=="string"?v.then(jt,jt):(v.status="pending",v.then(function(U){v.status==="pending"&&(v.status="fulfilled",v.value=U)},function(U){v.status==="pending"&&(v.status="rejected",v.reason=U)})),v.status){case"fulfilled":return v.value;case"rejected":throw v.reason}}throw v}function O(v,U,q,G,P){var at=typeof v;(at==="undefined"||at==="boolean")&&(v=null);var ht=!1;if(v===null)ht=!0;else switch(at){case"bigint":case"string":case"number":ht=!0;break;case"object":switch(v.$$typeof){case c:case f:ht=!0;break;case N:return ht=v._init,O(ht(v._payload),U,q,G,P)}}if(ht)return P=P(v),ht=G===""?"."+be(v,0):G,St(P)?(q="",ht!=null&&(q=ht.replace(we,"$&/")+"/"),O(P,U,q,"",function(Ga){return Ga})):P!=null&&(ve(P)&&(P=Ue(P,q+(P.key==null||v&&v.key===P.key?"":(""+P.key).replace(we,"$&/")+"/")+ht)),U.push(P)),1;ht=0;var It=G===""?".":G+":";if(St(v))for(var Ct=0;Ct>>1,Et=O[gt];if(0>>1;gth(q,W))Gh(P,q)?(O[gt]=P,O[G]=W,gt=G):(O[gt]=q,O[U]=W,gt=U);else if(Gh(P,W))O[gt]=P,O[G]=W,gt=G;else break t}}return B}function h(O,B){var W=O.sortIndex-B.sortIndex;return W!==0?W:O.id-B.id}if(c.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var m=performance;c.unstable_now=function(){return m.now()}}else{var b=Date,j=b.now();c.unstable_now=function(){return b.now()-j}}var S=[],g=[],N=1,T=null,w=3,X=!1,Q=!1,Y=!1,H=!1,K=typeof setTimeout=="function"?setTimeout:null,et=typeof clearTimeout=="function"?clearTimeout:null,$=typeof setImmediate<"u"?setImmediate:null;function xt(O){for(var B=o(g);B!==null;){if(B.callback===null)s(g);else if(B.startTime<=O)s(g),B.sortIndex=B.expirationTime,f(S,B);else break;B=o(g)}}function St(O){if(Y=!1,xt(O),!Q)if(o(S)!==null)Q=!0,jt||(jt=!0,Wt());else{var B=o(g);B!==null&&Ht(St,B.startTime-O)}}var jt=!1,F=-1,Dt=5,$t=-1;function Ue(){return H?!0:!(c.unstable_now()-$tO&&Ue());){var gt=T.callback;if(typeof gt=="function"){T.callback=null,w=T.priorityLevel;var Et=gt(T.expirationTime<=O);if(O=c.unstable_now(),typeof Et=="function"){T.callback=Et,xt(O),B=!0;break e}T===o(S)&&s(S),xt(O)}else s(S);T=o(S)}if(T!==null)B=!0;else{var v=o(g);v!==null&&Ht(St,v.startTime-O),B=!1}}break t}finally{T=null,w=W,X=!1}B=void 0}}finally{B?Wt():jt=!1}}}var Wt;if(typeof $=="function")Wt=function(){$(ve)};else if(typeof MessageChannel<"u"){var we=new MessageChannel,be=we.port2;we.port1.onmessage=ve,Wt=function(){be.postMessage(null)}}else Wt=function(){K(ve,0)};function Ht(O,B){F=K(function(){O(c.unstable_now())},B)}c.unstable_IdlePriority=5,c.unstable_ImmediatePriority=1,c.unstable_LowPriority=4,c.unstable_NormalPriority=3,c.unstable_Profiling=null,c.unstable_UserBlockingPriority=2,c.unstable_cancelCallback=function(O){O.callback=null},c.unstable_forceFrameRate=function(O){0>O||125gt?(O.sortIndex=W,f(g,O),o(S)===null&&O===o(g)&&(Y?(et(F),F=-1):Y=!0,Ht(St,W-gt))):(O.sortIndex=Et,f(S,O),Q||X||(Q=!0,jt||(jt=!0,Wt()))),O},c.unstable_shouldYield=Ue,c.unstable_wrapCallback=function(O){var B=w;return function(){var W=w;w=B;try{return O.apply(this,arguments)}finally{w=W}}}})(qs)),qs}var fh;function M1(){return fh||(fh=1,Bs.exports=R1()),Bs.exports}var Ls={exports:{}},Ft={};var oh;function O1(){if(oh)return Ft;oh=1;var c=Zs();function f(S){var g="https://react.dev/errors/"+S;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(c)}catch(f){console.error(f)}}return c(),Ls.exports=O1(),Ls.exports}var hh;function D1(){if(hh)return Hn;hh=1;var c=M1(),f=Zs(),o=N1();function s(t){var e="https://react.dev/errors/"+t;if(1Et||(t.current=gt[Et],gt[Et]=null,Et--)}function q(t,e){Et++,gt[Et]=t.current,t.current=e}var G=v(null),P=v(null),at=v(null),ht=v(null);function It(t,e){switch(q(at,e),q(P,t),q(G,null),e.nodeType){case 9:case 11:t=(t=e.documentElement)&&(t=t.namespaceURI)?Rd(t):0;break;default:if(t=e.tagName,e=e.namespaceURI)e=Rd(e),t=Md(e,t);else switch(t){case"svg":t=1;break;case"math":t=2;break;default:t=0}}U(G),q(G,t)}function Ct(){U(G),U(P),U(at)}function Ga(t){t.memoizedState!==null&&q(ht,t);var e=G.current,l=Md(e,t.type);e!==l&&(q(P,t),q(G,l))}function Vn(t){P.current===t&&(U(G),U(P)),ht.current===t&&(U(ht),Nn._currentValue=W)}var gi,lr;function Hl(t){if(gi===void 0)try{throw Error()}catch(l){var e=l.stack.trim().match(/\n( *(at )?)/);gi=e&&e[1]||"",lr=-1)":-1n||y[a]!==z[n]){var M=` +`+y[a].replace(" at new "," at ");return t.displayName&&M.includes("")&&(M=M.replace("",t.displayName)),M}while(1<=a&&0<=n);break}}}finally{pi=!1,Error.prepareStackTrace=l}return(l=t?t.displayName||t.name:"")?Hl(l):""}function lm(t,e){switch(t.tag){case 26:case 27:case 5:return Hl(t.type);case 16:return Hl("Lazy");case 13:return t.child!==e&&e!==null?Hl("Suspense Fallback"):Hl("Suspense");case 19:return Hl("SuspenseList");case 0:case 15:return vi(t.type,!1);case 11:return vi(t.type.render,!1);case 1:return vi(t.type,!0);case 31:return Hl("Activity");default:return""}}function ar(t){try{var e="",l=null;do e+=lm(t,l),l=t,t=t.return;while(t);return e}catch(a){return` +Error generating stack: `+a.message+` +`+a.stack}}var bi=Object.prototype.hasOwnProperty,xi=c.unstable_scheduleCallback,Si=c.unstable_cancelCallback,am=c.unstable_shouldYield,nm=c.unstable_requestPaint,ce=c.unstable_now,um=c.unstable_getCurrentPriorityLevel,nr=c.unstable_ImmediatePriority,ur=c.unstable_UserBlockingPriority,Xn=c.unstable_NormalPriority,im=c.unstable_LowPriority,ir=c.unstable_IdlePriority,cm=c.log,sm=c.unstable_setDisableYieldValue,ka=null,se=null;function ol(t){if(typeof cm=="function"&&sm(t),se&&typeof se.setStrictMode=="function")try{se.setStrictMode(ka,t)}catch{}}var re=Math.clz32?Math.clz32:om,rm=Math.log,fm=Math.LN2;function om(t){return t>>>=0,t===0?32:31-(rm(t)/fm|0)|0}var Zn=256,Kn=262144,Jn=4194304;function Bl(t){var e=t&42;if(e!==0)return e;switch(t&-t){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 t&261888;case 262144:case 524288:case 1048576:case 2097152:return t&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return t&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return t}}function $n(t,e,l){var a=t.pendingLanes;if(a===0)return 0;var n=0,u=t.suspendedLanes,i=t.pingedLanes;t=t.warmLanes;var r=a&134217727;return r!==0?(a=r&~u,a!==0?n=Bl(a):(i&=r,i!==0?n=Bl(i):l||(l=r&~t,l!==0&&(n=Bl(l))))):(r=a&~u,r!==0?n=Bl(r):i!==0?n=Bl(i):l||(l=a&~t,l!==0&&(n=Bl(l)))),n===0?0:e!==0&&e!==n&&(e&u)===0&&(u=n&-n,l=e&-e,u>=l||u===32&&(l&4194048)!==0)?e:n}function Qa(t,e){return(t.pendingLanes&~(t.suspendedLanes&~t.pingedLanes)&e)===0}function dm(t,e){switch(t){case 1:case 2:case 4:case 8:case 64:return e+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 e+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 cr(){var t=Jn;return Jn<<=1,(Jn&62914560)===0&&(Jn=4194304),t}function Ei(t){for(var e=[],l=0;31>l;l++)e.push(t);return e}function Va(t,e){t.pendingLanes|=e,e!==268435456&&(t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0)}function hm(t,e,l,a,n,u){var i=t.pendingLanes;t.pendingLanes=l,t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0,t.expiredLanes&=l,t.entangledLanes&=l,t.errorRecoveryDisabledLanes&=l,t.shellSuspendCounter=0;var r=t.entanglements,y=t.expirationTimes,z=t.hiddenUpdates;for(l=i&~l;0"u")return null;try{return t.activeElement||t.body}catch{return t.body}}var bm=/[\n"\\]/g;function Se(t){return t.replace(bm,function(e){return"\\"+e.charCodeAt(0).toString(16)+" "})}function Ri(t,e,l,a,n,u,i,r){t.name="",i!=null&&typeof i!="function"&&typeof i!="symbol"&&typeof i!="boolean"?t.type=i:t.removeAttribute("type"),e!=null?i==="number"?(e===0&&t.value===""||t.value!=e)&&(t.value=""+xe(e)):t.value!==""+xe(e)&&(t.value=""+xe(e)):i!=="submit"&&i!=="reset"||t.removeAttribute("value"),e!=null?Mi(t,i,xe(e)):l!=null?Mi(t,i,xe(l)):a!=null&&t.removeAttribute("value"),n==null&&u!=null&&(t.defaultChecked=!!u),n!=null&&(t.checked=n&&typeof n!="function"&&typeof n!="symbol"),r!=null&&typeof r!="function"&&typeof r!="symbol"&&typeof r!="boolean"?t.name=""+xe(r):t.removeAttribute("name")}function xr(t,e,l,a,n,u,i,r){if(u!=null&&typeof u!="function"&&typeof u!="symbol"&&typeof u!="boolean"&&(t.type=u),e!=null||l!=null){if(!(u!=="submit"&&u!=="reset"||e!=null)){ji(t);return}l=l!=null?""+xe(l):"",e=e!=null?""+xe(e):l,r||e===t.value||(t.value=e),t.defaultValue=e}a=a??n,a=typeof a!="function"&&typeof a!="symbol"&&!!a,t.checked=r?t.checked:!!a,t.defaultChecked=!!a,i!=null&&typeof i!="function"&&typeof i!="symbol"&&typeof i!="boolean"&&(t.name=i),ji(t)}function Mi(t,e,l){e==="number"&&In(t.ownerDocument)===t||t.defaultValue===""+l||(t.defaultValue=""+l)}function ia(t,e,l,a){if(t=t.options,e){e={};for(var n=0;n"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),Ui=!1;if(Ve)try{var Ja={};Object.defineProperty(Ja,"passive",{get:function(){Ui=!0}}),window.addEventListener("test",Ja,Ja),window.removeEventListener("test",Ja,Ja)}catch{Ui=!1}var hl=null,wi=null,tu=null;function jr(){if(tu)return tu;var t,e=wi,l=e.length,a,n="value"in hl?hl.value:hl.textContent,u=n.length;for(t=0;t=Fa),Cr=" ",Ur=!1;function wr(t,e){switch(t){case"keyup":return Km.indexOf(e.keyCode)!==-1;case"keydown":return e.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Hr(t){return t=t.detail,typeof t=="object"&&"data"in t?t.data:null}var fa=!1;function $m(t,e){switch(t){case"compositionend":return Hr(e);case"keypress":return e.which!==32?null:(Ur=!0,Cr);case"textInput":return t=e.data,t===Cr&&Ur?null:t;default:return null}}function Wm(t,e){if(fa)return t==="compositionend"||!Yi&&wr(t,e)?(t=jr(),tu=wi=hl=null,fa=!1,t):null;switch(t){case"paste":return null;case"keypress":if(!(e.ctrlKey||e.altKey||e.metaKey)||e.ctrlKey&&e.altKey){if(e.char&&1=e)return{node:l,offset:e-t};t=a}t:{for(;l;){if(l.nextSibling){l=l.nextSibling;break t}l=l.parentNode}l=void 0}l=Vr(l)}}function Zr(t,e){return t&&e?t===e?!0:t&&t.nodeType===3?!1:e&&e.nodeType===3?Zr(t,e.parentNode):"contains"in t?t.contains(e):t.compareDocumentPosition?!!(t.compareDocumentPosition(e)&16):!1:!1}function Kr(t){t=t!=null&&t.ownerDocument!=null&&t.ownerDocument.defaultView!=null?t.ownerDocument.defaultView:window;for(var e=In(t.document);e instanceof t.HTMLIFrameElement;){try{var l=typeof e.contentWindow.location.href=="string"}catch{l=!1}if(l)t=e.contentWindow;else break;e=In(t.document)}return e}function Qi(t){var e=t&&t.nodeName&&t.nodeName.toLowerCase();return e&&(e==="input"&&(t.type==="text"||t.type==="search"||t.type==="tel"||t.type==="url"||t.type==="password")||e==="textarea"||t.contentEditable==="true")}var n0=Ve&&"documentMode"in document&&11>=document.documentMode,oa=null,Vi=null,en=null,Xi=!1;function Jr(t,e,l){var a=l.window===l?l.document:l.nodeType===9?l:l.ownerDocument;Xi||oa==null||oa!==In(a)||(a=oa,"selectionStart"in a&&Qi(a)?a={start:a.selectionStart,end:a.selectionEnd}:(a=(a.ownerDocument&&a.ownerDocument.defaultView||window).getSelection(),a={anchorNode:a.anchorNode,anchorOffset:a.anchorOffset,focusNode:a.focusNode,focusOffset:a.focusOffset}),en&&tn(en,a)||(en=a,a=Ku(Vi,"onSelect"),0>=i,n-=i,He=1<<32-re(e)+n|l<lt?(ct=k,k=null):ct=k.sibling;var ft=_(x,k,E[lt],D);if(ft===null){k===null&&(k=ct);break}t&&k&&ft.alternate===null&&e(x,k),p=u(ft,p,lt),rt===null?V=ft:rt.sibling=ft,rt=ft,k=ct}if(lt===E.length)return l(x,k),st&&Ze(x,lt),V;if(k===null){for(;ltlt?(ct=k,k=null):ct=k.sibling;var wl=_(x,k,ft.value,D);if(wl===null){k===null&&(k=ct);break}t&&k&&wl.alternate===null&&e(x,k),p=u(wl,p,lt),rt===null?V=wl:rt.sibling=wl,rt=wl,k=ct}if(ft.done)return l(x,k),st&&Ze(x,lt),V;if(k===null){for(;!ft.done;lt++,ft=E.next())ft=C(x,ft.value,D),ft!==null&&(p=u(ft,p,lt),rt===null?V=ft:rt.sibling=ft,rt=ft);return st&&Ze(x,lt),V}for(k=a(k);!ft.done;lt++,ft=E.next())ft=R(k,x,lt,ft.value,D),ft!==null&&(t&&ft.alternate!==null&&k.delete(ft.key===null?lt:ft.key),p=u(ft,p,lt),rt===null?V=ft:rt.sibling=ft,rt=ft);return t&&k.forEach(function(_1){return e(x,_1)}),st&&Ze(x,lt),V}function bt(x,p,E,D){if(typeof E=="object"&&E!==null&&E.type===Y&&E.key===null&&(E=E.props.children),typeof E=="object"&&E!==null){switch(E.$$typeof){case X:t:{for(var V=E.key;p!==null;){if(p.key===V){if(V=E.type,V===Y){if(p.tag===7){l(x,p.sibling),D=n(p,E.props.children),D.return=x,x=D;break t}}else if(p.elementType===V||typeof V=="object"&&V!==null&&V.$$typeof===Dt&&Jl(V)===p.type){l(x,p.sibling),D=n(p,E.props),sn(D,E),D.return=x,x=D;break t}l(x,p);break}else e(x,p);p=p.sibling}E.type===Y?(D=Ql(E.props.children,x.mode,D,E.key),D.return=x,x=D):(D=fu(E.type,E.key,E.props,null,x.mode,D),sn(D,E),D.return=x,x=D)}return i(x);case Q:t:{for(V=E.key;p!==null;){if(p.key===V)if(p.tag===4&&p.stateNode.containerInfo===E.containerInfo&&p.stateNode.implementation===E.implementation){l(x,p.sibling),D=n(p,E.children||[]),D.return=x,x=D;break t}else{l(x,p);break}else e(x,p);p=p.sibling}D=Ii(E,x.mode,D),D.return=x,x=D}return i(x);case Dt:return E=Jl(E),bt(x,p,E,D)}if(Ht(E))return L(x,p,E,D);if(Wt(E)){if(V=Wt(E),typeof V!="function")throw Error(s(150));return E=V.call(E),Z(x,p,E,D)}if(typeof E.then=="function")return bt(x,p,pu(E),D);if(E.$$typeof===$)return bt(x,p,hu(x,E),D);vu(x,E)}return typeof E=="string"&&E!==""||typeof E=="number"||typeof E=="bigint"?(E=""+E,p!==null&&p.tag===6?(l(x,p.sibling),D=n(p,E),D.return=x,x=D):(l(x,p),D=Fi(E,x.mode,D),D.return=x,x=D),i(x)):l(x,p)}return function(x,p,E,D){try{cn=0;var V=bt(x,p,E,D);return Ea=null,V}catch(k){if(k===Sa||k===yu)throw k;var rt=oe(29,k,null,x.mode);return rt.lanes=D,rt.return=x,rt}}}var Wl=vf(!0),bf=vf(!1),vl=!1;function fc(t){t.updateQueue={baseState:t.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function oc(t,e){t=t.updateQueue,e.updateQueue===t&&(e.updateQueue={baseState:t.baseState,firstBaseUpdate:t.firstBaseUpdate,lastBaseUpdate:t.lastBaseUpdate,shared:t.shared,callbacks:null})}function bl(t){return{lane:t,tag:0,payload:null,callback:null,next:null}}function xl(t,e,l){var a=t.updateQueue;if(a===null)return null;if(a=a.shared,(dt&2)!==0){var n=a.pending;return n===null?e.next=e:(e.next=n.next,n.next=e),a.pending=e,e=ru(t),ef(t,null,l),e}return su(t,a,e,l),ru(t)}function rn(t,e,l){if(e=e.updateQueue,e!==null&&(e=e.shared,(l&4194048)!==0)){var a=e.lanes;a&=t.pendingLanes,l|=a,e.lanes=l,rr(t,l)}}function dc(t,e){var l=t.updateQueue,a=t.alternate;if(a!==null&&(a=a.updateQueue,l===a)){var n=null,u=null;if(l=l.firstBaseUpdate,l!==null){do{var i={lane:l.lane,tag:l.tag,payload:l.payload,callback:null,next:null};u===null?n=u=i:u=u.next=i,l=l.next}while(l!==null);u===null?n=u=e:u=u.next=e}else n=u=e;l={baseState:a.baseState,firstBaseUpdate:n,lastBaseUpdate:u,shared:a.shared,callbacks:a.callbacks},t.updateQueue=l;return}t=l.lastBaseUpdate,t===null?l.firstBaseUpdate=e:t.next=e,l.lastBaseUpdate=e}var hc=!1;function fn(){if(hc){var t=xa;if(t!==null)throw t}}function on(t,e,l,a){hc=!1;var n=t.updateQueue;vl=!1;var u=n.firstBaseUpdate,i=n.lastBaseUpdate,r=n.shared.pending;if(r!==null){n.shared.pending=null;var y=r,z=y.next;y.next=null,i===null?u=z:i.next=z,i=y;var M=t.alternate;M!==null&&(M=M.updateQueue,r=M.lastBaseUpdate,r!==i&&(r===null?M.firstBaseUpdate=z:r.next=z,M.lastBaseUpdate=y))}if(u!==null){var C=n.baseState;i=0,M=z=y=null,r=u;do{var _=r.lane&-536870913,R=_!==r.lane;if(R?(it&_)===_:(a&_)===_){_!==0&&_===ba&&(hc=!0),M!==null&&(M=M.next={lane:0,tag:r.tag,payload:r.payload,callback:null,next:null});t:{var L=t,Z=r;_=e;var bt=l;switch(Z.tag){case 1:if(L=Z.payload,typeof L=="function"){C=L.call(bt,C,_);break t}C=L;break t;case 3:L.flags=L.flags&-65537|128;case 0:if(L=Z.payload,_=typeof L=="function"?L.call(bt,C,_):L,_==null)break t;C=T({},C,_);break t;case 2:vl=!0}}_=r.callback,_!==null&&(t.flags|=64,R&&(t.flags|=8192),R=n.callbacks,R===null?n.callbacks=[_]:R.push(_))}else R={lane:_,tag:r.tag,payload:r.payload,callback:r.callback,next:null},M===null?(z=M=R,y=C):M=M.next=R,i|=_;if(r=r.next,r===null){if(r=n.shared.pending,r===null)break;R=r,r=R.next,R.next=null,n.lastBaseUpdate=R,n.shared.pending=null}}while(!0);M===null&&(y=C),n.baseState=y,n.firstBaseUpdate=z,n.lastBaseUpdate=M,u===null&&(n.shared.lanes=0),Tl|=i,t.lanes=i,t.memoizedState=C}}function xf(t,e){if(typeof t!="function")throw Error(s(191,t));t.call(e)}function Sf(t,e){var l=t.callbacks;if(l!==null)for(t.callbacks=null,t=0;tu?u:8;var i=O.T,r={};O.T=r,Dc(t,!1,e,l);try{var y=n(),z=O.S;if(z!==null&&z(r,y),y!==null&&typeof y=="object"&&typeof y.then=="function"){var M=h0(y,a);mn(t,e,M,ge(t))}else mn(t,e,a,ge(t))}catch(C){mn(t,e,{then:function(){},status:"rejected",reason:C},ge())}finally{B.p=u,i!==null&&r.types!==null&&(i.types=r.types),O.T=i}}function b0(){}function Oc(t,e,l,a){if(t.tag!==5)throw Error(s(476));var n=Pf(t).queue;If(t,n,e,W,l===null?b0:function(){return to(t),l(a)})}function Pf(t){var e=t.memoizedState;if(e!==null)return e;e={memoizedState:W,baseState:W,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:We,lastRenderedState:W},next:null};var l={};return e.next={memoizedState:l,baseState:l,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:We,lastRenderedState:l},next:null},t.memoizedState=e,t=t.alternate,t!==null&&(t.memoizedState=e),e}function to(t){var e=Pf(t);e.next===null&&(e=t.alternate.memoizedState),mn(t,e.next.queue,{},ge())}function Nc(){return Zt(Nn)}function eo(){return wt().memoizedState}function lo(){return wt().memoizedState}function x0(t){for(var e=t.return;e!==null;){switch(e.tag){case 24:case 3:var l=ge();t=bl(l);var a=xl(e,t,l);a!==null&&(ie(a,e,l),rn(a,e,l)),e={cache:ic()},t.payload=e;return}e=e.return}}function S0(t,e,l){var a=ge();l={lane:a,revertLane:0,gesture:null,action:l,hasEagerState:!1,eagerState:null,next:null},Ru(t)?no(e,l):(l=$i(t,e,l,a),l!==null&&(ie(l,t,a),uo(l,e,a)))}function ao(t,e,l){var a=ge();mn(t,e,l,a)}function mn(t,e,l,a){var n={lane:a,revertLane:0,gesture:null,action:l,hasEagerState:!1,eagerState:null,next:null};if(Ru(t))no(e,n);else{var u=t.alternate;if(t.lanes===0&&(u===null||u.lanes===0)&&(u=e.lastRenderedReducer,u!==null))try{var i=e.lastRenderedState,r=u(i,l);if(n.hasEagerState=!0,n.eagerState=r,fe(r,i))return su(t,e,n,0),zt===null&&cu(),!1}catch{}if(l=$i(t,e,n,a),l!==null)return ie(l,t,a),uo(l,e,a),!0}return!1}function Dc(t,e,l,a){if(a={lane:2,revertLane:fs(),gesture:null,action:a,hasEagerState:!1,eagerState:null,next:null},Ru(t)){if(e)throw Error(s(479))}else e=$i(t,l,a,2),e!==null&&ie(e,t,2)}function Ru(t){var e=t.alternate;return t===tt||e!==null&&e===tt}function no(t,e){_a=Su=!0;var l=t.pending;l===null?e.next=e:(e.next=l.next,l.next=e),t.pending=e}function uo(t,e,l){if((l&4194048)!==0){var a=e.lanes;a&=t.pendingLanes,l|=a,e.lanes=l,rr(t,l)}}var yn={readContext:Zt,use:_u,useCallback:Mt,useContext:Mt,useEffect:Mt,useImperativeHandle:Mt,useLayoutEffect:Mt,useInsertionEffect:Mt,useMemo:Mt,useReducer:Mt,useRef:Mt,useState:Mt,useDebugValue:Mt,useDeferredValue:Mt,useTransition:Mt,useSyncExternalStore:Mt,useId:Mt,useHostTransitionStatus:Mt,useFormState:Mt,useActionState:Mt,useOptimistic:Mt,useMemoCache:Mt,useCacheRefresh:Mt};yn.useEffectEvent=Mt;var io={readContext:Zt,use:_u,useCallback:function(t,e){return Pt().memoizedState=[t,e===void 0?null:e],t},useContext:Zt,useEffect:Qf,useImperativeHandle:function(t,e,l){l=l!=null?l.concat([t]):null,Au(4194308,4,Kf.bind(null,e,t),l)},useLayoutEffect:function(t,e){return Au(4194308,4,t,e)},useInsertionEffect:function(t,e){Au(4,2,t,e)},useMemo:function(t,e){var l=Pt();e=e===void 0?null:e;var a=t();if(Fl){ol(!0);try{t()}finally{ol(!1)}}return l.memoizedState=[a,e],a},useReducer:function(t,e,l){var a=Pt();if(l!==void 0){var n=l(e);if(Fl){ol(!0);try{l(e)}finally{ol(!1)}}}else n=e;return a.memoizedState=a.baseState=n,t={pending:null,lanes:0,dispatch:null,lastRenderedReducer:t,lastRenderedState:n},a.queue=t,t=t.dispatch=S0.bind(null,tt,t),[a.memoizedState,t]},useRef:function(t){var e=Pt();return t={current:t},e.memoizedState=t},useState:function(t){t=Tc(t);var e=t.queue,l=ao.bind(null,tt,e);return e.dispatch=l,[t.memoizedState,l]},useDebugValue:Rc,useDeferredValue:function(t,e){var l=Pt();return Mc(l,t,e)},useTransition:function(){var t=Tc(!1);return t=If.bind(null,tt,t.queue,!0,!1),Pt().memoizedState=t,[!1,t]},useSyncExternalStore:function(t,e,l){var a=tt,n=Pt();if(st){if(l===void 0)throw Error(s(407));l=l()}else{if(l=e(),zt===null)throw Error(s(349));(it&127)!==0||jf(a,e,l)}n.memoizedState=l;var u={value:l,getSnapshot:e};return n.queue=u,Qf(Mf.bind(null,a,u,t),[t]),a.flags|=2048,Aa(9,{destroy:void 0},Rf.bind(null,a,u,l,e),null),l},useId:function(){var t=Pt(),e=zt.identifierPrefix;if(st){var l=Be,a=He;l=(a&~(1<<32-re(a)-1)).toString(32)+l,e="_"+e+"R_"+l,l=Eu++,0<\/script>",u=u.removeChild(u.firstChild);break;case"select":u=typeof a.is=="string"?i.createElement("select",{is:a.is}):i.createElement("select"),a.multiple?u.multiple=!0:a.size&&(u.size=a.size);break;default:u=typeof a.is=="string"?i.createElement(n,{is:a.is}):i.createElement(n)}}u[Vt]=e,u[te]=a;t:for(i=e.child;i!==null;){if(i.tag===5||i.tag===6)u.appendChild(i.stateNode);else if(i.tag!==4&&i.tag!==27&&i.child!==null){i.child.return=i,i=i.child;continue}if(i===e)break t;for(;i.sibling===null;){if(i.return===null||i.return===e)break t;i=i.return}i.sibling.return=i.return,i=i.sibling}e.stateNode=u;t:switch(Jt(u,n,a),n){case"button":case"input":case"select":case"textarea":a=!!a.autoFocus;break t;case"img":a=!0;break t;default:a=!1}a&&Ie(e)}}return Tt(e),Zc(e,e.type,t===null?null:t.memoizedProps,e.pendingProps,l),null;case 6:if(t&&e.stateNode!=null)t.memoizedProps!==a&&Ie(e);else{if(typeof a!="string"&&e.stateNode===null)throw Error(s(166));if(t=at.current,pa(e)){if(t=e.stateNode,l=e.memoizedProps,a=null,n=Xt,n!==null)switch(n.tag){case 27:case 5:a=n.memoizedProps}t[Vt]=e,t=!!(t.nodeValue===l||a!==null&&a.suppressHydrationWarning===!0||Ad(t.nodeValue,l)),t||gl(e,!0)}else t=Ju(t).createTextNode(a),t[Vt]=e,e.stateNode=t}return Tt(e),null;case 31:if(l=e.memoizedState,t===null||t.memoizedState!==null){if(a=pa(e),l!==null){if(t===null){if(!a)throw Error(s(318));if(t=e.memoizedState,t=t!==null?t.dehydrated:null,!t)throw Error(s(557));t[Vt]=e}else Vl(),(e.flags&128)===0&&(e.memoizedState=null),e.flags|=4;Tt(e),t=!1}else l=lc(),t!==null&&t.memoizedState!==null&&(t.memoizedState.hydrationErrors=l),t=!0;if(!t)return e.flags&256?(he(e),e):(he(e),null);if((e.flags&128)!==0)throw Error(s(558))}return Tt(e),null;case 13:if(a=e.memoizedState,t===null||t.memoizedState!==null&&t.memoizedState.dehydrated!==null){if(n=pa(e),a!==null&&a.dehydrated!==null){if(t===null){if(!n)throw Error(s(318));if(n=e.memoizedState,n=n!==null?n.dehydrated:null,!n)throw Error(s(317));n[Vt]=e}else Vl(),(e.flags&128)===0&&(e.memoizedState=null),e.flags|=4;Tt(e),n=!1}else n=lc(),t!==null&&t.memoizedState!==null&&(t.memoizedState.hydrationErrors=n),n=!0;if(!n)return e.flags&256?(he(e),e):(he(e),null)}return he(e),(e.flags&128)!==0?(e.lanes=l,e):(l=a!==null,t=t!==null&&t.memoizedState!==null,l&&(a=e.child,n=null,a.alternate!==null&&a.alternate.memoizedState!==null&&a.alternate.memoizedState.cachePool!==null&&(n=a.alternate.memoizedState.cachePool.pool),u=null,a.memoizedState!==null&&a.memoizedState.cachePool!==null&&(u=a.memoizedState.cachePool.pool),u!==n&&(a.flags|=2048)),l!==t&&l&&(e.child.flags|=8192),Cu(e,e.updateQueue),Tt(e),null);case 4:return Ct(),t===null&&ms(e.stateNode.containerInfo),Tt(e),null;case 10:return Je(e.type),Tt(e),null;case 19:if(U(Ut),a=e.memoizedState,a===null)return Tt(e),null;if(n=(e.flags&128)!==0,u=a.rendering,u===null)if(n)pn(a,!1);else{if(Ot!==0||t!==null&&(t.flags&128)!==0)for(t=e.child;t!==null;){if(u=xu(t),u!==null){for(e.flags|=128,pn(a,!1),t=u.updateQueue,e.updateQueue=t,Cu(e,t),e.subtreeFlags=0,t=l,l=e.child;l!==null;)lf(l,t),l=l.sibling;return q(Ut,Ut.current&1|2),st&&Ze(e,a.treeForkCount),e.child}t=t.sibling}a.tail!==null&&ce()>qu&&(e.flags|=128,n=!0,pn(a,!1),e.lanes=4194304)}else{if(!n)if(t=xu(u),t!==null){if(e.flags|=128,n=!0,t=t.updateQueue,e.updateQueue=t,Cu(e,t),pn(a,!0),a.tail===null&&a.tailMode==="hidden"&&!u.alternate&&!st)return Tt(e),null}else 2*ce()-a.renderingStartTime>qu&&l!==536870912&&(e.flags|=128,n=!0,pn(a,!1),e.lanes=4194304);a.isBackwards?(u.sibling=e.child,e.child=u):(t=a.last,t!==null?t.sibling=u:e.child=u,a.last=u)}return a.tail!==null?(t=a.tail,a.rendering=t,a.tail=t.sibling,a.renderingStartTime=ce(),t.sibling=null,l=Ut.current,q(Ut,n?l&1|2:l&1),st&&Ze(e,a.treeForkCount),t):(Tt(e),null);case 22:case 23:return he(e),yc(),a=e.memoizedState!==null,t!==null?t.memoizedState!==null!==a&&(e.flags|=8192):a&&(e.flags|=8192),a?(l&536870912)!==0&&(e.flags&128)===0&&(Tt(e),e.subtreeFlags&6&&(e.flags|=8192)):Tt(e),l=e.updateQueue,l!==null&&Cu(e,l.retryQueue),l=null,t!==null&&t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(l=t.memoizedState.cachePool.pool),a=null,e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(a=e.memoizedState.cachePool.pool),a!==l&&(e.flags|=2048),t!==null&&U(Kl),null;case 24:return l=null,t!==null&&(l=t.memoizedState.cache),e.memoizedState.cache!==l&&(e.flags|=2048),Je(Bt),Tt(e),null;case 25:return null;case 30:return null}throw Error(s(156,e.tag))}function A0(t,e){switch(tc(e),e.tag){case 1:return t=e.flags,t&65536?(e.flags=t&-65537|128,e):null;case 3:return Je(Bt),Ct(),t=e.flags,(t&65536)!==0&&(t&128)===0?(e.flags=t&-65537|128,e):null;case 26:case 27:case 5:return Vn(e),null;case 31:if(e.memoizedState!==null){if(he(e),e.alternate===null)throw Error(s(340));Vl()}return t=e.flags,t&65536?(e.flags=t&-65537|128,e):null;case 13:if(he(e),t=e.memoizedState,t!==null&&t.dehydrated!==null){if(e.alternate===null)throw Error(s(340));Vl()}return t=e.flags,t&65536?(e.flags=t&-65537|128,e):null;case 19:return U(Ut),null;case 4:return Ct(),null;case 10:return Je(e.type),null;case 22:case 23:return he(e),yc(),t!==null&&U(Kl),t=e.flags,t&65536?(e.flags=t&-65537|128,e):null;case 24:return Je(Bt),null;case 25:return null;default:return null}}function No(t,e){switch(tc(e),e.tag){case 3:Je(Bt),Ct();break;case 26:case 27:case 5:Vn(e);break;case 4:Ct();break;case 31:e.memoizedState!==null&&he(e);break;case 13:he(e);break;case 19:U(Ut);break;case 10:Je(e.type);break;case 22:case 23:he(e),yc(),t!==null&&U(Kl);break;case 24:Je(Bt)}}function vn(t,e){try{var l=e.updateQueue,a=l!==null?l.lastEffect:null;if(a!==null){var n=a.next;l=n;do{if((l.tag&t)===t){a=void 0;var u=l.create,i=l.inst;a=u(),i.destroy=a}l=l.next}while(l!==n)}}catch(r){yt(e,e.return,r)}}function zl(t,e,l){try{var a=e.updateQueue,n=a!==null?a.lastEffect:null;if(n!==null){var u=n.next;a=u;do{if((a.tag&t)===t){var i=a.inst,r=i.destroy;if(r!==void 0){i.destroy=void 0,n=e;var y=l,z=r;try{z()}catch(M){yt(n,y,M)}}}a=a.next}while(a!==u)}}catch(M){yt(e,e.return,M)}}function Do(t){var e=t.updateQueue;if(e!==null){var l=t.stateNode;try{Sf(e,l)}catch(a){yt(t,t.return,a)}}}function Co(t,e,l){l.props=Il(t.type,t.memoizedProps),l.state=t.memoizedState;try{l.componentWillUnmount()}catch(a){yt(t,e,a)}}function bn(t,e){try{var l=t.ref;if(l!==null){switch(t.tag){case 26:case 27:case 5:var a=t.stateNode;break;case 30:a=t.stateNode;break;default:a=t.stateNode}typeof l=="function"?t.refCleanup=l(a):l.current=a}}catch(n){yt(t,e,n)}}function qe(t,e){var l=t.ref,a=t.refCleanup;if(l!==null)if(typeof a=="function")try{a()}catch(n){yt(t,e,n)}finally{t.refCleanup=null,t=t.alternate,t!=null&&(t.refCleanup=null)}else if(typeof l=="function")try{l(null)}catch(n){yt(t,e,n)}else l.current=null}function Uo(t){var e=t.type,l=t.memoizedProps,a=t.stateNode;try{t:switch(e){case"button":case"input":case"select":case"textarea":l.autoFocus&&a.focus();break t;case"img":l.src?a.src=l.src:l.srcSet&&(a.srcset=l.srcSet)}}catch(n){yt(t,t.return,n)}}function Kc(t,e,l){try{var a=t.stateNode;J0(a,t.type,l,e),a[te]=e}catch(n){yt(t,t.return,n)}}function wo(t){return t.tag===5||t.tag===3||t.tag===26||t.tag===27&&Ol(t.type)||t.tag===4}function Jc(t){t:for(;;){for(;t.sibling===null;){if(t.return===null||wo(t.return))return null;t=t.return}for(t.sibling.return=t.return,t=t.sibling;t.tag!==5&&t.tag!==6&&t.tag!==18;){if(t.tag===27&&Ol(t.type)||t.flags&2||t.child===null||t.tag===4)continue t;t.child.return=t,t=t.child}if(!(t.flags&2))return t.stateNode}}function $c(t,e,l){var a=t.tag;if(a===5||a===6)t=t.stateNode,e?(l.nodeType===9?l.body:l.nodeName==="HTML"?l.ownerDocument.body:l).insertBefore(t,e):(e=l.nodeType===9?l.body:l.nodeName==="HTML"?l.ownerDocument.body:l,e.appendChild(t),l=l._reactRootContainer,l!=null||e.onclick!==null||(e.onclick=Qe));else if(a!==4&&(a===27&&Ol(t.type)&&(l=t.stateNode,e=null),t=t.child,t!==null))for($c(t,e,l),t=t.sibling;t!==null;)$c(t,e,l),t=t.sibling}function Uu(t,e,l){var a=t.tag;if(a===5||a===6)t=t.stateNode,e?l.insertBefore(t,e):l.appendChild(t);else if(a!==4&&(a===27&&Ol(t.type)&&(l=t.stateNode),t=t.child,t!==null))for(Uu(t,e,l),t=t.sibling;t!==null;)Uu(t,e,l),t=t.sibling}function Ho(t){var e=t.stateNode,l=t.memoizedProps;try{for(var a=t.type,n=e.attributes;n.length;)e.removeAttributeNode(n[0]);Jt(e,a,l),e[Vt]=t,e[te]=l}catch(u){yt(t,t.return,u)}}var Pe=!1,Yt=!1,Wc=!1,Bo=typeof WeakSet=="function"?WeakSet:Set,Qt=null;function j0(t,e){if(t=t.containerInfo,ps=ei,t=Kr(t),Qi(t)){if("selectionStart"in t)var l={start:t.selectionStart,end:t.selectionEnd};else t:{l=(l=t.ownerDocument)&&l.defaultView||window;var a=l.getSelection&&l.getSelection();if(a&&a.rangeCount!==0){l=a.anchorNode;var n=a.anchorOffset,u=a.focusNode;a=a.focusOffset;try{l.nodeType,u.nodeType}catch{l=null;break t}var i=0,r=-1,y=-1,z=0,M=0,C=t,_=null;e:for(;;){for(var R;C!==l||n!==0&&C.nodeType!==3||(r=i+n),C!==u||a!==0&&C.nodeType!==3||(y=i+a),C.nodeType===3&&(i+=C.nodeValue.length),(R=C.firstChild)!==null;)_=C,C=R;for(;;){if(C===t)break e;if(_===l&&++z===n&&(r=i),_===u&&++M===a&&(y=i),(R=C.nextSibling)!==null)break;C=_,_=C.parentNode}C=R}l=r===-1||y===-1?null:{start:r,end:y}}else l=null}l=l||{start:0,end:0}}else l=null;for(vs={focusedElem:t,selectionRange:l},ei=!1,Qt=e;Qt!==null;)if(e=Qt,t=e.child,(e.subtreeFlags&1028)!==0&&t!==null)t.return=e,Qt=t;else for(;Qt!==null;){switch(e=Qt,u=e.alternate,t=e.flags,e.tag){case 0:if((t&4)!==0&&(t=e.updateQueue,t=t!==null?t.events:null,t!==null))for(l=0;l title"))),Jt(u,a,l),u[Vt]=t,kt(u),a=u;break t;case"link":var i=Qd("link","href",n).get(a+(l.href||""));if(i){for(var r=0;rbt&&(i=bt,bt=Z,Z=i);var x=Xr(r,Z),p=Xr(r,bt);if(x&&p&&(R.rangeCount!==1||R.anchorNode!==x.node||R.anchorOffset!==x.offset||R.focusNode!==p.node||R.focusOffset!==p.offset)){var E=C.createRange();E.setStart(x.node,x.offset),R.removeAllRanges(),Z>bt?(R.addRange(E),R.extend(p.node,p.offset)):(E.setEnd(p.node,p.offset),R.addRange(E))}}}}for(C=[],R=r;R=R.parentNode;)R.nodeType===1&&C.push({element:R,left:R.scrollLeft,top:R.scrollTop});for(typeof r.focus=="function"&&r.focus(),r=0;rl?32:l,O.T=null,l=as,as=null;var u=jl,i=nl;if(Gt=0,Na=jl=null,nl=0,(dt&6)!==0)throw Error(s(331));var r=dt;if(dt|=4,Jo(u.current),Xo(u,u.current,i,l),dt=r,Tn(0,!1),se&&typeof se.onPostCommitFiberRoot=="function")try{se.onPostCommitFiberRoot(ka,u)}catch{}return!0}finally{B.p=n,O.T=a,dd(t,e)}}function md(t,e,l){e=ze(l,e),e=Hc(t.stateNode,e,2),t=xl(t,e,2),t!==null&&(Va(t,2),Le(t))}function yt(t,e,l){if(t.tag===3)md(t,t,l);else for(;e!==null;){if(e.tag===3){md(e,t,l);break}else if(e.tag===1){var a=e.stateNode;if(typeof e.type.getDerivedStateFromError=="function"||typeof a.componentDidCatch=="function"&&(Al===null||!Al.has(a))){t=ze(l,t),l=yo(2),a=xl(e,l,2),a!==null&&(go(l,a,e,t),Va(a,2),Le(a));break}}e=e.return}}function cs(t,e,l){var a=t.pingCache;if(a===null){a=t.pingCache=new O0;var n=new Set;a.set(e,n)}else n=a.get(e),n===void 0&&(n=new Set,a.set(e,n));n.has(l)||(Pc=!0,n.add(l),t=w0.bind(null,t,e,l),e.then(t,t))}function w0(t,e,l){var a=t.pingCache;a!==null&&a.delete(e),t.pingedLanes|=t.suspendedLanes&l,t.warmLanes&=~l,zt===t&&(it&l)===l&&(Ot===4||Ot===3&&(it&62914560)===it&&300>ce()-Bu?(dt&2)===0&&Da(t,0):ts|=l,Oa===it&&(Oa=0)),Le(t)}function yd(t,e){e===0&&(e=cr()),t=kl(t,e),t!==null&&(Va(t,e),Le(t))}function H0(t){var e=t.memoizedState,l=0;e!==null&&(l=e.retryLane),yd(t,l)}function B0(t,e){var l=0;switch(t.tag){case 31:case 13:var a=t.stateNode,n=t.memoizedState;n!==null&&(l=n.retryLane);break;case 19:a=t.stateNode;break;case 22:a=t.stateNode._retryCache;break;default:throw Error(s(314))}a!==null&&a.delete(e),yd(t,l)}function q0(t,e){return xi(t,e)}var Vu=null,Ua=null,ss=!1,Xu=!1,rs=!1,Ml=0;function Le(t){t!==Ua&&t.next===null&&(Ua===null?Vu=Ua=t:Ua=Ua.next=t),Xu=!0,ss||(ss=!0,Y0())}function Tn(t,e){if(!rs&&Xu){rs=!0;do for(var l=!1,a=Vu;a!==null;){if(t!==0){var n=a.pendingLanes;if(n===0)var u=0;else{var i=a.suspendedLanes,r=a.pingedLanes;u=(1<<31-re(42|t)+1)-1,u&=n&~(i&~r),u=u&201326741?u&201326741|1:u?u|2:0}u!==0&&(l=!0,bd(a,u))}else u=it,u=$n(a,a===zt?u:0,a.cancelPendingCommit!==null||a.timeoutHandle!==-1),(u&3)===0||Qa(a,u)||(l=!0,bd(a,u));a=a.next}while(l);rs=!1}}function L0(){gd()}function gd(){Xu=ss=!1;var t=0;Ml!==0&&W0()&&(t=Ml);for(var e=ce(),l=null,a=Vu;a!==null;){var n=a.next,u=pd(a,e);u===0?(a.next=null,l===null?Vu=n:l.next=n,n===null&&(Ua=l)):(l=a,(t!==0||(u&3)!==0)&&(Xu=!0)),a=n}Gt!==0&&Gt!==5||Tn(t),Ml!==0&&(Ml=0)}function pd(t,e){for(var l=t.suspendedLanes,a=t.pingedLanes,n=t.expirationTimes,u=t.pendingLanes&-62914561;0r)break;var M=y.transferSize,C=y.initiatorType;M&&jd(C)&&(y=y.responseEnd,i+=M*(y"u"?null:document;function Ld(t,e,l){var a=wa;if(a&&typeof e=="string"&&e){var n=Se(e);n='link[rel="'+t+'"][href="'+n+'"]',typeof l=="string"&&(n+='[crossorigin="'+l+'"]'),qd.has(n)||(qd.add(n),t={rel:t,crossOrigin:l,href:e},a.querySelector(n)===null&&(e=a.createElement("link"),Jt(e,"link",t),kt(e),a.head.appendChild(e)))}}function u1(t){ul.D(t),Ld("dns-prefetch",t,null)}function i1(t,e){ul.C(t,e),Ld("preconnect",t,e)}function c1(t,e,l){ul.L(t,e,l);var a=wa;if(a&&t&&e){var n='link[rel="preload"][as="'+Se(e)+'"]';e==="image"&&l&&l.imageSrcSet?(n+='[imagesrcset="'+Se(l.imageSrcSet)+'"]',typeof l.imageSizes=="string"&&(n+='[imagesizes="'+Se(l.imageSizes)+'"]')):n+='[href="'+Se(t)+'"]';var u=n;switch(e){case"style":u=Ha(t);break;case"script":u=Ba(t)}Me.has(u)||(t=T({rel:"preload",href:e==="image"&&l&&l.imageSrcSet?void 0:t,as:e},l),Me.set(u,t),a.querySelector(n)!==null||e==="style"&&a.querySelector(Mn(u))||e==="script"&&a.querySelector(On(u))||(e=a.createElement("link"),Jt(e,"link",t),kt(e),a.head.appendChild(e)))}}function s1(t,e){ul.m(t,e);var l=wa;if(l&&t){var a=e&&typeof e.as=="string"?e.as:"script",n='link[rel="modulepreload"][as="'+Se(a)+'"][href="'+Se(t)+'"]',u=n;switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":u=Ba(t)}if(!Me.has(u)&&(t=T({rel:"modulepreload",href:t},e),Me.set(u,t),l.querySelector(n)===null)){switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(l.querySelector(On(u)))return}a=l.createElement("link"),Jt(a,"link",t),kt(a),l.head.appendChild(a)}}}function r1(t,e,l){ul.S(t,e,l);var a=wa;if(a&&t){var n=na(a).hoistableStyles,u=Ha(t);e=e||"default";var i=n.get(u);if(!i){var r={loading:0,preload:null};if(i=a.querySelector(Mn(u)))r.loading=5;else{t=T({rel:"stylesheet",href:t,"data-precedence":e},l),(l=Me.get(u))&&Ts(t,l);var y=i=a.createElement("link");kt(y),Jt(y,"link",t),y._p=new Promise(function(z,M){y.onload=z,y.onerror=M}),y.addEventListener("load",function(){r.loading|=1}),y.addEventListener("error",function(){r.loading|=2}),r.loading|=4,Wu(i,e,a)}i={type:"stylesheet",instance:i,count:1,state:r},n.set(u,i)}}}function f1(t,e){ul.X(t,e);var l=wa;if(l&&t){var a=na(l).hoistableScripts,n=Ba(t),u=a.get(n);u||(u=l.querySelector(On(n)),u||(t=T({src:t,async:!0},e),(e=Me.get(n))&&As(t,e),u=l.createElement("script"),kt(u),Jt(u,"link",t),l.head.appendChild(u)),u={type:"script",instance:u,count:1,state:null},a.set(n,u))}}function o1(t,e){ul.M(t,e);var l=wa;if(l&&t){var a=na(l).hoistableScripts,n=Ba(t),u=a.get(n);u||(u=l.querySelector(On(n)),u||(t=T({src:t,async:!0,type:"module"},e),(e=Me.get(n))&&As(t,e),u=l.createElement("script"),kt(u),Jt(u,"link",t),l.head.appendChild(u)),u={type:"script",instance:u,count:1,state:null},a.set(n,u))}}function Yd(t,e,l,a){var n=(n=at.current)?$u(n):null;if(!n)throw Error(s(446));switch(t){case"meta":case"title":return null;case"style":return typeof l.precedence=="string"&&typeof l.href=="string"?(e=Ha(l.href),l=na(n).hoistableStyles,a=l.get(e),a||(a={type:"style",instance:null,count:0,state:null},l.set(e,a)),a):{type:"void",instance:null,count:0,state:null};case"link":if(l.rel==="stylesheet"&&typeof l.href=="string"&&typeof l.precedence=="string"){t=Ha(l.href);var u=na(n).hoistableStyles,i=u.get(t);if(i||(n=n.ownerDocument||n,i={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},u.set(t,i),(u=n.querySelector(Mn(t)))&&!u._p&&(i.instance=u,i.state.loading=5),Me.has(t)||(l={rel:"preload",as:"style",href:l.href,crossOrigin:l.crossOrigin,integrity:l.integrity,media:l.media,hrefLang:l.hrefLang,referrerPolicy:l.referrerPolicy},Me.set(t,l),u||d1(n,t,l,i.state))),e&&a===null)throw Error(s(528,""));return i}if(e&&a!==null)throw Error(s(529,""));return null;case"script":return e=l.async,l=l.src,typeof l=="string"&&e&&typeof e!="function"&&typeof e!="symbol"?(e=Ba(l),l=na(n).hoistableScripts,a=l.get(e),a||(a={type:"script",instance:null,count:0,state:null},l.set(e,a)),a):{type:"void",instance:null,count:0,state:null};default:throw Error(s(444,t))}}function Ha(t){return'href="'+Se(t)+'"'}function Mn(t){return'link[rel="stylesheet"]['+t+"]"}function Gd(t){return T({},t,{"data-precedence":t.precedence,precedence:null})}function d1(t,e,l,a){t.querySelector('link[rel="preload"][as="style"]['+e+"]")?a.loading=1:(e=t.createElement("link"),a.preload=e,e.addEventListener("load",function(){return a.loading|=1}),e.addEventListener("error",function(){return a.loading|=2}),Jt(e,"link",l),kt(e),t.head.appendChild(e))}function Ba(t){return'[src="'+Se(t)+'"]'}function On(t){return"script[async]"+t}function kd(t,e,l){if(e.count++,e.instance===null)switch(e.type){case"style":var a=t.querySelector('style[data-href~="'+Se(l.href)+'"]');if(a)return e.instance=a,kt(a),a;var n=T({},l,{"data-href":l.href,"data-precedence":l.precedence,href:null,precedence:null});return a=(t.ownerDocument||t).createElement("style"),kt(a),Jt(a,"style",n),Wu(a,l.precedence,t),e.instance=a;case"stylesheet":n=Ha(l.href);var u=t.querySelector(Mn(n));if(u)return e.state.loading|=4,e.instance=u,kt(u),u;a=Gd(l),(n=Me.get(n))&&Ts(a,n),u=(t.ownerDocument||t).createElement("link"),kt(u);var i=u;return i._p=new Promise(function(r,y){i.onload=r,i.onerror=y}),Jt(u,"link",a),e.state.loading|=4,Wu(u,l.precedence,t),e.instance=u;case"script":return u=Ba(l.src),(n=t.querySelector(On(u)))?(e.instance=n,kt(n),n):(a=l,(n=Me.get(u))&&(a=T({},l),As(a,n)),t=t.ownerDocument||t,n=t.createElement("script"),kt(n),Jt(n,"link",a),t.head.appendChild(n),e.instance=n);case"void":return null;default:throw Error(s(443,e.type))}else e.type==="stylesheet"&&(e.state.loading&4)===0&&(a=e.instance,e.state.loading|=4,Wu(a,l.precedence,t));return e.instance}function Wu(t,e,l){for(var a=l.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),n=a.length?a[a.length-1]:null,u=n,i=0;i title"):null)}function h1(t,e,l){if(l===1||e.itemProp!=null)return!1;switch(t){case"meta":case"title":return!0;case"style":if(typeof e.precedence!="string"||typeof e.href!="string"||e.href==="")break;return!0;case"link":if(typeof e.rel!="string"||typeof e.href!="string"||e.href===""||e.onLoad||e.onError)break;return e.rel==="stylesheet"?(t=e.disabled,typeof e.precedence=="string"&&t==null):!0;case"script":if(e.async&&typeof e.async!="function"&&typeof e.async!="symbol"&&!e.onLoad&&!e.onError&&e.src&&typeof e.src=="string")return!0}return!1}function Xd(t){return!(t.type==="stylesheet"&&(t.state.loading&3)===0)}function m1(t,e,l,a){if(l.type==="stylesheet"&&(typeof a.media!="string"||matchMedia(a.media).matches!==!1)&&(l.state.loading&4)===0){if(l.instance===null){var n=Ha(a.href),u=e.querySelector(Mn(n));if(u){e=u._p,e!==null&&typeof e=="object"&&typeof e.then=="function"&&(t.count++,t=Iu.bind(t),e.then(t,t)),l.state.loading|=4,l.instance=u,kt(u);return}u=e.ownerDocument||e,a=Gd(a),(n=Me.get(n))&&Ts(a,n),u=u.createElement("link"),kt(u);var i=u;i._p=new Promise(function(r,y){i.onload=r,i.onerror=y}),Jt(u,"link",a),l.instance=u}t.stylesheets===null&&(t.stylesheets=new Map),t.stylesheets.set(l,e),(e=l.state.preload)&&(l.state.loading&3)===0&&(t.count++,l=Iu.bind(t),e.addEventListener("load",l),e.addEventListener("error",l))}}var js=0;function y1(t,e){return t.stylesheets&&t.count===0&&ti(t,t.stylesheets),0js?50:800)+e);return t.unsuspend=l,function(){t.unsuspend=null,clearTimeout(a),clearTimeout(n)}}:null}function Iu(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)ti(this,this.stylesheets);else if(this.unsuspend){var t=this.unsuspend;this.unsuspend=null,t()}}}var Pu=null;function ti(t,e){t.stylesheets=null,t.unsuspend!==null&&(t.count++,Pu=new Map,e.forEach(g1,t),Pu=null,Iu.call(t))}function g1(t,e){if(!(e.state.loading&4)){var l=Pu.get(t);if(l)var a=l.get(null);else{l=new Map,Pu.set(t,l);for(var n=t.querySelectorAll("link[data-precedence],style[data-precedence]"),u=0;u"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(c)}catch(f){console.error(f)}}return c(),Hs.exports=D1(),Hs.exports}var U1=C1();const w1="modulepreload",H1=function(c){return"/algorithm-visualizer/"+c},yh={},Nt=function(f,o,s){let h=Promise.resolve();if(o&&o.length>0){let S=function(g){return Promise.all(g.map(N=>Promise.resolve(N).then(T=>({status:"fulfilled",value:T}),T=>({status:"rejected",reason:T}))))};document.getElementsByTagName("link");const b=document.querySelector("meta[property=csp-nonce]"),j=b?.nonce||b?.getAttribute("nonce");h=S(o.map(g=>{if(g=H1(g),g in yh)return;yh[g]=!0;const N=g.endsWith(".css"),T=N?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${g}"]${T}`))return;const w=document.createElement("link");if(w.rel=N?"stylesheet":w1,N||(w.as="script"),w.crossOrigin="",w.href=g,j&&w.setAttribute("nonce",j),document.head.appendChild(w),N)return new Promise((X,Q)=>{w.addEventListener("load",X),w.addEventListener("error",()=>Q(new Error(`Unable to preload CSS for ${g}`)))})}))}function m(b){const j=new Event("vite:preloadError",{cancelable:!0});if(j.payload=b,window.dispatchEvent(j),!j.defaultPrevented)throw b}return h.then(b=>{for(const j of b||[])j.status==="rejected"&&m(j.reason);return f().catch(m)})};var gh="popstate";function ph(c){return typeof c=="object"&&c!=null&&"pathname"in c&&"search"in c&&"hash"in c&&"state"in c&&"key"in c}function B1(c={}){function f(s,h){let m=h.state?.masked,{pathname:b,search:j,hash:S}=m||s.location;return Vs("",{pathname:b,search:j,hash:S},h.state&&h.state.usr||null,h.state&&h.state.key||"default",m?{pathname:s.location.pathname,search:s.location.search,hash:s.location.hash}:void 0)}function o(s,h){return typeof h=="string"?h:qn(h)}return L1(f,o,null,c)}function Rt(c,f){if(c===!1||c===null||typeof c>"u")throw new Error(f)}function Ge(c,f){if(!c){typeof console<"u"&&console.warn(f);try{throw new Error(f)}catch{}}}function q1(){return Math.random().toString(36).substring(2,10)}function vh(c,f){return{usr:c.state,key:c.key,idx:f,masked:c.unstable_mask?{pathname:c.pathname,search:c.search,hash:c.hash}:void 0}}function Vs(c,f,o=null,s,h){return{pathname:typeof c=="string"?c:c.pathname,search:"",hash:"",...typeof f=="string"?La(f):f,state:o,key:f&&f.key||s||q1(),unstable_mask:h}}function qn({pathname:c="/",search:f="",hash:o=""}){return f&&f!=="?"&&(c+=f.charAt(0)==="?"?f:"?"+f),o&&o!=="#"&&(c+=o.charAt(0)==="#"?o:"#"+o),c}function La(c){let f={};if(c){let o=c.indexOf("#");o>=0&&(f.hash=c.substring(o),c=c.substring(0,o));let s=c.indexOf("?");s>=0&&(f.search=c.substring(s),c=c.substring(0,s)),c&&(f.pathname=c)}return f}function L1(c,f,o,s={}){let{window:h=document.defaultView,v5Compat:m=!1}=s,b=h.history,j="POP",S=null,g=N();g==null&&(g=0,b.replaceState({...b.state,idx:g},""));function N(){return(b.state||{idx:null}).idx}function T(){j="POP";let H=N(),K=H==null?null:H-g;g=H,S&&S({action:j,location:Y.location,delta:K})}function w(H,K){j="PUSH";let et=ph(H)?H:Vs(Y.location,H,K);g=N()+1;let $=vh(et,g),xt=Y.createHref(et.unstable_mask||et);try{b.pushState($,"",xt)}catch(St){if(St instanceof DOMException&&St.name==="DataCloneError")throw St;h.location.assign(xt)}m&&S&&S({action:j,location:Y.location,delta:1})}function X(H,K){j="REPLACE";let et=ph(H)?H:Vs(Y.location,H,K);g=N();let $=vh(et,g),xt=Y.createHref(et.unstable_mask||et);b.replaceState($,"",xt),m&&S&&S({action:j,location:Y.location,delta:0})}function Q(H){return Y1(H)}let Y={get action(){return j},get location(){return c(h,b)},listen(H){if(S)throw new Error("A history only accepts one active listener");return h.addEventListener(gh,T),S=H,()=>{h.removeEventListener(gh,T),S=null}},createHref(H){return f(h,H)},createURL:Q,encodeLocation(H){let K=Q(H);return{pathname:K.pathname,search:K.search,hash:K.hash}},push:w,replace:X,go(H){return b.go(H)}};return Y}function Y1(c,f=!1){let o="http://localhost";typeof window<"u"&&(o=window.location.origin!=="null"?window.location.origin:window.location.href),Rt(o,"No window.location.(origin|href) available to create URL");let s=typeof c=="string"?c:qn(c);return s=s.replace(/ $/,"%20"),!f&&s.startsWith("//")&&(s=o+s),new URL(s,o)}function Nh(c,f,o="/"){return G1(c,f,o,!1)}function G1(c,f,o,s){let h=typeof f=="string"?La(f):f,m=sl(h.pathname||"/",o);if(m==null)return null;let b=Dh(c);k1(b);let j=null;for(let S=0;j==null&&S{let N={relativePath:g===void 0?b.path||"":g,caseSensitive:b.caseSensitive===!0,childrenIndex:j,route:b};if(N.relativePath.startsWith("/")){if(!N.relativePath.startsWith(s)&&S)return;Rt(N.relativePath.startsWith(s),`Absolute route path "${N.relativePath}" nested under path "${s}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),N.relativePath=N.relativePath.slice(s.length)}let T=Ye([s,N.relativePath]),w=o.concat(N);b.children&&b.children.length>0&&(Rt(b.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${T}".`),Dh(b.children,f,w,T,S)),!(b.path==null&&!b.index)&&f.push({path:T,score:$1(T,b.index),routesMeta:w})};return c.forEach((b,j)=>{if(b.path===""||!b.path?.includes("?"))m(b,j);else for(let S of Ch(b.path))m(b,j,!0,S)}),f}function Ch(c){let f=c.split("/");if(f.length===0)return[];let[o,...s]=f,h=o.endsWith("?"),m=o.replace(/\?$/,"");if(s.length===0)return h?[m,""]:[m];let b=Ch(s.join("/")),j=[];return j.push(...b.map(S=>S===""?m:[m,S].join("/"))),h&&j.push(...b),j.map(S=>c.startsWith("/")&&S===""?"/":S)}function k1(c){c.sort((f,o)=>f.score!==o.score?o.score-f.score:W1(f.routesMeta.map(s=>s.childrenIndex),o.routesMeta.map(s=>s.childrenIndex)))}var Q1=/^:[\w-]+$/,V1=3,X1=2,Z1=1,K1=10,J1=-2,bh=c=>c==="*";function $1(c,f){let o=c.split("/"),s=o.length;return o.some(bh)&&(s+=J1),f&&(s+=X1),o.filter(h=>!bh(h)).reduce((h,m)=>h+(Q1.test(m)?V1:m===""?Z1:K1),s)}function W1(c,f){return c.length===f.length&&c.slice(0,-1).every((s,h)=>s===f[h])?c[c.length-1]-f[f.length-1]:0}function F1(c,f,o=!1){let{routesMeta:s}=c,h={},m="/",b=[];for(let j=0;j{if(N==="*"){let Q=j[w]||"";b=m.slice(0,m.length-Q.length).replace(/(.)\/+$/,"$1")}const X=j[w];return T&&!X?g[N]=void 0:g[N]=(X||"").replace(/%2F/g,"/"),g},{}),pathname:m,pathnameBase:b,pattern:c}}function I1(c,f=!1,o=!0){Ge(c==="*"||!c.endsWith("*")||c.endsWith("/*"),`Route path "${c}" will be treated as if it were "${c.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${c.replace(/\*$/,"/*")}".`);let s=[],h="^"+c.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(b,j,S,g,N)=>{if(s.push({paramName:j,isOptional:S!=null}),S){let T=N.charAt(g+b.length);return T&&T!=="/"?"/([^\\/]*)":"(?:/([^\\/]*))?"}return"/([^\\/]+)"}).replace(/\/([\w-]+)\?(\/|$)/g,"(/$1)?$2");return c.endsWith("*")?(s.push({paramName:"*"}),h+=c==="*"||c==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):o?h+="\\/*$":c!==""&&c!=="/"&&(h+="(?:(?=\\/|$))"),[new RegExp(h,f?void 0:"i"),s]}function P1(c){try{return c.split("/").map(f=>decodeURIComponent(f).replace(/\//g,"%2F")).join("/")}catch(f){return Ge(!1,`The URL path "${c}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${f}).`),c}}function sl(c,f){if(f==="/")return c;if(!c.toLowerCase().startsWith(f.toLowerCase()))return null;let o=f.endsWith("/")?f.length-1:f.length,s=c.charAt(o);return s&&s!=="/"?null:c.slice(o)||"/"}var ty=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;function ey(c,f="/"){let{pathname:o,search:s="",hash:h=""}=typeof c=="string"?La(c):c,m;return o?(o=o.replace(/\/\/+/g,"/"),o.startsWith("/")?m=xh(o.substring(1),"/"):m=xh(o,f)):m=f,{pathname:m,search:ny(s),hash:uy(h)}}function xh(c,f){let o=f.replace(/\/+$/,"").split("/");return c.split("/").forEach(h=>{h===".."?o.length>1&&o.pop():h!=="."&&o.push(h)}),o.length>1?o.join("/"):"/"}function Ys(c,f,o,s){return`Cannot include a '${c}' character in a manually specified \`to.${f}\` field [${JSON.stringify(s)}]. Please separate it out to the \`to.${o}\` field. Alternatively you may provide the full path as a string in and the router will parse it for you.`}function ly(c){return c.filter((f,o)=>o===0||f.route.path&&f.route.path.length>0)}function Uh(c){let f=ly(c);return f.map((o,s)=>s===f.length-1?o.pathname:o.pathnameBase)}function Ks(c,f,o,s=!1){let h;typeof c=="string"?h=La(c):(h={...c},Rt(!h.pathname||!h.pathname.includes("?"),Ys("?","pathname","search",h)),Rt(!h.pathname||!h.pathname.includes("#"),Ys("#","pathname","hash",h)),Rt(!h.search||!h.search.includes("#"),Ys("#","search","hash",h)));let m=c===""||h.pathname==="",b=m?"/":h.pathname,j;if(b==null)j=o;else{let T=f.length-1;if(!s&&b.startsWith("..")){let w=b.split("/");for(;w[0]==="..";)w.shift(),T-=1;h.pathname=w.join("/")}j=T>=0?f[T]:"/"}let S=ey(h,j),g=b&&b!=="/"&&b.endsWith("/"),N=(m||b===".")&&o.endsWith("/");return!S.pathname.endsWith("/")&&(g||N)&&(S.pathname+="/"),S}var Ye=c=>c.join("/").replace(/\/\/+/g,"/"),ay=c=>c.replace(/\/+$/,"").replace(/^\/*/,"/"),ny=c=>!c||c==="?"?"":c.startsWith("?")?c:"?"+c,uy=c=>!c||c==="#"?"":c.startsWith("#")?c:"#"+c,iy=class{constructor(c,f,o,s=!1){this.status=c,this.statusText=f||"",this.internal=s,o instanceof Error?(this.data=o.toString(),this.error=o):this.data=o}};function cy(c){return c!=null&&typeof c.status=="number"&&typeof c.statusText=="string"&&typeof c.internal=="boolean"&&"data"in c}function sy(c){return c.map(f=>f.route.path).filter(Boolean).join("/").replace(/\/\/*/g,"/")||"/"}var wh=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function Hh(c,f){let o=c;if(typeof o!="string"||!ty.test(o))return{absoluteURL:void 0,isExternal:!1,to:o};let s=o,h=!1;if(wh)try{let m=new URL(window.location.href),b=o.startsWith("//")?new URL(m.protocol+o):new URL(o),j=sl(b.pathname,f);b.origin===m.origin&&j!=null?o=j+b.search+b.hash:h=!0}catch{Ge(!1,` contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}return{absoluteURL:s,isExternal:h,to:o}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");var Bh=["POST","PUT","PATCH","DELETE"];new Set(Bh);var ry=["GET",...Bh];new Set(ry);var Ya=A.createContext(null);Ya.displayName="DataRouter";var mi=A.createContext(null);mi.displayName="DataRouterState";var fy=A.createContext(!1),qh=A.createContext({isTransitioning:!1});qh.displayName="ViewTransition";var oy=A.createContext(new Map);oy.displayName="Fetchers";var dy=A.createContext(null);dy.displayName="Await";var Oe=A.createContext(null);Oe.displayName="Navigation";var Ln=A.createContext(null);Ln.displayName="Location";var rl=A.createContext({outlet:null,matches:[],isDataRoute:!1});rl.displayName="Route";var Js=A.createContext(null);Js.displayName="RouteError";var Lh="REACT_ROUTER_ERROR",hy="REDIRECT",my="ROUTE_ERROR_RESPONSE";function yy(c){if(c.startsWith(`${Lh}:${hy}:{`))try{let f=JSON.parse(c.slice(28));if(typeof f=="object"&&f&&typeof f.status=="number"&&typeof f.statusText=="string"&&typeof f.location=="string"&&typeof f.reloadDocument=="boolean"&&typeof f.replace=="boolean")return f}catch{}}function gy(c){if(c.startsWith(`${Lh}:${my}:{`))try{let f=JSON.parse(c.slice(40));if(typeof f=="object"&&f&&typeof f.status=="number"&&typeof f.statusText=="string")return new iy(f.status,f.statusText,f.data)}catch{}}function py(c,{relative:f}={}){Rt(Yn(),"useHref() may be used only in the context of a component.");let{basename:o,navigator:s}=A.useContext(Oe),{hash:h,pathname:m,search:b}=Gn(c,{relative:f}),j=m;return o!=="/"&&(j=m==="/"?o:Ye([o,m])),s.createHref({pathname:j,search:b,hash:h})}function Yn(){return A.useContext(Ln)!=null}function pe(){return Rt(Yn(),"useLocation() may be used only in the context of a component."),A.useContext(Ln).location}var Yh="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function Gh(c){A.useContext(Oe).static||A.useLayoutEffect(c)}function vy(){let{isDataRoute:c}=A.useContext(rl);return c?Ny():by()}function by(){Rt(Yn(),"useNavigate() may be used only in the context of a component.");let c=A.useContext(Ya),{basename:f,navigator:o}=A.useContext(Oe),{matches:s}=A.useContext(rl),{pathname:h}=pe(),m=JSON.stringify(Uh(s)),b=A.useRef(!1);return Gh(()=>{b.current=!0}),A.useCallback((S,g={})=>{if(Ge(b.current,Yh),!b.current)return;if(typeof S=="number"){o.go(S);return}let N=Ks(S,JSON.parse(m),h,g.relative==="path");c==null&&f!=="/"&&(N.pathname=N.pathname==="/"?f:Ye([f,N.pathname])),(g.replace?o.replace:o.push)(N,g.state,g)},[f,o,m,h,c])}A.createContext(null);function Gn(c,{relative:f}={}){let{matches:o}=A.useContext(rl),{pathname:s}=pe(),h=JSON.stringify(Uh(o));return A.useMemo(()=>Ks(c,JSON.parse(h),s,f==="path"),[c,h,s,f])}function xy(c,f){return kh(c,f)}function kh(c,f,o){Rt(Yn(),"useRoutes() may be used only in the context of a component.");let{navigator:s}=A.useContext(Oe),{matches:h}=A.useContext(rl),m=h[h.length-1],b=m?m.params:{},j=m?m.pathname:"/",S=m?m.pathnameBase:"/",g=m&&m.route;{let H=g&&g.path||"";Vh(j,!g||H.endsWith("*")||H.endsWith("*?"),`You rendered descendant (or called \`useRoutes()\`) at "${j}" (under ) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render. + +Please change the parent to .`)}let N=pe(),T;if(f){let H=typeof f=="string"?La(f):f;Rt(S==="/"||H.pathname?.startsWith(S),`When overriding the location using \`\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${S}" but pathname "${H.pathname}" was given in the \`location\` prop.`),T=H}else T=N;let w=T.pathname||"/",X=w;if(S!=="/"){let H=S.replace(/^\//,"").split("/");X="/"+w.replace(/^\//,"").split("/").slice(H.length).join("/")}let Q=Nh(c,{pathname:X});Ge(g||Q!=null,`No routes matched location "${T.pathname}${T.search}${T.hash}" `),Ge(Q==null||Q[Q.length-1].route.element!==void 0||Q[Q.length-1].route.Component!==void 0||Q[Q.length-1].route.lazy!==void 0,`Matched leaf route at location "${T.pathname}${T.search}${T.hash}" does not have an element or Component. This means it will render an with a null value by default resulting in an "empty" page.`);let Y=Ty(Q&&Q.map(H=>Object.assign({},H,{params:Object.assign({},b,H.params),pathname:Ye([S,s.encodeLocation?s.encodeLocation(H.pathname.replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:H.pathname]),pathnameBase:H.pathnameBase==="/"?S:Ye([S,s.encodeLocation?s.encodeLocation(H.pathnameBase.replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:H.pathnameBase])})),h,o);return f&&Y?A.createElement(Ln.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",unstable_mask:void 0,...T},navigationType:"POP"}},Y):Y}function Sy(){let c=Oy(),f=cy(c)?`${c.status} ${c.statusText}`:c instanceof Error?c.message:JSON.stringify(c),o=c instanceof Error?c.stack:null,s="rgba(200,200,200, 0.5)",h={padding:"0.5rem",backgroundColor:s},m={padding:"2px 4px",backgroundColor:s},b=null;return console.error("Error handled by React Router default ErrorBoundary:",c),b=A.createElement(A.Fragment,null,A.createElement("p",null,"💿 Hey developer 👋"),A.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",A.createElement("code",{style:m},"ErrorBoundary")," or"," ",A.createElement("code",{style:m},"errorElement")," prop on your route.")),A.createElement(A.Fragment,null,A.createElement("h2",null,"Unexpected Application Error!"),A.createElement("h3",{style:{fontStyle:"italic"}},f),o?A.createElement("pre",{style:h},o):null,b)}var Ey=A.createElement(Sy,null),Qh=class extends A.Component{constructor(c){super(c),this.state={location:c.location,revalidation:c.revalidation,error:c.error}}static getDerivedStateFromError(c){return{error:c}}static getDerivedStateFromProps(c,f){return f.location!==c.location||f.revalidation!=="idle"&&c.revalidation==="idle"?{error:c.error,location:c.location,revalidation:c.revalidation}:{error:c.error!==void 0?c.error:f.error,location:f.location,revalidation:c.revalidation||f.revalidation}}componentDidCatch(c,f){this.props.onError?this.props.onError(c,f):console.error("React Router caught the following error during render",c)}render(){let c=this.state.error;if(this.context&&typeof c=="object"&&c&&"digest"in c&&typeof c.digest=="string"){const o=gy(c.digest);o&&(c=o)}let f=c!==void 0?A.createElement(rl.Provider,{value:this.props.routeContext},A.createElement(Js.Provider,{value:c,children:this.props.component})):this.props.children;return this.context?A.createElement(zy,{error:c},f):f}};Qh.contextType=fy;var Gs=new WeakMap;function zy({children:c,error:f}){let{basename:o}=A.useContext(Oe);if(typeof f=="object"&&f&&"digest"in f&&typeof f.digest=="string"){let s=yy(f.digest);if(s){let h=Gs.get(f);if(h)throw h;let m=Hh(s.location,o);if(wh&&!Gs.get(f))if(m.isExternal||s.reloadDocument)window.location.href=m.absoluteURL||m.to;else{const b=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(m.to,{replace:s.replace}));throw Gs.set(f,b),b}return A.createElement("meta",{httpEquiv:"refresh",content:`0;url=${m.absoluteURL||m.to}`})}}return c}function _y({routeContext:c,match:f,children:o}){let s=A.useContext(Ya);return s&&s.static&&s.staticContext&&(f.route.errorElement||f.route.ErrorBoundary)&&(s.staticContext._deepestRenderedBoundaryId=f.route.id),A.createElement(rl.Provider,{value:c},o)}function Ty(c,f=[],o){let s=o?.state;if(c==null){if(!s)return null;if(s.errors)c=s.matches;else if(f.length===0&&!s.initialized&&s.matches.length>0)c=s.matches;else return null}let h=c,m=s?.errors;if(m!=null){let N=h.findIndex(T=>T.route.id&&m?.[T.route.id]!==void 0);Rt(N>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(m).join(",")}`),h=h.slice(0,Math.min(h.length,N+1))}let b=!1,j=-1;if(o&&s){b=s.renderFallback;for(let N=0;N=0?h=h.slice(0,j+1):h=[h[0]];break}}}}let S=o?.onError,g=s&&S?(N,T)=>{S(N,{location:s.location,params:s.matches?.[0]?.params??{},unstable_pattern:sy(s.matches),errorInfo:T})}:void 0;return h.reduceRight((N,T,w)=>{let X,Q=!1,Y=null,H=null;s&&(X=m&&T.route.id?m[T.route.id]:void 0,Y=T.route.errorElement||Ey,b&&(j<0&&w===0?(Vh("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),Q=!0,H=null):j===w&&(Q=!0,H=T.route.hydrateFallbackElement||null)));let K=f.concat(h.slice(0,w+1)),et=()=>{let $;return X?$=Y:Q?$=H:T.route.Component?$=A.createElement(T.route.Component,null):T.route.element?$=T.route.element:$=N,A.createElement(_y,{match:T,routeContext:{outlet:N,matches:K,isDataRoute:s!=null},children:$})};return s&&(T.route.ErrorBoundary||T.route.errorElement||w===0)?A.createElement(Qh,{location:s.location,revalidation:s.revalidation,component:Y,error:X,children:et(),routeContext:{outlet:null,matches:K,isDataRoute:!0},onError:g}):et()},null)}function $s(c){return`${c} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function Ay(c){let f=A.useContext(Ya);return Rt(f,$s(c)),f}function jy(c){let f=A.useContext(mi);return Rt(f,$s(c)),f}function Ry(c){let f=A.useContext(rl);return Rt(f,$s(c)),f}function Ws(c){let f=Ry(c),o=f.matches[f.matches.length-1];return Rt(o.route.id,`${c} can only be used on routes that contain a unique "id"`),o.route.id}function My(){return Ws("useRouteId")}function Oy(){let c=A.useContext(Js),f=jy("useRouteError"),o=Ws("useRouteError");return c!==void 0?c:f.errors?.[o]}function Ny(){let{router:c}=Ay("useNavigate"),f=Ws("useNavigate"),o=A.useRef(!1);return Gh(()=>{o.current=!0}),A.useCallback(async(h,m={})=>{Ge(o.current,Yh),o.current&&(typeof h=="number"?await c.navigate(h):await c.navigate(h,{fromRouteId:f,...m}))},[c,f])}var Sh={};function Vh(c,f,o){!f&&!Sh[c]&&(Sh[c]=!0,Ge(!1,o))}A.memo(Dy);function Dy({routes:c,future:f,state:o,isStatic:s,onError:h}){return kh(c,void 0,{state:o,isStatic:s,onError:h})}function J(c){Rt(!1,"A is only ever to be used as the child of element, never rendered directly. Please wrap your in a .")}function Cy({basename:c="/",children:f=null,location:o,navigationType:s="POP",navigator:h,static:m=!1,unstable_useTransitions:b}){Rt(!Yn(),"You cannot render a inside another . You should never have more than one in your app.");let j=c.replace(/^\/*/,"/"),S=A.useMemo(()=>({basename:j,navigator:h,static:m,unstable_useTransitions:b,future:{}}),[j,h,m,b]);typeof o=="string"&&(o=La(o));let{pathname:g="/",search:N="",hash:T="",state:w=null,key:X="default",unstable_mask:Q}=o,Y=A.useMemo(()=>{let H=sl(g,j);return H==null?null:{location:{pathname:H,search:N,hash:T,state:w,key:X,unstable_mask:Q},navigationType:s}},[j,g,N,T,w,X,s,Q]);return Ge(Y!=null,` is not able to match the URL "${g}${N}${T}" because it does not start with the basename, so the won't render anything.`),Y==null?null:A.createElement(Oe.Provider,{value:S},A.createElement(Ln.Provider,{children:f,value:Y}))}function Uy({children:c,location:f}){return xy(Xs(c),f)}function Xs(c,f=[]){let o=[];return A.Children.forEach(c,(s,h)=>{if(!A.isValidElement(s))return;let m=[...f,h];if(s.type===A.Fragment){o.push.apply(o,Xs(s.props.children,m));return}Rt(s.type===J,`[${typeof s.type=="string"?s.type:s.type.name}] is not a component. All component children of must be a or `),Rt(!s.props.index||!s.props.children,"An index route cannot have child routes.");let b={id:s.props.id||m.join("-"),caseSensitive:s.props.caseSensitive,element:s.props.element,Component:s.props.Component,index:s.props.index,path:s.props.path,middleware:s.props.middleware,loader:s.props.loader,action:s.props.action,hydrateFallbackElement:s.props.hydrateFallbackElement,HydrateFallback:s.props.HydrateFallback,errorElement:s.props.errorElement,ErrorBoundary:s.props.ErrorBoundary,hasErrorBoundary:s.props.hasErrorBoundary===!0||s.props.ErrorBoundary!=null||s.props.errorElement!=null,shouldRevalidate:s.props.shouldRevalidate,handle:s.props.handle,lazy:s.props.lazy};s.props.children&&(b.children=Xs(s.props.children,m)),o.push(b)}),o}var ri="get",fi="application/x-www-form-urlencoded";function yi(c){return typeof HTMLElement<"u"&&c instanceof HTMLElement}function wy(c){return yi(c)&&c.tagName.toLowerCase()==="button"}function Hy(c){return yi(c)&&c.tagName.toLowerCase()==="form"}function By(c){return yi(c)&&c.tagName.toLowerCase()==="input"}function qy(c){return!!(c.metaKey||c.altKey||c.ctrlKey||c.shiftKey)}function Ly(c,f){return c.button===0&&(!f||f==="_self")&&!qy(c)}var si=null;function Yy(){if(si===null)try{new FormData(document.createElement("form"),0),si=!1}catch{si=!0}return si}var Gy=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function ks(c){return c!=null&&!Gy.has(c)?(Ge(!1,`"${c}" is not a valid \`encType\` for \`
\`/\`\` and will default to "${fi}"`),null):c}function ky(c,f){let o,s,h,m,b;if(Hy(c)){let j=c.getAttribute("action");s=j?sl(j,f):null,o=c.getAttribute("method")||ri,h=ks(c.getAttribute("enctype"))||fi,m=new FormData(c)}else if(wy(c)||By(c)&&(c.type==="submit"||c.type==="image")){let j=c.form;if(j==null)throw new Error('Cannot submit a + + + + ); + } +} diff --git a/src/components/Layout/Header.tsx b/src/components/Layout/Header.tsx index 0c0e9cd..04f8843 100644 --- a/src/components/Layout/Header.tsx +++ b/src/components/Layout/Header.tsx @@ -1,19 +1,72 @@ -import { useState, useCallback } from 'react'; +import { useCallback, useState, type ComponentType } from 'react'; import { Network, Database, Gamepad2, Waypoints, GitBranch, Menu, X } from 'lucide-react'; import { Link, useLocation } from 'react-router-dom'; -const navItems = [ +interface NavItem { + path: string; + label: string; + icon: ComponentType<{ size?: number; className?: string }>; +} + +const navItems: NavItem[] = [ { path: '/algorithms', label: 'Algorithms', icon: Waypoints }, { path: '/data-structures', label: 'Data Structures', icon: Database }, { path: '/games', label: 'Games', icon: Gamepad2 }, { path: '/git', label: 'Git', icon: GitBranch }, ]; +const SECTION_PREFIXES = ['/games', '/algorithms', '/data-structures', '/git'] as const; + +/** Compute whether a nav item is "active" given the current pathname. */ +function isNavActive(itemPath: string, pathname: string): boolean { + // Legacy paths (`/sorting`, `/traversals/*`) live under the Algorithms section. + const legacyAlgorithmsActive = + itemPath === '/algorithms' && (pathname.startsWith('/traversals') || pathname === '/sorting'); + const isSectionItem = (SECTION_PREFIXES as readonly string[]).includes(itemPath); + return isSectionItem + ? pathname.startsWith(itemPath) || legacyAlgorithmsActive + : pathname === itemPath; +} + +interface NavLinkProps { + item: NavItem; + active: boolean; + onNavigate: () => void; + variant: 'desktop' | 'mobile'; +} + +function NavLink({ item, active, onNavigate, variant }: NavLinkProps) { + const { path, label, icon: Icon } = item; + const layoutClasses = + variant === 'desktop' + ? 'gap-2 px-3 py-2' + : 'gap-3 px-3 py-2.5'; + return ( + + + {label} + + ); +} + export default function Header() { const location = useLocation(); const [menuOpen, setMenuOpen] = useState(false); const toggleMenu = useCallback(() => setMenuOpen((p) => !p), []); + const closeMenu = useCallback(() => setMenuOpen(false), []); return (
@@ -28,36 +81,23 @@ export default function Header() { {/* Desktop nav */} {/* Mobile hamburger */} @@ -66,29 +106,15 @@ export default function Header() { {/* Mobile menu dropdown */} {menuOpen && ( )}
diff --git a/src/components/RouteFallback.tsx b/src/components/RouteFallback.tsx new file mode 100644 index 0000000..8ec9da8 --- /dev/null +++ b/src/components/RouteFallback.tsx @@ -0,0 +1,16 @@ +/** + * Suspense fallback shown while a lazy-loaded route chunk is being fetched. + * Deliberately understated — most chunks load in well under a frame on + * fast networks, so a heavy spinner would flash distractingly. + */ +export default function RouteFallback() { + return ( +
+
+ + + +
+
+ ); +} diff --git a/src/features/algorithms/AlgorithmPlaygroundPage.tsx b/src/features/algorithms/AlgorithmPlaygroundPage.tsx index d121f90..33c2be5 100644 --- a/src/features/algorithms/AlgorithmPlaygroundPage.tsx +++ b/src/features/algorithms/AlgorithmPlaygroundPage.tsx @@ -1,6 +1,7 @@ import { useState } from 'react'; import { ChevronLeft, ChevronRight, Play, RotateCcw, Shuffle, Volume2, VolumeX } from 'lucide-react'; import { useAlgorithmSound } from './hooks/useAlgorithmSound'; +import AlgorithmCodePanel from './shared/AlgorithmCodePanel'; export type AlgorithmDemo = | 'binary-search' @@ -28,15 +29,27 @@ interface DemoStep { path?: number[]; visited?: number[]; meta?: string[]; + /** 0-based index into the demo's `pseudocode` array (line being executed). */ + codeLine?: number; } -const DEMO_INFO: Record = { +const DEMO_INFO: Record = { 'binary-search': { title: 'Binary Search', subtitle: 'Search a sorted array in logarithmic time', inputLabel: 'Sorted numbers; target', defaultInput: '2,5,8,12,16,23,38,56,72;23', helper: 'Format: sorted comma-separated numbers; target', + pseudocode: [ + 'function binarySearch(arr, target):', + ' low = 0; high = arr.length - 1', + ' while low <= high:', + ' mid = (low + high) / 2', + ' if arr[mid] == target: return mid', + ' if arr[mid] < target: low = mid + 1', + ' else: high = mid - 1', + ' return -1 // not found', + ], }, 'ternary-search': { title: 'Ternary Search', @@ -44,6 +57,19 @@ const DEMO_INFO: Record arr[mid2]: low = mid2 + 1', + ' else: low = mid1 + 1; high = mid2 - 1', + ' return -1 // not found', + ], }, 'dutch-national-flag': { title: 'Sort Colors', @@ -51,6 +77,18 @@ const DEMO_INFO: Record to', + ' hanoi(n - 1, aux, to, from) // move them onto target', + ], }, 'rat-maze': { title: 'Rat in a Maze', @@ -86,6 +159,18 @@ const DEMO_INFO: Record(() => buildSteps(demo, info.defaultInput)); const [stepIndex, setStepIndex] = useState(0); - const [animationDelay, setAnimationDelay] = useState(650); + const [animationDelay, setAnimationDelay] = useState(800); const { soundEnabled, toggleSound, playEvent } = useAlgorithmSound(); const currentStep = steps[stepIndex] ?? steps[0]; const progress = steps.length > 0 ? ((stepIndex + 1) / steps.length) * 100 : 0; @@ -147,6 +244,7 @@ export default function AlgorithmPlaygroundPage({ demo }: { demo: AlgorithmDemo

{info.subtitle}

+