diff --git a/.assets/core29-endorsed.png b/.assets/core29-endorsed.png
deleted file mode 100644
index bea14e9..0000000
Binary files a/.assets/core29-endorsed.png and /dev/null differ
diff --git a/.assets/final-logo.svg b/.assets/final-logo.svg
deleted file mode 100644
index 3fad67d..0000000
--- a/.assets/final-logo.svg
+++ /dev/null
@@ -1,291 +0,0 @@
-
diff --git a/.assets/games.png b/.assets/games.png
new file mode 100644
index 0000000..6d581fc
Binary files /dev/null and b/.assets/games.png differ
diff --git a/.assets/meme.png b/.assets/meme.png
new file mode 100644
index 0000000..45accbd
Binary files /dev/null and b/.assets/meme.png differ
diff --git a/.assets/paths.png b/.assets/paths.png
new file mode 100644
index 0000000..4727f44
Binary files /dev/null and b/.assets/paths.png differ
diff --git a/.assets/pongBossMess.png b/.assets/pongBossMess.png
new file mode 100644
index 0000000..a007af3
Binary files /dev/null and b/.assets/pongBossMess.png differ
diff --git a/.assets/salus.png b/.assets/salus.png
deleted file mode 100644
index e31f1e1..0000000
Binary files a/.assets/salus.png and /dev/null differ
diff --git a/.assets/socet.png b/.assets/socet.png
deleted file mode 100644
index a5924bb..0000000
Binary files a/.assets/socet.png and /dev/null differ
diff --git a/.assets/startScreen.png b/.assets/startScreen.png
new file mode 100644
index 0000000..5639be5
Binary files /dev/null and b/.assets/startScreen.png differ
diff --git a/.assets/sword.png b/.assets/sword.png
deleted file mode 100644
index 9b87057..0000000
Binary files a/.assets/sword.png and /dev/null differ
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..4d2d239
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,37 @@
+# Dependencies
+node_modules
+
+# Build output
+dist
+build
+coverage
+
+# Logs
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+bun.lockb
+
+# Environment files
+.env
+.env.*
+!.env.example
+
+# Git and editor metadata
+.assets
+.git
+.gitignore
+.gitattributes
+.vscode
+.idea
+.vite
+
+# Docker metadata not needed in context
+docker-compose.yml
+docker-compose.local.yml
+
+# OS files
+.DS_Store
+Thumbs.db
+.pdf
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..f28239b
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,4 @@
+root = true
+
+[*]
+charset = utf-8
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..8ad74f7
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,2 @@
+# Normalize EOL for all files that Git considers text files.
+* text=auto eol=lf
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3217a55
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,25 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+.vite/
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 0000000..ad4715b
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,24 @@
+# Dependencies
+node_modules/
+
+# Build output
+dist/
+build/
+coverage/
+
+# Logs
+*.log
+
+# Environment and generated lock files
+.env
+.env.*
+bun.lockb
+
+# OS/editor/project metadata
+.DS_Store
+.vscode/
+.idea/
+.vite/
+
+# Static/generated assets
+public/
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..3d8aae8
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,20 @@
+FROM oven/bun:alpine AS base
+WORKDIR /usr/src/app
+
+FROM base AS install
+RUN mkdir -p /temp/dev
+COPY package.json bun.lock /temp/dev/
+RUN cd /temp/dev && bun install --frozen-lockfile
+
+FROM base AS prerelease
+COPY --from=install /temp/dev/node_modules node_modules
+COPY . .
+
+ENV NODE_ENV=production
+RUN bun run build
+
+FROM cgr.dev/chainguard/nginx:latest AS release
+COPY --from=prerelease /usr/src/app/dist /usr/share/nginx/html
+COPY nginx-main.conf /etc/nginx/nginx.conf
+COPY nginx.conf /etc/nginx/conf.d/default.conf
+EXPOSE 80
diff --git a/LIAR... CHEATER... FIRED..pptx b/LIAR... CHEATER... FIRED..pptx
new file mode 100644
index 0000000..6442da5
Binary files /dev/null and b/LIAR... CHEATER... FIRED..pptx differ
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..3c36dd5
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,41 @@
+# Makefile for Docker Compose
+
+# Variables
+docker_compose_file = docker-compose.yml
+docker_compose_file_dev = docker-compose.local.yml
+project_name = liar
+
+# Targets
+.PHONY: up down build logs serve shell local-serve clean format
+
+up:
+ docker compose -f $(docker_compose_file) down
+ docker compose -f $(docker_compose_file) up -d
+
+down:
+ docker compose -f $(docker_compose_file) down
+
+build:
+ docker compose -f $(docker_compose_file) build
+
+logs:
+ docker compose -f $(docker_compose_file) logs -f
+
+serve:
+ docker compose -f $(docker_compose_file) down
+ docker compose -f $(docker_compose_file) up -d --build
+ make clean
+
+local-serve:
+ docker compose -f $(docker_compose_file_dev) down
+ docker compose -f $(docker_compose_file_dev) up --build
+
+shell:
+ docker exec -it $$(docker compose -f $(docker_compose_file) ps -q $(project_name)) sh || bash
+
+clean:
+ docker image prune -f
+ docker volume prune -f
+
+format:
+ prettier --write . --ignore-path .prettierignore
diff --git a/README.md b/README.md
index 8a1b9ef..db5886d 100644
--- a/README.md
+++ b/README.md
@@ -1,42 +1,75 @@
-
+# π₯ Liar, Cheater, Fired: The Corporate Escape
-# Welcome to RGU Hack 26!
-### This is the repo for your team
-### At the end of the hack make sure to put all of your code into here for judging!
-If you have any issues come to the help desk!
+> **"The ultimate race to the bottom. Can you get fired before the 5:00 PM whistle?"**
+
+
+
+## πΌ The Concept
+
+As a team of **"Wonderful Magical Interns"** by day, we decided to spend RGUHack 26 exploring our dark mirrors.
+
+In **Liar, Cheater, Fired**, the traditional "Escape Room" logic is flipped on its head. You aren't escaping a room; you are escaping a **career**. You play as a catastrophically bad employee. Your goal? **Get fired.** The ultimate "Fail State"? **A Promotion.** If you accidentally show competence, youβll be locked in a corner office with a 60-hour work week. You must sabotage your way to freedom!
+
+---
+
+## π§© The "Work" (Puzzles)
+
+To meet the **Sword Group** challenge requirements, weβve built a suite of anti-productivity puzzles that test your ability to do absolutely nothing:
+
+- **π€ Corporate Yap Wordle:** Decipher the most annoying corporate buzzwords. Guess "Scope" or "Scrum" and you risk looking like a high-performer. Guess the "slacker" words to tank the meeting.
+- **π§± Jira Ticket Tetris:** The backlog is crazy! In sprint planning battle, your goal is to avoid being important. Every line of the backlog is being assigned to an individual, and if you aren't careful, you'll end up with a big project. Stay "Dead Weight" and keep your board clear to dodge the workload.
+- **π Marty Pong & Slacker Pacman:** Classic time-wasters dodging your Boss's Microsoft Teams pings. One hit and youβre stuck in a "Quick Sync" that lasts three hours. Then in Pacman Navigate the cubicle maze while running from unread emails.Stay alert, stay silent, stay unemployed!
+
+
+
+---
+
+## πΆ The Boss Baby (The Antagonist)
+
+Meet your manager: **The Boss Baby**. He is micromanaging your every move.
+
+- **The Goal:** Aggravate him until he hands you your P45.
+- **The Risk:** If you solve his "Training Challenges" too efficiently, he might think you're "Management Material." Avoid the promotion at all costs!
+
+---
+
+## π οΈ The "Unprofessional" Stack
+
+We used a professional stack to build a very "professional" experience:
+
+- **Framework:** React 19 + Vite
+- **Styling:** Tailwind CSS and Lucide React for that sterile, soul-crushing office aesthetic.
---
-# The Challenges
-The challenges for this year that have been chosen by our sponsors are below, pick one and get started using any languages or frameworks you like!
-Challenges sponsored by:
+## ποΈ The "Hacker" Win
+
+The biggest challenge was creating a game where **Winning = Losing** and **Losing = Winning**. We had to decouple traditional game rewards (points/levels) and replace them with disciplinary write-ups and HR complaints.
-
-
-
-
-
-
-
-
-
-
-
-
+
+---
+
+## π₯ The "Magical Interns" (The Team)
-Click on a sponsor or checkout the [Challenges Folder](challenges/)
+We are a group of placement students currently being "wonderful" in the real world, but "terrible" in this repo:
-#### [Nao Documentation](http://doc.aldebaran.com/2-1/nao/nao-connecting.html#nao-connecting)
-#### [Nao Repo from SoCET](https://github.com/RGU-Computing/pepper)
+- **[Arman Shaikh]** - Chief Sabotage Officer
+- **[Charis Drain]** - Head of Corporate Yap
+- **[Himani Patney]** - Jira Ticket Architect
+- **[Vidhi Jalan]** - Boss Baby Handler
+- **[Lemar Tokham]** - Professional Email Ignorer
------
+---
-
+### π How to Play
+Navigate your wonderful self to: https://liar.armandev.co.uk/
-
-#### Join our discord server [https://discord.gg/MuntB88f](https://discord.gg/MuntB88f) and tag us on LinkedIn [#rguhack](https://www.linkedin.com/search/results/all/?keywords=%23rguhack)
+### Run it locally
+1. Install [bun](https://www.bun.com)
+2. Run `bun install`
+3. Run `bun dev`
-# Good Luck! π
+
diff --git a/bun.lock b/bun.lock
new file mode 100644
index 0000000..e7399b7
--- /dev/null
+++ b/bun.lock
@@ -0,0 +1,1129 @@
+{
+ "lockfileVersion": 1,
+ "configVersion": 1,
+ "workspaces": {
+ "": {
+ "name": "vite_react_shadcn_ts",
+ "dependencies": {
+ "@hookform/resolvers": "^5.2.2",
+ "@radix-ui/react-accordion": "^1.2.12",
+ "@radix-ui/react-alert-dialog": "^1.1.15",
+ "@radix-ui/react-aspect-ratio": "^1.1.8",
+ "@radix-ui/react-avatar": "^1.1.11",
+ "@radix-ui/react-checkbox": "^1.3.3",
+ "@radix-ui/react-collapsible": "^1.1.12",
+ "@radix-ui/react-context-menu": "^2.2.16",
+ "@radix-ui/react-dialog": "^1.1.15",
+ "@radix-ui/react-dropdown-menu": "^2.1.16",
+ "@radix-ui/react-hover-card": "^1.1.15",
+ "@radix-ui/react-label": "^2.1.8",
+ "@radix-ui/react-menubar": "^1.1.16",
+ "@radix-ui/react-navigation-menu": "^1.2.14",
+ "@radix-ui/react-popover": "^1.1.15",
+ "@radix-ui/react-progress": "^1.1.8",
+ "@radix-ui/react-radio-group": "^1.3.8",
+ "@radix-ui/react-scroll-area": "^1.2.10",
+ "@radix-ui/react-select": "^2.2.6",
+ "@radix-ui/react-separator": "^1.1.8",
+ "@radix-ui/react-slider": "^1.3.6",
+ "@radix-ui/react-slot": "^1.2.4",
+ "@radix-ui/react-switch": "^1.2.6",
+ "@radix-ui/react-tabs": "^1.1.13",
+ "@radix-ui/react-toast": "^1.2.15",
+ "@radix-ui/react-toggle": "^1.1.10",
+ "@radix-ui/react-toggle-group": "^1.1.11",
+ "@radix-ui/react-tooltip": "^1.2.8",
+ "@tanstack/react-query": "^5.90.21",
+ "browserslist": "^4.28.1",
+ "caniuse-lite": "^1.0.30001775",
+ "class-variance-authority": "^0.7.1",
+ "clsx": "^2.1.1",
+ "cmdk": "^1.1.1",
+ "date-fns": "^4.1.0",
+ "embla-carousel-react": "^8.6.0",
+ "input-otp": "^1.4.2",
+ "lucide-react": "^0.575.0",
+ "next-themes": "^0.4.6",
+ "react": "^19.2.4",
+ "react-day-picker": "^9.14.0",
+ "react-dom": "^19.2.4",
+ "react-hook-form": "^7.71.2",
+ "react-resizable-panels": "^4.7.0",
+ "react-router-dom": "^7.13.1",
+ "recharts": "^3.7.0",
+ "sonner": "^2.0.7",
+ "tailwind-merge": "^3.5.0",
+ "tailwindcss-animate": "^1.0.7",
+ "vaul": "^1.1.2",
+ "zod": "^4.3.6",
+ },
+ "devDependencies": {
+ "@eslint/js": "^10.0.1",
+ "@tailwindcss/postcss": "^4.2.1",
+ "@tailwindcss/typography": "^0.5.19",
+ "@testing-library/jest-dom": "^6.9.1",
+ "@testing-library/react": "^16.3.2",
+ "@types/node": "^25.3.3",
+ "@types/react": "^19.2.14",
+ "@types/react-dom": "^19.2.3",
+ "@vitejs/plugin-react-swc": "^4.2.3",
+ "autoprefixer": "^10.4.27",
+ "eslint": "^10.0.2",
+ "eslint-plugin-react-hooks": "^7.0.1",
+ "eslint-plugin-react-refresh": "^0.5.2",
+ "globals": "^17.4.0",
+ "jsdom": "^28.1.0",
+ "postcss": "^8.5.6",
+ "tailwindcss": "^4.2.1",
+ "typescript": "^5.9.3",
+ "typescript-eslint": "^8.56.1",
+ "vite": "^7.3.1",
+ "vite-plugin-compression": "^0.5.1",
+ "vitest": "^4.0.18",
+ },
+ },
+ },
+ "packages": {
+ "@acemir/cssom": ["@acemir/cssom@0.9.31", "", {}, "sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA=="],
+
+ "@adobe/css-tools": ["@adobe/css-tools@4.4.4", "", {}, "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg=="],
+
+ "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="],
+
+ "@asamuzakjp/css-color": ["@asamuzakjp/css-color@5.0.1", "", { "dependencies": { "@csstools/css-calc": "^3.1.1", "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "lru-cache": "^11.2.6" } }, "sha512-2SZFvqMyvboVV1d15lMf7XiI3m7SDqXUuKaTymJYLN6dSGadqp+fVojqJlVoMlbZnlTmu3S0TLwLTJpvBMO1Aw=="],
+
+ "@asamuzakjp/dom-selector": ["@asamuzakjp/dom-selector@6.8.1", "", { "dependencies": { "@asamuzakjp/nwsapi": "^2.3.9", "bidi-js": "^1.0.3", "css-tree": "^3.1.0", "is-potential-custom-element-name": "^1.0.1", "lru-cache": "^11.2.6" } }, "sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ=="],
+
+ "@asamuzakjp/nwsapi": ["@asamuzakjp/nwsapi@2.3.9", "", {}, "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q=="],
+
+ "@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="],
+
+ "@babel/compat-data": ["@babel/compat-data@7.29.0", "", {}, "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg=="],
+
+ "@babel/core": ["@babel/core@7.29.0", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-module-transforms": "^7.28.6", "@babel/helpers": "^7.28.6", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/traverse": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA=="],
+
+ "@babel/generator": ["@babel/generator@7.29.1", "", { "dependencies": { "@babel/parser": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw=="],
+
+ "@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.28.6", "", { "dependencies": { "@babel/compat-data": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA=="],
+
+ "@babel/helper-globals": ["@babel/helper-globals@7.28.0", "", {}, "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw=="],
+
+ "@babel/helper-module-imports": ["@babel/helper-module-imports@7.28.6", "", { "dependencies": { "@babel/traverse": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw=="],
+
+ "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.6", "", { "dependencies": { "@babel/helper-module-imports": "^7.28.6", "@babel/helper-validator-identifier": "^7.28.5", "@babel/traverse": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA=="],
+
+ "@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="],
+
+ "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="],
+
+ "@babel/helper-validator-option": ["@babel/helper-validator-option@7.27.1", "", {}, "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg=="],
+
+ "@babel/helpers": ["@babel/helpers@7.28.6", "", { "dependencies": { "@babel/template": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw=="],
+
+ "@babel/parser": ["@babel/parser@7.29.0", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww=="],
+
+ "@babel/runtime": ["@babel/runtime@7.28.2", "", {}, "sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA=="],
+
+ "@babel/template": ["@babel/template@7.28.6", "", { "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/parser": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ=="],
+
+ "@babel/traverse": ["@babel/traverse@7.29.0", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/types": "^7.29.0", "debug": "^4.3.1" } }, "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA=="],
+
+ "@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="],
+
+ "@bramus/specificity": ["@bramus/specificity@2.4.2", "", { "dependencies": { "css-tree": "^3.0.0" }, "bin": { "specificity": "bin/cli.js" } }, "sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw=="],
+
+ "@csstools/color-helpers": ["@csstools/color-helpers@6.0.2", "", {}, "sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q=="],
+
+ "@csstools/css-calc": ["@csstools/css-calc@3.1.1", "", { "peerDependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" } }, "sha512-HJ26Z/vmsZQqs/o3a6bgKslXGFAungXGbinULZO3eMsOyNJHeBBZfup5FiZInOghgoM4Hwnmw+OgbJCNg1wwUQ=="],
+
+ "@csstools/css-color-parser": ["@csstools/css-color-parser@4.0.2", "", { "dependencies": { "@csstools/color-helpers": "^6.0.2", "@csstools/css-calc": "^3.1.1" }, "peerDependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" } }, "sha512-0GEfbBLmTFf0dJlpsNU7zwxRIH0/BGEMuXLTCvFYxuL1tNhqzTbtnFICyJLTNK4a+RechKP75e7w42ClXSnJQw=="],
+
+ "@csstools/css-parser-algorithms": ["@csstools/css-parser-algorithms@4.0.0", "", { "peerDependencies": { "@csstools/css-tokenizer": "^4.0.0" } }, "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w=="],
+
+ "@csstools/css-syntax-patches-for-csstree": ["@csstools/css-syntax-patches-for-csstree@1.0.28", "", {}, "sha512-1NRf1CUBjnr3K7hu8BLxjQrKCxEe8FP/xmPTenAxCRZWVLbmGotkFvG9mfNpjA6k7Bw1bw4BilZq9cu19RA5pg=="],
+
+ "@csstools/css-tokenizer": ["@csstools/css-tokenizer@4.0.0", "", {}, "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA=="],
+
+ "@date-fns/tz": ["@date-fns/tz@1.4.1", "", {}, "sha512-P5LUNhtbj6YfI3iJjw5EL9eUAG6OitD0W3fWQcpQjDRc/QIsL0tRNuO1PcDvPccWL1fSTXXdE1ds+l95DV/OFA=="],
+
+ "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg=="],
+
+ "@esbuild/android-arm": ["@esbuild/android-arm@0.27.3", "", { "os": "android", "cpu": "arm" }, "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA=="],
+
+ "@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.3", "", { "os": "android", "cpu": "arm64" }, "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg=="],
+
+ "@esbuild/android-x64": ["@esbuild/android-x64@0.27.3", "", { "os": "android", "cpu": "x64" }, "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ=="],
+
+ "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg=="],
+
+ "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg=="],
+
+ "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.3", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w=="],
+
+ "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.3", "", { "os": "freebsd", "cpu": "x64" }, "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA=="],
+
+ "@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.3", "", { "os": "linux", "cpu": "arm" }, "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw=="],
+
+ "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg=="],
+
+ "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.3", "", { "os": "linux", "cpu": "ia32" }, "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg=="],
+
+ "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA=="],
+
+ "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw=="],
+
+ "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA=="],
+
+ "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ=="],
+
+ "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw=="],
+
+ "@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.3", "", { "os": "linux", "cpu": "x64" }, "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA=="],
+
+ "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.3", "", { "os": "none", "cpu": "arm64" }, "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA=="],
+
+ "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.3", "", { "os": "none", "cpu": "x64" }, "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA=="],
+
+ "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.3", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw=="],
+
+ "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.3", "", { "os": "openbsd", "cpu": "x64" }, "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ=="],
+
+ "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.3", "", { "os": "none", "cpu": "arm64" }, "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g=="],
+
+ "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.3", "", { "os": "sunos", "cpu": "x64" }, "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA=="],
+
+ "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA=="],
+
+ "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.3", "", { "os": "win32", "cpu": "ia32" }, "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q=="],
+
+ "@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.3", "", { "os": "win32", "cpu": "x64" }, "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA=="],
+
+ "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ=="],
+
+ "@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.2", "", {}, "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew=="],
+
+ "@eslint/config-array": ["@eslint/config-array@0.23.2", "", { "dependencies": { "@eslint/object-schema": "^3.0.2", "debug": "^4.3.1", "minimatch": "^10.2.1" } }, "sha512-YF+fE6LV4v5MGWRGj7G404/OZzGNepVF8fxk7jqmqo3lrza7a0uUcDnROGRBG1WFC1omYUS/Wp1f42i0M+3Q3A=="],
+
+ "@eslint/config-helpers": ["@eslint/config-helpers@0.5.2", "", { "dependencies": { "@eslint/core": "^1.1.0" } }, "sha512-a5MxrdDXEvqnIq+LisyCX6tQMPF/dSJpCfBgBauY+pNZ28yCtSsTvyTYrMhaI+LK26bVyCJfJkT0u8KIj2i1dQ=="],
+
+ "@eslint/core": ["@eslint/core@1.1.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-/nr9K9wkr3P1EzFTdFdMoLuo1PmIxjmwvPozwoSodjNBdefGujXQUF93u1DDZpEaTuDvMsIQddsd35BwtrW9Xw=="],
+
+ "@eslint/js": ["@eslint/js@10.0.1", "", { "peerDependencies": { "eslint": "^10.0.0" }, "optionalPeers": ["eslint"] }, "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA=="],
+
+ "@eslint/object-schema": ["@eslint/object-schema@3.0.2", "", {}, "sha512-HOy56KJt48Bx8KmJ+XGQNSUMT/6dZee/M54XyUyuvTvPXJmsERRvBchsUVx1UMe1WwIH49XLAczNC7V2INsuUw=="],
+
+ "@eslint/plugin-kit": ["@eslint/plugin-kit@0.6.0", "", { "dependencies": { "@eslint/core": "^1.1.0", "levn": "^0.4.1" } }, "sha512-bIZEUzOI1jkhviX2cp5vNyXQc6olzb2ohewQubuYlMXZ2Q/XjBO0x0XhGPvc9fjSIiUN0vw+0hq53BJ4eQSJKQ=="],
+
+ "@exodus/bytes": ["@exodus/bytes@1.14.1", "", { "peerDependencies": { "@noble/hashes": "^1.8.0 || ^2.0.0" }, "optionalPeers": ["@noble/hashes"] }, "sha512-OhkBFWI6GcRMUroChZiopRiSp2iAMvEBK47NhJooDqz1RERO4QuZIZnjP63TXX8GAiLABkYmX+fuQsdJ1dd2QQ=="],
+
+ "@floating-ui/core": ["@floating-ui/core@1.7.2", "", { "dependencies": { "@floating-ui/utils": "^0.2.10" } }, "sha512-wNB5ooIKHQc+Kui96jE/n69rHFWAVoxn5CAzL1Xdd8FG03cgY3MLO+GF9U3W737fYDSgPWA6MReKhBQBop6Pcw=="],
+
+ "@floating-ui/dom": ["@floating-ui/dom@1.7.2", "", { "dependencies": { "@floating-ui/core": "^1.7.2", "@floating-ui/utils": "^0.2.10" } }, "sha512-7cfaOQuCS27HD7DX+6ib2OrnW+b4ZBwDNnCcT0uTyidcmyWb03FnQqJybDBoCnpdxwBSfA94UAYlRCt7mV+TbA=="],
+
+ "@floating-ui/react-dom": ["@floating-ui/react-dom@2.1.4", "", { "dependencies": { "@floating-ui/dom": "^1.7.2" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-JbbpPhp38UmXDDAu60RJmbeme37Jbgsm7NrHGgzYYFKmblzRUh6Pa641dII6LsjwF4XlScDrde2UAzDo/b9KPw=="],
+
+ "@floating-ui/utils": ["@floating-ui/utils@0.2.10", "", {}, "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="],
+
+ "@hookform/resolvers": ["@hookform/resolvers@5.2.2", "", { "dependencies": { "@standard-schema/utils": "^0.3.0" }, "peerDependencies": { "react-hook-form": "^7.55.0" } }, "sha512-A/IxlMLShx3KjV/HeTcTfaMxdwy690+L/ZADoeaTltLx+CVuzkeVIPuybK3jrRfw7YZnmdKsVVHAlEPIAEUNlA=="],
+
+ "@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
+
+ "@humanfs/node": ["@humanfs/node@0.16.6", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.3.0" } }, "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw=="],
+
+ "@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="],
+
+ "@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="],
+
+ "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.5", "", { "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg=="],
+
+ "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="],
+
+ "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
+
+ "@jridgewell/set-array": ["@jridgewell/set-array@1.2.1", "", {}, "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A=="],
+
+ "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
+
+ "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="],
+
+ "@radix-ui/number": ["@radix-ui/number@1.1.1", "", {}, "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g=="],
+
+ "@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="],
+
+ "@radix-ui/react-accordion": ["@radix-ui/react-accordion@1.2.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collapsible": "1.1.12", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA=="],
+
+ "@radix-ui/react-alert-dialog": ["@radix-ui/react-alert-dialog@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dialog": "1.1.15", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw=="],
+
+ "@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w=="],
+
+ "@radix-ui/react-aspect-ratio": ["@radix-ui/react-aspect-ratio@1.1.8", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-5nZrJTF7gH+e0nZS7/QxFz6tJV4VimhQb1avEgtsJxvvIp5JilL+c58HICsKzPxghdwaDt48hEfPM1au4zGy+w=="],
+
+ "@radix-ui/react-avatar": ["@radix-ui/react-avatar@1.1.11", "", { "dependencies": { "@radix-ui/react-context": "1.1.3", "@radix-ui/react-primitive": "2.1.4", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-is-hydrated": "0.1.0", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-0Qk603AHGV28BOBO34p7IgD5m+V5Sg/YovfayABkoDDBM5d3NCx0Mp4gGrjzLGes1jV5eNOE1r3itqOR33VC6Q=="],
+
+ "@radix-ui/react-checkbox": ["@radix-ui/react-checkbox@1.3.3", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw=="],
+
+ "@radix-ui/react-collapsible": ["@radix-ui/react-collapsible@1.1.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA=="],
+
+ "@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw=="],
+
+ "@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg=="],
+
+ "@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="],
+
+ "@radix-ui/react-context-menu": ["@radix-ui/react-context-menu@2.2.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-menu": "2.1.16", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-O8morBEW+HsVG28gYDZPTrT9UUovQUlJue5YO836tiTJhuIWBm/zQHc7j388sHWtdH/xUZurK9olD2+pcqx5ww=="],
+
+ "@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw=="],
+
+ "@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw=="],
+
+ "@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-escape-keydown": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg=="],
+
+ "@radix-ui/react-dropdown-menu": ["@radix-ui/react-dropdown-menu@2.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-menu": "2.1.16", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw=="],
+
+ "@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw=="],
+
+ "@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw=="],
+
+ "@radix-ui/react-hover-card": ["@radix-ui/react-hover-card@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-qgTkjNT1CfKMoP0rcasmlH2r1DAiYicWsDsufxl940sT2wHNEWWv6FMWIQXWhVdmC1d/HYfbhQx60KYyAtKxjg=="],
+
+ "@radix-ui/react-id": ["@radix-ui/react-id@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg=="],
+
+ "@radix-ui/react-label": ["@radix-ui/react-label@2.1.8", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-FmXs37I6hSBVDlO4y764TNz1rLgKwjJMQ0EGte6F3Cb3f4bIuHB/iLa/8I9VKkmOy+gNHq8rql3j686ACVV21A=="],
+
+ "@radix-ui/react-menu": ["@radix-ui/react-menu@2.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-callback-ref": "1.1.1", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg=="],
+
+ "@radix-ui/react-menubar": ["@radix-ui/react-menubar@1.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-menu": "2.1.16", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-EB1FktTz5xRRi2Er974AUQZWg2yVBb1yjip38/lgwtCVRd3a+maUoGHN/xs9Yv8SY8QwbSEb+YrxGadVWbEutA=="],
+
+ "@radix-ui/react-navigation-menu": ["@radix-ui/react-navigation-menu@1.2.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w=="],
+
+ "@radix-ui/react-popover": ["@radix-ui/react-popover@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA=="],
+
+ "@radix-ui/react-popper": ["@radix-ui/react-popper@1.2.8", "", { "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-rect": "1.1.1", "@radix-ui/react-use-size": "1.1.1", "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw=="],
+
+ "@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.9", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ=="],
+
+ "@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.5", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ=="],
+
+ "@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
+
+ "@radix-ui/react-progress": ["@radix-ui/react-progress@1.1.8", "", { "dependencies": { "@radix-ui/react-context": "1.1.3", "@radix-ui/react-primitive": "2.1.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-+gISHcSPUJ7ktBy9RnTqbdKW78bcGke3t6taawyZ71pio1JewwGSJizycs7rLhGTvMJYCQB1DBK4KQsxs7U8dA=="],
+
+ "@radix-ui/react-radio-group": ["@radix-ui/react-radio-group@1.3.8", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ=="],
+
+ "@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA=="],
+
+ "@radix-ui/react-scroll-area": ["@radix-ui/react-scroll-area@1.2.10", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A=="],
+
+ "@radix-ui/react-select": ["@radix-ui/react-select@2.2.6", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-visually-hidden": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ=="],
+
+ "@radix-ui/react-separator": ["@radix-ui/react-separator@1.1.8", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-sDvqVY4itsKwwSMEe0jtKgfTh+72Sy3gPmQpjqcQneqQ4PFmr/1I0YA+2/puilhggCe2gJcx5EBAYFkWkdpa5g=="],
+
+ "@radix-ui/react-slider": ["@radix-ui/react-slider@1.3.6", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw=="],
+
+ "@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.4", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA=="],
+
+ "@radix-ui/react-switch": ["@radix-ui/react-switch@1.2.6", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ=="],
+
+ "@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A=="],
+
+ "@radix-ui/react-toast": ["@radix-ui/react-toast@1.2.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-3OSz3TacUWy4WtOXV38DggwxoqJK4+eDkNMl5Z/MJZaoUPaP4/9lf81xXMe1I2ReTAptverZUpbPY4wWwWyL5g=="],
+
+ "@radix-ui/react-toggle": ["@radix-ui/react-toggle@1.1.10", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ=="],
+
+ "@radix-ui/react-toggle-group": ["@radix-ui/react-toggle-group@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-toggle": "1.1.10", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q=="],
+
+ "@radix-ui/react-tooltip": ["@radix-ui/react-tooltip@1.2.8", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg=="],
+
+ "@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="],
+
+ "@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.2", "", { "dependencies": { "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg=="],
+
+ "@radix-ui/react-use-effect-event": ["@radix-ui/react-use-effect-event@0.0.2", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA=="],
+
+ "@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.1", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g=="],
+
+ "@radix-ui/react-use-is-hydrated": ["@radix-ui/react-use-is-hydrated@0.1.0", "", { "dependencies": { "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA=="],
+
+ "@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ=="],
+
+ "@radix-ui/react-use-previous": ["@radix-ui/react-use-previous@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ=="],
+
+ "@radix-ui/react-use-rect": ["@radix-ui/react-use-rect@1.1.1", "", { "dependencies": { "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w=="],
+
+ "@radix-ui/react-use-size": ["@radix-ui/react-use-size@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ=="],
+
+ "@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.2.3", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug=="],
+
+ "@radix-ui/rect": ["@radix-ui/rect@1.1.1", "", {}, "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw=="],
+
+ "@reduxjs/toolkit": ["@reduxjs/toolkit@2.11.2", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "@standard-schema/utils": "^0.3.0", "immer": "^11.0.0", "redux": "^5.0.1", "redux-thunk": "^3.1.0", "reselect": "^5.1.0" }, "peerDependencies": { "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" }, "optionalPeers": ["react", "react-redux"] }, "sha512-Kd6kAHTA6/nUpp8mySPqj3en3dm0tdMIgbttnQ1xFMVpufoj+ADi8pXLBsd4xzTRHQa7t/Jv8W5UnCuW4kuWMQ=="],
+
+ "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.2", "", {}, "sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw=="],
+
+ "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.59.0", "", { "os": "android", "cpu": "arm" }, "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg=="],
+
+ "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.59.0", "", { "os": "android", "cpu": "arm64" }, "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q=="],
+
+ "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.59.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg=="],
+
+ "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.59.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w=="],
+
+ "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.59.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA=="],
+
+ "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.59.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg=="],
+
+ "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.59.0", "", { "os": "linux", "cpu": "arm" }, "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw=="],
+
+ "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.59.0", "", { "os": "linux", "cpu": "arm" }, "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA=="],
+
+ "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.59.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA=="],
+
+ "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.59.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA=="],
+
+ "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg=="],
+
+ "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q=="],
+
+ "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.59.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA=="],
+
+ "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.59.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA=="],
+
+ "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg=="],
+
+ "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg=="],
+
+ "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.59.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w=="],
+
+ "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.59.0", "", { "os": "linux", "cpu": "x64" }, "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg=="],
+
+ "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.59.0", "", { "os": "linux", "cpu": "x64" }, "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg=="],
+
+ "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.59.0", "", { "os": "openbsd", "cpu": "x64" }, "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ=="],
+
+ "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.59.0", "", { "os": "none", "cpu": "arm64" }, "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA=="],
+
+ "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.59.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A=="],
+
+ "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.59.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA=="],
+
+ "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.59.0", "", { "os": "win32", "cpu": "x64" }, "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA=="],
+
+ "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.59.0", "", { "os": "win32", "cpu": "x64" }, "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA=="],
+
+ "@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="],
+
+ "@standard-schema/utils": ["@standard-schema/utils@0.3.0", "", {}, "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g=="],
+
+ "@swc/core": ["@swc/core@1.15.18", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.25" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.15.18", "@swc/core-darwin-x64": "1.15.18", "@swc/core-linux-arm-gnueabihf": "1.15.18", "@swc/core-linux-arm64-gnu": "1.15.18", "@swc/core-linux-arm64-musl": "1.15.18", "@swc/core-linux-x64-gnu": "1.15.18", "@swc/core-linux-x64-musl": "1.15.18", "@swc/core-win32-arm64-msvc": "1.15.18", "@swc/core-win32-ia32-msvc": "1.15.18", "@swc/core-win32-x64-msvc": "1.15.18" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" }, "optionalPeers": ["@swc/helpers"] }, "sha512-z87aF9GphWp//fnkRsqvtY+inMVPgYW3zSlXH1kJFvRT5H/wiAn+G32qW5l3oEk63KSF1x3Ov0BfHCObAmT8RA=="],
+
+ "@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.15.18", "", { "os": "darwin", "cpu": "arm64" }, "sha512-+mIv7uBuSaywN3C9LNuWaX1jJJ3SKfiJuE6Lr3bd+/1Iv8oMU7oLBjYMluX1UrEPzwN2qCdY6Io0yVicABoCwQ=="],
+
+ "@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.15.18", "", { "os": "darwin", "cpu": "x64" }, "sha512-wZle0eaQhnzxWX5V/2kEOI6Z9vl/lTFEC6V4EWcn+5pDjhemCpQv9e/TDJ0GIoiClX8EDWRvuZwh+Z3dhL1NAg=="],
+
+ "@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.15.18", "", { "os": "linux", "cpu": "arm" }, "sha512-ao61HGXVqrJFHAcPtF4/DegmwEkVCo4HApnotLU8ognfmU8x589z7+tcf3hU+qBiU1WOXV5fQX6W9Nzs6hjxDw=="],
+
+ "@swc/core-linux-arm64-gnu": ["@swc/core-linux-arm64-gnu@1.15.18", "", { "os": "linux", "cpu": "arm64" }, "sha512-3xnctOBLIq3kj8PxOCgPrGjBLP/kNOddr6f5gukYt/1IZxsITQaU9TDyjeX6jG+FiCIHjCuWuffsyQDL5Ew1bg=="],
+
+ "@swc/core-linux-arm64-musl": ["@swc/core-linux-arm64-musl@1.15.18", "", { "os": "linux", "cpu": "arm64" }, "sha512-0a+Lix+FSSHBSBOA0XznCcHo5/1nA6oLLjcnocvzXeqtdjnPb+SvchItHI+lfeiuj1sClYPDvPMLSLyXFaiIKw=="],
+
+ "@swc/core-linux-x64-gnu": ["@swc/core-linux-x64-gnu@1.15.18", "", { "os": "linux", "cpu": "x64" }, "sha512-wG9J8vReUlpaHz4KOD/5UE1AUgirimU4UFT9oZmupUDEofxJKYb1mTA/DrMj0s78bkBiNI+7Fo2EgPuvOJfuAA=="],
+
+ "@swc/core-linux-x64-musl": ["@swc/core-linux-x64-musl@1.15.18", "", { "os": "linux", "cpu": "x64" }, "sha512-4nwbVvCphKzicwNWRmvD5iBaZj8JYsRGa4xOxJmOyHlMDpsvvJ2OR2cODlvWyGFH6BYL1MfIAK3qph3hp0Az6g=="],
+
+ "@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.15.18", "", { "os": "win32", "cpu": "arm64" }, "sha512-zk0RYO+LjiBCat2RTMHzAWaMky0cra9loH4oRrLKLLNuL+jarxKLFDA8xTZWEkCPLjUTwlRN7d28eDLLMgtUcQ=="],
+
+ "@swc/core-win32-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.15.18", "", { "os": "win32", "cpu": "ia32" }, "sha512-yVuTrZ0RccD5+PEkpcLOBAuPbYBXS6rslENvIXfvJGXSdX5QGi1ehC4BjAMl5FkKLiam4kJECUI0l7Hq7T1vwg=="],
+
+ "@swc/core-win32-x64-msvc": ["@swc/core-win32-x64-msvc@1.15.18", "", { "os": "win32", "cpu": "x64" }, "sha512-7NRmE4hmUQNCbYU3Hn9Tz57mK9Qq4c97ZS+YlamlK6qG9Fb5g/BB3gPDe0iLlJkns/sYv2VWSkm8c3NmbEGjbg=="],
+
+ "@swc/counter": ["@swc/counter@0.1.3", "", {}, "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="],
+
+ "@swc/types": ["@swc/types@0.1.25", "", { "dependencies": { "@swc/counter": "^0.1.3" } }, "sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g=="],
+
+ "@tabby_ai/hijri-converter": ["@tabby_ai/hijri-converter@1.0.5", "", {}, "sha512-r5bClKrcIusDoo049dSL8CawnHR6mRdDwhlQuIgZRNty68q0x8k3Lf1BtPAMxRf/GgnHBnIO4ujd3+GQdLWzxQ=="],
+
+ "@tailwindcss/node": ["@tailwindcss/node@4.2.1", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "^5.19.0", "jiti": "^2.6.1", "lightningcss": "1.31.1", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.2.1" } }, "sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg=="],
+
+ "@tailwindcss/oxide": ["@tailwindcss/oxide@4.2.1", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.2.1", "@tailwindcss/oxide-darwin-arm64": "4.2.1", "@tailwindcss/oxide-darwin-x64": "4.2.1", "@tailwindcss/oxide-freebsd-x64": "4.2.1", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.1", "@tailwindcss/oxide-linux-arm64-gnu": "4.2.1", "@tailwindcss/oxide-linux-arm64-musl": "4.2.1", "@tailwindcss/oxide-linux-x64-gnu": "4.2.1", "@tailwindcss/oxide-linux-x64-musl": "4.2.1", "@tailwindcss/oxide-wasm32-wasi": "4.2.1", "@tailwindcss/oxide-win32-arm64-msvc": "4.2.1", "@tailwindcss/oxide-win32-x64-msvc": "4.2.1" } }, "sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw=="],
+
+ "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.2.1", "", { "os": "android", "cpu": "arm64" }, "sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg=="],
+
+ "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.2.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw=="],
+
+ "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.2.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw=="],
+
+ "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.2.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA=="],
+
+ "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.2.1", "", { "os": "linux", "cpu": "arm" }, "sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw=="],
+
+ "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.2.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ=="],
+
+ "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.2.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ=="],
+
+ "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.2.1", "", { "os": "linux", "cpu": "x64" }, "sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g=="],
+
+ "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.2.1", "", { "os": "linux", "cpu": "x64" }, "sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g=="],
+
+ "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.2.1", "", { "dependencies": { "@emnapi/core": "^1.8.1", "@emnapi/runtime": "^1.8.1", "@emnapi/wasi-threads": "^1.1.0", "@napi-rs/wasm-runtime": "^1.1.1", "@tybys/wasm-util": "^0.10.1", "tslib": "^2.8.1" }, "cpu": "none" }, "sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q=="],
+
+ "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.2.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA=="],
+
+ "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.2.1", "", { "os": "win32", "cpu": "x64" }, "sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ=="],
+
+ "@tailwindcss/postcss": ["@tailwindcss/postcss@4.2.1", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.2.1", "@tailwindcss/oxide": "4.2.1", "postcss": "^8.5.6", "tailwindcss": "4.2.1" } }, "sha512-OEwGIBnXnj7zJeonOh6ZG9woofIjGrd2BORfvE5p9USYKDCZoQmfqLcfNiRWoJlRWLdNPn2IgVZuWAOM4iTYMw=="],
+
+ "@tailwindcss/typography": ["@tailwindcss/typography@0.5.19", "", { "dependencies": { "postcss-selector-parser": "6.0.10" }, "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" } }, "sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg=="],
+
+ "@tanstack/query-core": ["@tanstack/query-core@5.90.20", "", {}, "sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg=="],
+
+ "@tanstack/react-query": ["@tanstack/react-query@5.90.21", "", { "dependencies": { "@tanstack/query-core": "5.90.20" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-0Lu6y5t+tvlTJMTO7oh5NSpJfpg/5D41LlThfepTixPYkJ0sE2Jj0m0f6yYqujBwIXlId87e234+MxG3D3g7kg=="],
+
+ "@testing-library/dom": ["@testing-library/dom@10.4.1", "", { "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", "@types/aria-query": "^5.0.1", "aria-query": "5.3.0", "dom-accessibility-api": "^0.5.9", "lz-string": "^1.5.0", "picocolors": "1.1.1", "pretty-format": "^27.0.2" } }, "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg=="],
+
+ "@testing-library/jest-dom": ["@testing-library/jest-dom@6.9.1", "", { "dependencies": { "@adobe/css-tools": "^4.4.0", "aria-query": "^5.0.0", "css.escape": "^1.5.1", "dom-accessibility-api": "^0.6.3", "picocolors": "^1.1.1", "redent": "^3.0.0" } }, "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA=="],
+
+ "@testing-library/react": ["@testing-library/react@16.3.2", "", { "dependencies": { "@babel/runtime": "^7.12.5" }, "peerDependencies": { "@testing-library/dom": "^10.0.0", "@types/react": "^18.0.0 || ^19.0.0", "@types/react-dom": "^18.0.0 || ^19.0.0", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g=="],
+
+ "@types/aria-query": ["@types/aria-query@5.0.4", "", {}, "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw=="],
+
+ "@types/chai": ["@types/chai@5.2.3", "", { "dependencies": { "@types/deep-eql": "*", "assertion-error": "^2.0.1" } }, "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA=="],
+
+ "@types/d3-array": ["@types/d3-array@3.2.1", "", {}, "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg=="],
+
+ "@types/d3-color": ["@types/d3-color@3.1.3", "", {}, "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A=="],
+
+ "@types/d3-ease": ["@types/d3-ease@3.0.2", "", {}, "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA=="],
+
+ "@types/d3-interpolate": ["@types/d3-interpolate@3.0.4", "", { "dependencies": { "@types/d3-color": "*" } }, "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA=="],
+
+ "@types/d3-path": ["@types/d3-path@3.1.0", "", {}, "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ=="],
+
+ "@types/d3-scale": ["@types/d3-scale@4.0.8", "", { "dependencies": { "@types/d3-time": "*" } }, "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ=="],
+
+ "@types/d3-shape": ["@types/d3-shape@3.1.6", "", { "dependencies": { "@types/d3-path": "*" } }, "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA=="],
+
+ "@types/d3-time": ["@types/d3-time@3.0.3", "", {}, "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw=="],
+
+ "@types/d3-timer": ["@types/d3-timer@3.0.2", "", {}, "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw=="],
+
+ "@types/deep-eql": ["@types/deep-eql@4.0.2", "", {}, "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw=="],
+
+ "@types/esrecurse": ["@types/esrecurse@4.3.1", "", {}, "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw=="],
+
+ "@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="],
+
+ "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
+
+ "@types/node": ["@types/node@25.3.3", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-DpzbrH7wIcBaJibpKo9nnSQL0MTRdnWttGyE5haGwK86xgMOkFLp7vEyfQPGLOJh5wNYiJ3V9PmUMDhV9u8kkQ=="],
+
+ "@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="],
+
+ "@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="],
+
+ "@types/use-sync-external-store": ["@types/use-sync-external-store@0.0.6", "", {}, "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg=="],
+
+ "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.56.1", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.56.1", "@typescript-eslint/type-utils": "8.56.1", "@typescript-eslint/utils": "8.56.1", "@typescript-eslint/visitor-keys": "8.56.1", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.56.1", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A=="],
+
+ "@typescript-eslint/parser": ["@typescript-eslint/parser@8.56.1", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.56.1", "@typescript-eslint/types": "8.56.1", "@typescript-eslint/typescript-estree": "8.56.1", "@typescript-eslint/visitor-keys": "8.56.1", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg=="],
+
+ "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.56.1", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.56.1", "@typescript-eslint/types": "^8.56.1", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ=="],
+
+ "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.56.1", "", { "dependencies": { "@typescript-eslint/types": "8.56.1", "@typescript-eslint/visitor-keys": "8.56.1" } }, "sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w=="],
+
+ "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.56.1", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ=="],
+
+ "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.56.1", "", { "dependencies": { "@typescript-eslint/types": "8.56.1", "@typescript-eslint/typescript-estree": "8.56.1", "@typescript-eslint/utils": "8.56.1", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg=="],
+
+ "@typescript-eslint/types": ["@typescript-eslint/types@8.56.1", "", {}, "sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw=="],
+
+ "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.56.1", "", { "dependencies": { "@typescript-eslint/project-service": "8.56.1", "@typescript-eslint/tsconfig-utils": "8.56.1", "@typescript-eslint/types": "8.56.1", "@typescript-eslint/visitor-keys": "8.56.1", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg=="],
+
+ "@typescript-eslint/utils": ["@typescript-eslint/utils@8.56.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.56.1", "@typescript-eslint/types": "8.56.1", "@typescript-eslint/typescript-estree": "8.56.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA=="],
+
+ "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.56.1", "", { "dependencies": { "@typescript-eslint/types": "8.56.1", "eslint-visitor-keys": "^5.0.0" } }, "sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw=="],
+
+ "@vitejs/plugin-react-swc": ["@vitejs/plugin-react-swc@4.2.3", "", { "dependencies": { "@rolldown/pluginutils": "1.0.0-rc.2", "@swc/core": "^1.15.11" }, "peerDependencies": { "vite": "^4 || ^5 || ^6 || ^7" } }, "sha512-QIluDil2prhY1gdA3GGwxZzTAmLdi8cQ2CcuMW4PB/Wu4e/1pzqrwhYWVd09LInCRlDUidQjd0B70QWbjWtLxA=="],
+
+ "@vitest/expect": ["@vitest/expect@4.0.18", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "@types/chai": "^5.2.2", "@vitest/spy": "4.0.18", "@vitest/utils": "4.0.18", "chai": "^6.2.1", "tinyrainbow": "^3.0.3" } }, "sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ=="],
+
+ "@vitest/mocker": ["@vitest/mocker@4.0.18", "", { "dependencies": { "@vitest/spy": "4.0.18", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^6.0.0 || ^7.0.0-0" }, "optionalPeers": ["msw", "vite"] }, "sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ=="],
+
+ "@vitest/pretty-format": ["@vitest/pretty-format@4.0.18", "", { "dependencies": { "tinyrainbow": "^3.0.3" } }, "sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw=="],
+
+ "@vitest/runner": ["@vitest/runner@4.0.18", "", { "dependencies": { "@vitest/utils": "4.0.18", "pathe": "^2.0.3" } }, "sha512-rpk9y12PGa22Jg6g5M3UVVnTS7+zycIGk9ZNGN+m6tZHKQb7jrP7/77WfZy13Y/EUDd52NDsLRQhYKtv7XfPQw=="],
+
+ "@vitest/snapshot": ["@vitest/snapshot@4.0.18", "", { "dependencies": { "@vitest/pretty-format": "4.0.18", "magic-string": "^0.30.21", "pathe": "^2.0.3" } }, "sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA=="],
+
+ "@vitest/spy": ["@vitest/spy@4.0.18", "", {}, "sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw=="],
+
+ "@vitest/utils": ["@vitest/utils@4.0.18", "", { "dependencies": { "@vitest/pretty-format": "4.0.18", "tinyrainbow": "^3.0.3" } }, "sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA=="],
+
+ "acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="],
+
+ "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
+
+ "agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="],
+
+ "ajv": ["ajv@6.14.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw=="],
+
+ "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
+
+ "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
+
+ "aria-hidden": ["aria-hidden@1.2.4", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A=="],
+
+ "aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="],
+
+ "assertion-error": ["assertion-error@2.0.1", "", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="],
+
+ "autoprefixer": ["autoprefixer@10.4.27", "", { "dependencies": { "browserslist": "^4.28.1", "caniuse-lite": "^1.0.30001774", "fraction.js": "^5.3.4", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA=="],
+
+ "balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
+
+ "baseline-browser-mapping": ["baseline-browser-mapping@2.10.0", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA=="],
+
+ "bidi-js": ["bidi-js@1.0.3", "", { "dependencies": { "require-from-string": "^2.0.2" } }, "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw=="],
+
+ "brace-expansion": ["brace-expansion@5.0.4", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg=="],
+
+ "browserslist": ["browserslist@4.28.1", "", { "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" } }, "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA=="],
+
+ "caniuse-lite": ["caniuse-lite@1.0.30001775", "", {}, "sha512-s3Qv7Lht9zbVKE9XoTyRG6wVDCKdtOFIjBGg3+Yhn6JaytuNKPIjBMTMIY1AnOH3seL5mvF+x33oGAyK3hVt3A=="],
+
+ "chai": ["chai@6.2.2", "", {}, "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg=="],
+
+ "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
+
+ "class-variance-authority": ["class-variance-authority@0.7.1", "", { "dependencies": { "clsx": "^2.1.1" } }, "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg=="],
+
+ "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
+
+ "cmdk": ["cmdk@1.1.1", "", { "dependencies": { "@radix-ui/react-compose-refs": "^1.1.1", "@radix-ui/react-dialog": "^1.1.6", "@radix-ui/react-id": "^1.1.0", "@radix-ui/react-primitive": "^2.0.2" }, "peerDependencies": { "react": "^18 || ^19 || ^19.0.0-rc", "react-dom": "^18 || ^19 || ^19.0.0-rc" } }, "sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg=="],
+
+ "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
+
+ "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
+
+ "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="],
+
+ "cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="],
+
+ "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
+
+ "css-tree": ["css-tree@3.1.0", "", { "dependencies": { "mdn-data": "2.12.2", "source-map-js": "^1.0.1" } }, "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w=="],
+
+ "css.escape": ["css.escape@1.5.1", "", {}, "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg=="],
+
+ "cssesc": ["cssesc@3.0.0", "", { "bin": "bin/cssesc" }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="],
+
+ "cssstyle": ["cssstyle@6.1.0", "", { "dependencies": { "@asamuzakjp/css-color": "^5.0.0", "@csstools/css-syntax-patches-for-csstree": "^1.0.28", "css-tree": "^3.1.0", "lru-cache": "^11.2.6" } }, "sha512-Ml4fP2UT2K3CUBQnVlbdV/8aFDdlY69E+YnwJM+3VUWl08S3J8c8aRuJqCkD9Py8DHZ7zNNvsfKl8psocHZEFg=="],
+
+ "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
+
+ "d3-array": ["d3-array@3.2.4", "", { "dependencies": { "internmap": "1 - 2" } }, "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg=="],
+
+ "d3-color": ["d3-color@3.1.0", "", {}, "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA=="],
+
+ "d3-ease": ["d3-ease@3.0.1", "", {}, "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w=="],
+
+ "d3-format": ["d3-format@3.1.0", "", {}, "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA=="],
+
+ "d3-interpolate": ["d3-interpolate@3.0.1", "", { "dependencies": { "d3-color": "1 - 3" } }, "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g=="],
+
+ "d3-path": ["d3-path@3.1.0", "", {}, "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ=="],
+
+ "d3-scale": ["d3-scale@4.0.2", "", { "dependencies": { "d3-array": "2.10.0 - 3", "d3-format": "1 - 3", "d3-interpolate": "1.2.0 - 3", "d3-time": "2.1.1 - 3", "d3-time-format": "2 - 4" } }, "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ=="],
+
+ "d3-shape": ["d3-shape@3.2.0", "", { "dependencies": { "d3-path": "^3.1.0" } }, "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA=="],
+
+ "d3-time": ["d3-time@3.1.0", "", { "dependencies": { "d3-array": "2 - 3" } }, "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q=="],
+
+ "d3-time-format": ["d3-time-format@4.1.0", "", { "dependencies": { "d3-time": "1 - 3" } }, "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg=="],
+
+ "d3-timer": ["d3-timer@3.0.1", "", {}, "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA=="],
+
+ "data-urls": ["data-urls@7.0.0", "", { "dependencies": { "whatwg-mimetype": "^5.0.0", "whatwg-url": "^16.0.0" } }, "sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA=="],
+
+ "date-fns": ["date-fns@4.1.0", "", {}, "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg=="],
+
+ "date-fns-jalali": ["date-fns-jalali@4.1.0-0", "", {}, "sha512-hTIP/z+t+qKwBDcmmsnmjWTduxCg+5KfdqWQvb2X/8C9+knYY6epN/pfxdDuyVlSVeFz0sM5eEfwIUQ70U4ckg=="],
+
+ "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
+
+ "decimal.js": ["decimal.js@10.6.0", "", {}, "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg=="],
+
+ "decimal.js-light": ["decimal.js-light@2.5.1", "", {}, "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg=="],
+
+ "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
+
+ "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="],
+
+ "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
+
+ "detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="],
+
+ "dom-accessibility-api": ["dom-accessibility-api@0.6.3", "", {}, "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w=="],
+
+ "electron-to-chromium": ["electron-to-chromium@1.5.302", "", {}, "sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg=="],
+
+ "embla-carousel": ["embla-carousel@8.6.0", "", {}, "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA=="],
+
+ "embla-carousel-react": ["embla-carousel-react@8.6.0", "", { "dependencies": { "embla-carousel": "8.6.0", "embla-carousel-reactive-utils": "8.6.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-0/PjqU7geVmo6F734pmPqpyHqiM99olvyecY7zdweCw+6tKEXnrE90pBiBbMMU8s5tICemzpQ3hi5EpxzGW+JA=="],
+
+ "embla-carousel-reactive-utils": ["embla-carousel-reactive-utils@8.6.0", "", { "peerDependencies": { "embla-carousel": "8.6.0" } }, "sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A=="],
+
+ "enhanced-resolve": ["enhanced-resolve@5.20.0", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.0" } }, "sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ=="],
+
+ "entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
+
+ "es-module-lexer": ["es-module-lexer@1.7.0", "", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="],
+
+ "es-toolkit": ["es-toolkit@1.44.0", "", {}, "sha512-6penXeZalaV88MM3cGkFZZfOoLGWshWWfdy0tWw/RlVVyhvMaWSBTOvXNeiW3e5FwdS5ePW0LGEu17zT139ktg=="],
+
+ "esbuild": ["esbuild@0.27.3", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.3", "@esbuild/android-arm": "0.27.3", "@esbuild/android-arm64": "0.27.3", "@esbuild/android-x64": "0.27.3", "@esbuild/darwin-arm64": "0.27.3", "@esbuild/darwin-x64": "0.27.3", "@esbuild/freebsd-arm64": "0.27.3", "@esbuild/freebsd-x64": "0.27.3", "@esbuild/linux-arm": "0.27.3", "@esbuild/linux-arm64": "0.27.3", "@esbuild/linux-ia32": "0.27.3", "@esbuild/linux-loong64": "0.27.3", "@esbuild/linux-mips64el": "0.27.3", "@esbuild/linux-ppc64": "0.27.3", "@esbuild/linux-riscv64": "0.27.3", "@esbuild/linux-s390x": "0.27.3", "@esbuild/linux-x64": "0.27.3", "@esbuild/netbsd-arm64": "0.27.3", "@esbuild/netbsd-x64": "0.27.3", "@esbuild/openbsd-arm64": "0.27.3", "@esbuild/openbsd-x64": "0.27.3", "@esbuild/openharmony-arm64": "0.27.3", "@esbuild/sunos-x64": "0.27.3", "@esbuild/win32-arm64": "0.27.3", "@esbuild/win32-ia32": "0.27.3", "@esbuild/win32-x64": "0.27.3" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg=="],
+
+ "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
+
+ "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
+
+ "eslint": ["eslint@10.0.2", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", "@eslint/config-array": "^0.23.2", "@eslint/config-helpers": "^0.5.2", "@eslint/core": "^1.1.0", "@eslint/plugin-kit": "^0.6.0", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.14.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^9.1.1", "eslint-visitor-keys": "^5.0.1", "espree": "^11.1.1", "esquery": "^1.7.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "minimatch": "^10.2.1", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-uYixubwmqJZH+KLVYIVKY1JQt7tysXhtj21WSvjcSmU5SVNzMus1bgLe+pAt816yQ8opKfheVVoPLqvVMGejYw=="],
+
+ "eslint-plugin-react-hooks": ["eslint-plugin-react-hooks@7.0.1", "", { "dependencies": { "@babel/core": "^7.24.4", "@babel/parser": "^7.24.4", "hermes-parser": "^0.25.1", "zod": "^3.25.0 || ^4.0.0", "zod-validation-error": "^3.5.0 || ^4.0.0" }, "peerDependencies": { "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" } }, "sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA=="],
+
+ "eslint-plugin-react-refresh": ["eslint-plugin-react-refresh@0.5.2", "", { "peerDependencies": { "eslint": "^9 || ^10" } }, "sha512-hmgTH57GfzoTFjVN0yBwTggnsVUF2tcqi7RJZHqi9lIezSs4eFyAMktA68YD4r5kNw1mxyY4dmkyoFDb3FIqrA=="],
+
+ "eslint-scope": ["eslint-scope@9.1.1", "", { "dependencies": { "@types/esrecurse": "^4.3.1", "@types/estree": "^1.0.8", "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-GaUN0sWim5qc8KVErfPBWmc31LEsOkrUJbvJZV+xuL3u2phMUK4HIvXlWAakfC8W4nzlK+chPEAkYOYb5ZScIw=="],
+
+ "eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="],
+
+ "espree": ["espree@11.1.1", "", { "dependencies": { "acorn": "^8.16.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^5.0.1" } }, "sha512-AVHPqQoZYc+RUM4/3Ly5udlZY/U4LS8pIG05jEjWM2lQMU/oaZ7qshzAl2YP1tfNmXfftH3ohurfwNAug+MnsQ=="],
+
+ "esquery": ["esquery@1.7.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g=="],
+
+ "esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="],
+
+ "estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="],
+
+ "estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="],
+
+ "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="],
+
+ "eventemitter3": ["eventemitter3@5.0.4", "", {}, "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw=="],
+
+ "expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="],
+
+ "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
+
+ "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="],
+
+ "fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="],
+
+ "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
+
+ "file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="],
+
+ "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="],
+
+ "flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="],
+
+ "flatted": ["flatted@3.3.1", "", {}, "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw=="],
+
+ "fraction.js": ["fraction.js@5.3.4", "", {}, "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ=="],
+
+ "fs-extra": ["fs-extra@10.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ=="],
+
+ "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
+
+ "gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="],
+
+ "get-nonce": ["get-nonce@1.0.1", "", {}, "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q=="],
+
+ "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
+
+ "globals": ["globals@17.4.0", "", {}, "sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw=="],
+
+ "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
+
+ "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
+
+ "hermes-estree": ["hermes-estree@0.25.1", "", {}, "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw=="],
+
+ "hermes-parser": ["hermes-parser@0.25.1", "", { "dependencies": { "hermes-estree": "0.25.1" } }, "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA=="],
+
+ "html-encoding-sniffer": ["html-encoding-sniffer@6.0.0", "", { "dependencies": { "@exodus/bytes": "^1.6.0" } }, "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg=="],
+
+ "http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="],
+
+ "https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="],
+
+ "ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
+
+ "immer": ["immer@10.2.0", "", {}, "sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw=="],
+
+ "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
+
+ "indent-string": ["indent-string@4.0.0", "", {}, "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="],
+
+ "input-otp": ["input-otp@1.4.2", "", { "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-l3jWwYNvrEa6NTCt7BECfCm48GvwuZzkoeG3gBL2w4CHeOXW3eKFmf9UNYkNfYc3mxMrthMnxjIE07MT0zLBQA=="],
+
+ "internmap": ["internmap@2.0.3", "", {}, "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="],
+
+ "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
+
+ "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
+
+ "is-potential-custom-element-name": ["is-potential-custom-element-name@1.0.1", "", {}, "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="],
+
+ "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
+
+ "jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="],
+
+ "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
+
+ "jsdom": ["jsdom@28.1.0", "", { "dependencies": { "@acemir/cssom": "^0.9.31", "@asamuzakjp/dom-selector": "^6.8.1", "@bramus/specificity": "^2.4.2", "@exodus/bytes": "^1.11.0", "cssstyle": "^6.0.1", "data-urls": "^7.0.0", "decimal.js": "^10.6.0", "html-encoding-sniffer": "^6.0.0", "http-proxy-agent": "^7.0.2", "https-proxy-agent": "^7.0.6", "is-potential-custom-element-name": "^1.0.1", "parse5": "^8.0.0", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^6.0.0", "undici": "^7.21.0", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^8.0.1", "whatwg-mimetype": "^5.0.0", "whatwg-url": "^16.0.0", "xml-name-validator": "^5.0.0" }, "peerDependencies": { "canvas": "^3.0.0" }, "optionalPeers": ["canvas"] }, "sha512-0+MoQNYyr2rBHqO1xilltfDjV9G7ymYGlAUazgcDLQaUf8JDHbuGwsxN6U9qWaElZ4w1B2r7yEGIL3GdeW3Rug=="],
+
+ "jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="],
+
+ "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="],
+
+ "json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
+
+ "json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="],
+
+ "json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="],
+
+ "jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="],
+
+ "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="],
+
+ "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
+
+ "lightningcss": ["lightningcss@1.31.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.31.1", "lightningcss-darwin-arm64": "1.31.1", "lightningcss-darwin-x64": "1.31.1", "lightningcss-freebsd-x64": "1.31.1", "lightningcss-linux-arm-gnueabihf": "1.31.1", "lightningcss-linux-arm64-gnu": "1.31.1", "lightningcss-linux-arm64-musl": "1.31.1", "lightningcss-linux-x64-gnu": "1.31.1", "lightningcss-linux-x64-musl": "1.31.1", "lightningcss-win32-arm64-msvc": "1.31.1", "lightningcss-win32-x64-msvc": "1.31.1" } }, "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ=="],
+
+ "lightningcss-android-arm64": ["lightningcss-android-arm64@1.31.1", "", { "os": "android", "cpu": "arm64" }, "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg=="],
+
+ "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.31.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg=="],
+
+ "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.31.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA=="],
+
+ "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.31.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A=="],
+
+ "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.31.1", "", { "os": "linux", "cpu": "arm" }, "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g=="],
+
+ "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.31.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg=="],
+
+ "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.31.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg=="],
+
+ "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.31.1", "", { "os": "linux", "cpu": "x64" }, "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA=="],
+
+ "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.31.1", "", { "os": "linux", "cpu": "x64" }, "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA=="],
+
+ "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.31.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w=="],
+
+ "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.31.1", "", { "os": "win32", "cpu": "x64" }, "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw=="],
+
+ "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
+
+ "lru-cache": ["lru-cache@11.2.6", "", {}, "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ=="],
+
+ "lucide-react": ["lucide-react@0.575.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-VuXgKZrk0uiDlWjGGXmKV6MSk9Yy4l10qgVvzGn2AWBx1Ylt0iBexKOAoA6I7JO3m+M9oeovJd3yYENfkUbOeg=="],
+
+ "lz-string": ["lz-string@1.5.0", "", { "bin": { "lz-string": "bin/bin.js" } }, "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ=="],
+
+ "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
+
+ "mdn-data": ["mdn-data@2.12.2", "", {}, "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA=="],
+
+ "min-indent": ["min-indent@1.0.1", "", {}, "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg=="],
+
+ "minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="],
+
+ "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
+
+ "nanoid": ["nanoid@3.3.11", "", { "bin": "bin/nanoid.cjs" }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
+
+ "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
+
+ "next-themes": ["next-themes@0.4.6", "", { "peerDependencies": { "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" } }, "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA=="],
+
+ "node-releases": ["node-releases@2.0.27", "", {}, "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="],
+
+ "obug": ["obug@2.1.1", "", {}, "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ=="],
+
+ "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="],
+
+ "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
+
+ "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="],
+
+ "parse5": ["parse5@8.0.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA=="],
+
+ "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="],
+
+ "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
+
+ "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="],
+
+ "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
+
+ "picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
+
+ "postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
+
+ "postcss-selector-parser": ["postcss-selector-parser@6.0.10", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w=="],
+
+ "postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="],
+
+ "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
+
+ "pretty-format": ["pretty-format@27.5.1", "", { "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" } }, "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ=="],
+
+ "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
+
+ "react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="],
+
+ "react-day-picker": ["react-day-picker@9.14.0", "", { "dependencies": { "@date-fns/tz": "^1.4.1", "@tabby_ai/hijri-converter": "1.0.5", "date-fns": "^4.1.0", "date-fns-jalali": "4.1.0-0" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-tBaoDWjPwe0M5pGrum4H0SR6Lyk+BO9oHnp9JbKpGKW2mlraNPgP9BMfsg5pWpwrssARmeqk7YBl2oXutZTaHA=="],
+
+ "react-dom": ["react-dom@19.2.4", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="],
+
+ "react-hook-form": ["react-hook-form@7.71.2", "", { "peerDependencies": { "react": "^16.8.0 || ^17 || ^18 || ^19" } }, "sha512-1CHvcDYzuRUNOflt4MOq3ZM46AronNJtQ1S7tnX6YN4y72qhgiUItpacZUAQ0TyWYci3yz1X+rXaSxiuEm86PA=="],
+
+ "react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
+
+ "react-redux": ["react-redux@9.2.0", "", { "dependencies": { "@types/use-sync-external-store": "^0.0.6", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { "@types/react": "^18.2.25 || ^19", "react": "^18.0 || ^19", "redux": "^5.0.0" }, "optionalPeers": ["@types/react", "redux"] }, "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g=="],
+
+ "react-remove-scroll": ["react-remove-scroll@2.7.1", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", "use-callback-ref": "^1.3.3", "use-sidecar": "^1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA=="],
+
+ "react-remove-scroll-bar": ["react-remove-scroll-bar@2.3.8", "", { "dependencies": { "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q=="],
+
+ "react-resizable-panels": ["react-resizable-panels@4.7.0", "", { "peerDependencies": { "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" } }, "sha512-QJTeh8KJR6lKzDwVez+WGPPUPuarIjR3ptg23thJ0G5dAMYJH4iSN1AnNY0DuSP+PgH8s9eYfwrR7AlmX6TvYA=="],
+
+ "react-router": ["react-router@7.13.1", "", { "dependencies": { "cookie": "^1.0.1", "set-cookie-parser": "^2.6.0" }, "peerDependencies": { "react": ">=18", "react-dom": ">=18" }, "optionalPeers": ["react-dom"] }, "sha512-td+xP4X2/6BJvZoX6xw++A2DdEi++YypA69bJUV5oVvqf6/9/9nNlD70YO1e9d3MyamJEBQFEzk6mbfDYbqrSA=="],
+
+ "react-router-dom": ["react-router-dom@7.13.1", "", { "dependencies": { "react-router": "7.13.1" }, "peerDependencies": { "react": ">=18", "react-dom": ">=18" } }, "sha512-UJnV3Rxc5TgUPJt2KJpo1Jpy0OKQr0AjgbZzBFjaPJcFOb2Y8jA5H3LT8HUJAiRLlWrEXWHbF1Z4SCZaQjWDHw=="],
+
+ "react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="],
+
+ "recharts": ["recharts@3.7.0", "", { "dependencies": { "@reduxjs/toolkit": "1.x.x || 2.x.x", "clsx": "^2.1.1", "decimal.js-light": "^2.5.1", "es-toolkit": "^1.39.3", "eventemitter3": "^5.0.1", "immer": "^10.1.1", "react-redux": "8.x.x || 9.x.x", "reselect": "5.1.1", "tiny-invariant": "^1.3.3", "use-sync-external-store": "^1.2.2", "victory-vendor": "^37.0.2" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-is": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-l2VCsy3XXeraxIID9fx23eCb6iCBsxUQDnE8tWm6DFdszVAO7WVY/ChAD9wVit01y6B2PMupYiMmQwhgPHc9Ew=="],
+
+ "redent": ["redent@3.0.0", "", { "dependencies": { "indent-string": "^4.0.0", "strip-indent": "^3.0.0" } }, "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg=="],
+
+ "redux": ["redux@5.0.1", "", {}, "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w=="],
+
+ "redux-thunk": ["redux-thunk@3.1.0", "", { "peerDependencies": { "redux": "^5.0.0" } }, "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw=="],
+
+ "require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="],
+
+ "reselect": ["reselect@5.1.1", "", {}, "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w=="],
+
+ "rollup": ["rollup@4.59.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.59.0", "@rollup/rollup-android-arm64": "4.59.0", "@rollup/rollup-darwin-arm64": "4.59.0", "@rollup/rollup-darwin-x64": "4.59.0", "@rollup/rollup-freebsd-arm64": "4.59.0", "@rollup/rollup-freebsd-x64": "4.59.0", "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", "@rollup/rollup-linux-arm-musleabihf": "4.59.0", "@rollup/rollup-linux-arm64-gnu": "4.59.0", "@rollup/rollup-linux-arm64-musl": "4.59.0", "@rollup/rollup-linux-loong64-gnu": "4.59.0", "@rollup/rollup-linux-loong64-musl": "4.59.0", "@rollup/rollup-linux-ppc64-gnu": "4.59.0", "@rollup/rollup-linux-ppc64-musl": "4.59.0", "@rollup/rollup-linux-riscv64-gnu": "4.59.0", "@rollup/rollup-linux-riscv64-musl": "4.59.0", "@rollup/rollup-linux-s390x-gnu": "4.59.0", "@rollup/rollup-linux-x64-gnu": "4.59.0", "@rollup/rollup-linux-x64-musl": "4.59.0", "@rollup/rollup-openbsd-x64": "4.59.0", "@rollup/rollup-openharmony-arm64": "4.59.0", "@rollup/rollup-win32-arm64-msvc": "4.59.0", "@rollup/rollup-win32-ia32-msvc": "4.59.0", "@rollup/rollup-win32-x64-gnu": "4.59.0", "@rollup/rollup-win32-x64-msvc": "4.59.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg=="],
+
+ "saxes": ["saxes@6.0.0", "", { "dependencies": { "xmlchars": "^2.2.0" } }, "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA=="],
+
+ "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
+
+ "semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
+
+ "set-cookie-parser": ["set-cookie-parser@2.7.2", "", {}, "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw=="],
+
+ "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
+
+ "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
+
+ "siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="],
+
+ "sonner": ["sonner@2.0.7", "", { "peerDependencies": { "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w=="],
+
+ "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
+
+ "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="],
+
+ "std-env": ["std-env@3.10.0", "", {}, "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg=="],
+
+ "strip-indent": ["strip-indent@3.0.0", "", { "dependencies": { "min-indent": "^1.0.0" } }, "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ=="],
+
+ "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
+
+ "symbol-tree": ["symbol-tree@3.2.4", "", {}, "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="],
+
+ "tailwind-merge": ["tailwind-merge@3.5.0", "", {}, "sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A=="],
+
+ "tailwindcss": ["tailwindcss@4.2.1", "", {}, "sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw=="],
+
+ "tailwindcss-animate": ["tailwindcss-animate@1.0.7", "", { "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders" } }, "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA=="],
+
+ "tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="],
+
+ "tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="],
+
+ "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="],
+
+ "tinyexec": ["tinyexec@1.0.2", "", {}, "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg=="],
+
+ "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="],
+
+ "tinyrainbow": ["tinyrainbow@3.0.3", "", {}, "sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q=="],
+
+ "tldts": ["tldts@7.0.23", "", { "dependencies": { "tldts-core": "^7.0.23" }, "bin": { "tldts": "bin/cli.js" } }, "sha512-ASdhgQIBSay0R/eXggAkQ53G4nTJqTXqC2kbaBbdDwM7SkjyZyO0OaaN1/FH7U/yCeqOHDwFO5j8+Os/IS1dXw=="],
+
+ "tldts-core": ["tldts-core@7.0.23", "", {}, "sha512-0g9vrtDQLrNIiCj22HSe9d4mLVG3g5ph5DZ8zCKBr4OtrspmNB6ss7hVyzArAeE88ceZocIEGkyW1Ime7fxPtQ=="],
+
+ "tough-cookie": ["tough-cookie@6.0.0", "", { "dependencies": { "tldts": "^7.0.5" } }, "sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w=="],
+
+ "tr46": ["tr46@6.0.0", "", { "dependencies": { "punycode": "^2.3.1" } }, "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw=="],
+
+ "ts-api-utils": ["ts-api-utils@2.4.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA=="],
+
+ "tslib": ["tslib@2.8.0", "", {}, "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA=="],
+
+ "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
+
+ "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
+
+ "typescript-eslint": ["typescript-eslint@8.56.1", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.56.1", "@typescript-eslint/parser": "8.56.1", "@typescript-eslint/typescript-estree": "8.56.1", "@typescript-eslint/utils": "8.56.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-U4lM6pjmBX7J5wk4szltF7I1cGBHXZopnAXCMXb3+fZ3B/0Z3hq3wS/CCUB2NZBNAExK92mCU2tEohWuwVMsDQ=="],
+
+ "undici": ["undici@7.22.0", "", {}, "sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg=="],
+
+ "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="],
+
+ "universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="],
+
+ "update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="],
+
+ "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
+
+ "use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="],
+
+ "use-sidecar": ["use-sidecar@1.1.3", "", { "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ=="],
+
+ "use-sync-external-store": ["use-sync-external-store@1.5.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A=="],
+
+ "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
+
+ "vaul": ["vaul@1.1.2", "", { "dependencies": { "@radix-ui/react-dialog": "^1.1.1" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA=="],
+
+ "victory-vendor": ["victory-vendor@37.3.6", "", { "dependencies": { "@types/d3-array": "^3.0.3", "@types/d3-ease": "^3.0.0", "@types/d3-interpolate": "^3.0.1", "@types/d3-scale": "^4.0.2", "@types/d3-shape": "^3.1.0", "@types/d3-time": "^3.0.0", "@types/d3-timer": "^3.0.0", "d3-array": "^3.1.6", "d3-ease": "^3.0.1", "d3-interpolate": "^3.0.1", "d3-scale": "^4.0.2", "d3-shape": "^3.1.0", "d3-time": "^3.0.0", "d3-timer": "^3.0.1" } }, "sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ=="],
+
+ "vite": ["vite@7.3.1", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA=="],
+
+ "vite-plugin-compression": ["vite-plugin-compression@0.5.1", "", { "dependencies": { "chalk": "^4.1.2", "debug": "^4.3.3", "fs-extra": "^10.0.0" }, "peerDependencies": { "vite": ">=2.0.0" } }, "sha512-5QJKBDc+gNYVqL/skgFAP81Yuzo9R+EAf19d+EtsMF/i8kFUpNi3J/H01QD3Oo8zBQn+NzoCIFkpPLynoOzaJg=="],
+
+ "vitest": ["vitest@4.0.18", "", { "dependencies": { "@vitest/expect": "4.0.18", "@vitest/mocker": "4.0.18", "@vitest/pretty-format": "4.0.18", "@vitest/runner": "4.0.18", "@vitest/snapshot": "4.0.18", "@vitest/spy": "4.0.18", "@vitest/utils": "4.0.18", "es-module-lexer": "^1.7.0", "expect-type": "^1.2.2", "magic-string": "^0.30.21", "obug": "^2.1.1", "pathe": "^2.0.3", "picomatch": "^4.0.3", "std-env": "^3.10.0", "tinybench": "^2.9.0", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tinyrainbow": "^3.0.3", "vite": "^6.0.0 || ^7.0.0", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", "@vitest/browser-playwright": "4.0.18", "@vitest/browser-preview": "4.0.18", "@vitest/browser-webdriverio": "4.0.18", "@vitest/ui": "4.0.18", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@opentelemetry/api", "@types/node", "@vitest/browser-playwright", "@vitest/browser-preview", "@vitest/browser-webdriverio", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ=="],
+
+ "w3c-xmlserializer": ["w3c-xmlserializer@5.0.0", "", { "dependencies": { "xml-name-validator": "^5.0.0" } }, "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA=="],
+
+ "webidl-conversions": ["webidl-conversions@8.0.1", "", {}, "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ=="],
+
+ "whatwg-mimetype": ["whatwg-mimetype@5.0.0", "", {}, "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw=="],
+
+ "whatwg-url": ["whatwg-url@16.0.1", "", { "dependencies": { "@exodus/bytes": "^1.11.0", "tr46": "^6.0.0", "webidl-conversions": "^8.0.1" } }, "sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw=="],
+
+ "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
+
+ "why-is-node-running": ["why-is-node-running@2.3.0", "", { "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="],
+
+ "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
+
+ "xml-name-validator": ["xml-name-validator@5.0.0", "", {}, "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg=="],
+
+ "xmlchars": ["xmlchars@2.2.0", "", {}, "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="],
+
+ "yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
+
+ "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
+
+ "zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="],
+
+ "zod-validation-error": ["zod-validation-error@4.0.2", "", { "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" } }, "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ=="],
+
+ "@babel/generator/@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
+
+ "@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
+
+ "@babel/helper-compilation-targets/lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
+
+ "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
+
+ "@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="],
+
+ "@jridgewell/gen-mapping/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="],
+
+ "@jridgewell/trace-mapping/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="],
+
+ "@radix-ui/react-alert-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
+
+ "@radix-ui/react-aspect-ratio/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.4", "", { "dependencies": { "@radix-ui/react-slot": "1.2.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg=="],
+
+ "@radix-ui/react-avatar/@radix-ui/react-context": ["@radix-ui/react-context@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-ieIFACdMpYfMEjF0rEf5KLvfVyIkOz6PDGyNnP+u+4xQ6jny3VCgA4OgXOwNx2aUkxn8zx9fiVcM8CfFYv9Lxw=="],
+
+ "@radix-ui/react-avatar/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.4", "", { "dependencies": { "@radix-ui/react-slot": "1.2.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg=="],
+
+ "@radix-ui/react-collection/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
+
+ "@radix-ui/react-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
+
+ "@radix-ui/react-label/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.4", "", { "dependencies": { "@radix-ui/react-slot": "1.2.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg=="],
+
+ "@radix-ui/react-menu/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
+
+ "@radix-ui/react-popover/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
+
+ "@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
+
+ "@radix-ui/react-progress/@radix-ui/react-context": ["@radix-ui/react-context@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-ieIFACdMpYfMEjF0rEf5KLvfVyIkOz6PDGyNnP+u+4xQ6jny3VCgA4OgXOwNx2aUkxn8zx9fiVcM8CfFYv9Lxw=="],
+
+ "@radix-ui/react-progress/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.4", "", { "dependencies": { "@radix-ui/react-slot": "1.2.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg=="],
+
+ "@radix-ui/react-select/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
+
+ "@radix-ui/react-separator/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.4", "", { "dependencies": { "@radix-ui/react-slot": "1.2.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg=="],
+
+ "@radix-ui/react-tooltip/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
+
+ "@reduxjs/toolkit/immer": ["immer@11.1.4", "", {}, "sha512-XREFCPo6ksxVzP4E0ekD5aMdf8WMwmdNaz6vuvxgI40UaEiu6q3p8X52aU6GdyvLY3XXX/8R7JOTXStz/nBbRw=="],
+
+ "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.8.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg=="],
+
+ "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="],
+
+ "@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="],
+
+ "@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.1", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" }, "bundled": true }, "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A=="],
+
+ "@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
+
+ "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
+
+ "@testing-library/dom/aria-query": ["aria-query@5.3.0", "", { "dependencies": { "dequal": "^2.0.3" } }, "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A=="],
+
+ "@testing-library/dom/dom-accessibility-api": ["dom-accessibility-api@0.5.16", "", {}, "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg=="],
+
+ "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
+
+ "@typescript-eslint/typescript-estree/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
+
+ "autoprefixer/caniuse-lite": ["caniuse-lite@1.0.30001774", "", {}, "sha512-DDdwPGz99nmIEv216hKSgLD+D4ikHQHjBC/seF98N9CPqRX4M5mSxT9eTV6oyisnJcuzxtZy4n17yKKQYmYQOA=="],
+
+ "browserslist/caniuse-lite": ["caniuse-lite@1.0.30001774", "", {}, "sha512-DDdwPGz99nmIEv216hKSgLD+D4ikHQHjBC/seF98N9CPqRX4M5mSxT9eTV6oyisnJcuzxtZy4n17yKKQYmYQOA=="],
+
+ "cmdk/@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.10", "@radix-ui/react-focus-guards": "1.1.2", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.4", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw=="],
+
+ "eslint-scope/@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
+
+ "pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="],
+
+ "pretty-format/react-is": ["react-is@17.0.2", "", {}, "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="],
+
+ "rollup/@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
+
+ "cmdk/@radix-ui/react-dialog/@radix-ui/primitive": ["@radix-ui/primitive@1.1.2", "", {}, "sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA=="],
+
+ "cmdk/@radix-ui/react-dialog/@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.10", "", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-escape-keydown": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ=="],
+
+ "cmdk/@radix-ui/react-dialog/@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA=="],
+
+ "cmdk/@radix-ui/react-dialog/@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.4", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA=="],
+
+ "cmdk/@radix-ui/react-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
+ }
+}
diff --git a/challenges/Core29.pdf b/challenges/Core29.pdf
deleted file mode 100644
index aa1a246..0000000
Binary files a/challenges/Core29.pdf and /dev/null differ
diff --git a/challenges/README.md b/challenges/README.md
deleted file mode 100644
index 7b3ccca..0000000
--- a/challenges/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-### Good Luck! π
-#### If you have any questions about the challenges ask the Sponsors for some expert advice or grab a Lecturer or CompSoc Member
diff --git a/challenges/RGUHack 2026 - Game Dev Presentation.pdf b/challenges/RGUHack 2026 - Game Dev Presentation.pdf
deleted file mode 100644
index a1e9dac..0000000
Binary files a/challenges/RGUHack 2026 - Game Dev Presentation.pdf and /dev/null differ
diff --git a/challenges/SOCET.pdf b/challenges/SOCET.pdf
deleted file mode 100644
index 897e1ca..0000000
Binary files a/challenges/SOCET.pdf and /dev/null differ
diff --git a/challenges/SalusTechnical.pdf b/challenges/SalusTechnical.pdf
deleted file mode 100644
index de40284..0000000
Binary files a/challenges/SalusTechnical.pdf and /dev/null differ
diff --git a/challenges/Sword.pdf b/challenges/Sword.pdf
deleted file mode 100644
index 962a350..0000000
Binary files a/challenges/Sword.pdf and /dev/null differ
diff --git a/components.json b/components.json
new file mode 100644
index 0000000..62e1011
--- /dev/null
+++ b/components.json
@@ -0,0 +1,20 @@
+{
+ "$schema": "https://ui.shadcn.com/schema.json",
+ "style": "default",
+ "rsc": false,
+ "tsx": true,
+ "tailwind": {
+ "config": "tailwind.config.ts",
+ "css": "src/index.css",
+ "baseColor": "slate",
+ "cssVariables": true,
+ "prefix": ""
+ },
+ "aliases": {
+ "components": "@/components",
+ "utils": "@/lib/utils",
+ "ui": "@/components/ui",
+ "lib": "@/lib",
+ "hooks": "@/hooks"
+ }
+}
diff --git a/docker-compose.local.yml b/docker-compose.local.yml
new file mode 100644
index 0000000..063ce41
--- /dev/null
+++ b/docker-compose.local.yml
@@ -0,0 +1,12 @@
+services:
+ liar:
+ build:
+ context: .
+ dockerfile: Dockerfile
+ ports:
+ - "8000:80"
+ restart: unless-stopped
+ networks:
+ default:
+ aliases:
+ - liar
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..1f8be60
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,16 @@
+services:
+ liar:
+ build:
+ context: .
+ dockerfile: Dockerfile
+ restart: unless-stopped
+ labels:
+ - "com.centurylinklabs.watchtower.enable=false"
+ networks:
+ default:
+ aliases:
+ - liar
+networks:
+ default:
+ name: zoraxy_proxy
+ external: true
diff --git a/eslint.config.js b/eslint.config.js
new file mode 100644
index 0000000..043a121
--- /dev/null
+++ b/eslint.config.js
@@ -0,0 +1,29 @@
+import js from "@eslint/js";
+import globals from "globals";
+import reactHooks from "eslint-plugin-react-hooks";
+import reactRefresh from "eslint-plugin-react-refresh";
+import tseslint from "typescript-eslint";
+
+export default tseslint.config(
+ { ignores: ["dist", ".vite"] },
+ {
+ extends: [js.configs.recommended, ...tseslint.configs.recommended],
+ files: ["**/*.{ts,tsx}"],
+ languageOptions: {
+ ecmaVersion: 2020,
+ globals: globals.browser,
+ },
+ plugins: {
+ "react-hooks": reactHooks,
+ "react-refresh": reactRefresh,
+ },
+ rules: {
+ ...reactHooks.configs.recommended.rules,
+ "react-refresh/only-export-components": [
+ "warn",
+ { allowConstantExport: true },
+ ],
+ "@typescript-eslint/no-unused-vars": "off",
+ },
+ },
+);
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..45e49a7
--- /dev/null
+++ b/index.html
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+ Liar, Cheater, Fired | Office Chaos Browser Game
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/nginx-main.conf b/nginx-main.conf
new file mode 100644
index 0000000..2a40e02
--- /dev/null
+++ b/nginx-main.conf
@@ -0,0 +1,20 @@
+worker_processes auto;
+
+error_log /dev/stderr notice;
+pid /tmp/nginx.pid;
+
+events {
+ worker_connections 1024;
+}
+
+http {
+ include /etc/nginx/mime.types;
+ default_type application/octet-stream;
+
+ access_log /dev/stdout;
+
+ sendfile on;
+ keepalive_timeout 65;
+
+ include /etc/nginx/conf.d/*.conf;
+}
diff --git a/nginx.conf b/nginx.conf
new file mode 100644
index 0000000..11cd89d
--- /dev/null
+++ b/nginx.conf
@@ -0,0 +1,14 @@
+server {
+ listen 80;
+ server_name _;
+
+ root /usr/share/nginx/html;
+ index index.html;
+
+ location / {
+ try_files $uri $uri/ /index.html;
+ }
+
+ error_page 404 /errorpage?code=404;
+ error_page 500 502 503 504 /errorpage?code=500;
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..f12f215
--- /dev/null
+++ b/package.json
@@ -0,0 +1,92 @@
+{
+ "name": "vite_react_shadcn_ts",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "build:dev": "vite build --mode development",
+ "lint": "eslint .",
+ "preview": "vite preview",
+ "test": "vitest run",
+ "test:watch": "vitest"
+ },
+ "dependencies": {
+ "@hookform/resolvers": "^5.2.2",
+ "@radix-ui/react-accordion": "^1.2.12",
+ "@radix-ui/react-alert-dialog": "^1.1.15",
+ "@radix-ui/react-aspect-ratio": "^1.1.8",
+ "@radix-ui/react-avatar": "^1.1.11",
+ "@radix-ui/react-checkbox": "^1.3.3",
+ "@radix-ui/react-collapsible": "^1.1.12",
+ "@radix-ui/react-context-menu": "^2.2.16",
+ "@radix-ui/react-dialog": "^1.1.15",
+ "@radix-ui/react-dropdown-menu": "^2.1.16",
+ "@radix-ui/react-hover-card": "^1.1.15",
+ "@radix-ui/react-label": "^2.1.8",
+ "@radix-ui/react-menubar": "^1.1.16",
+ "@radix-ui/react-navigation-menu": "^1.2.14",
+ "@radix-ui/react-popover": "^1.1.15",
+ "@radix-ui/react-progress": "^1.1.8",
+ "@radix-ui/react-radio-group": "^1.3.8",
+ "@radix-ui/react-scroll-area": "^1.2.10",
+ "@radix-ui/react-select": "^2.2.6",
+ "@radix-ui/react-separator": "^1.1.8",
+ "@radix-ui/react-slider": "^1.3.6",
+ "@radix-ui/react-slot": "^1.2.4",
+ "@radix-ui/react-switch": "^1.2.6",
+ "@radix-ui/react-tabs": "^1.1.13",
+ "@radix-ui/react-toast": "^1.2.15",
+ "@radix-ui/react-toggle": "^1.1.10",
+ "@radix-ui/react-toggle-group": "^1.1.11",
+ "@radix-ui/react-tooltip": "^1.2.8",
+ "@tanstack/react-query": "^5.90.21",
+ "browserslist": "^4.28.1",
+ "caniuse-lite": "^1.0.30001775",
+ "class-variance-authority": "^0.7.1",
+ "clsx": "^2.1.1",
+ "cmdk": "^1.1.1",
+ "date-fns": "^4.1.0",
+ "embla-carousel-react": "^8.6.0",
+ "input-otp": "^1.4.2",
+ "lucide-react": "^0.575.0",
+ "next-themes": "^0.4.6",
+ "react": "^19.2.4",
+ "react-day-picker": "^9.14.0",
+ "react-dom": "^19.2.4",
+ "react-hook-form": "^7.71.2",
+ "react-resizable-panels": "^4.7.0",
+ "react-router-dom": "^7.13.1",
+ "recharts": "^3.7.0",
+ "sonner": "^2.0.7",
+ "tailwind-merge": "^3.5.0",
+ "tailwindcss-animate": "^1.0.7",
+ "vaul": "^1.1.2",
+ "zod": "^4.3.6"
+ },
+ "devDependencies": {
+ "@eslint/js": "^10.0.1",
+ "@tailwindcss/postcss": "^4.2.1",
+ "@tailwindcss/typography": "^0.5.19",
+ "@testing-library/jest-dom": "^6.9.1",
+ "@testing-library/react": "^16.3.2",
+ "@types/node": "^25.3.3",
+ "@types/react": "^19.2.14",
+ "@types/react-dom": "^19.2.3",
+ "@vitejs/plugin-react-swc": "^4.2.3",
+ "autoprefixer": "^10.4.27",
+ "eslint": "^10.0.2",
+ "eslint-plugin-react-hooks": "^7.0.1",
+ "eslint-plugin-react-refresh": "^0.5.2",
+ "globals": "^17.4.0",
+ "jsdom": "^28.1.0",
+ "postcss": "^8.5.6",
+ "tailwindcss": "^4.2.1",
+ "typescript": "^5.9.3",
+ "typescript-eslint": "^8.56.1",
+ "vite": "^7.3.1",
+ "vite-plugin-compression": "^0.5.1",
+ "vitest": "^4.0.18"
+ }
+}
diff --git a/postcss.config.js b/postcss.config.js
new file mode 100644
index 0000000..c2ddf74
--- /dev/null
+++ b/postcss.config.js
@@ -0,0 +1,5 @@
+export default {
+ plugins: {
+ "@tailwindcss/postcss": {},
+ },
+};
diff --git a/public/background.mp3 b/public/background.mp3
new file mode 100644
index 0000000..fdc2d12
Binary files /dev/null and b/public/background.mp3 differ
diff --git a/public/background.png b/public/background.png
new file mode 100644
index 0000000..f20e6f9
Binary files /dev/null and b/public/background.png differ
diff --git a/public/boss-baby.jpeg b/public/boss-baby.jpeg
new file mode 100644
index 0000000..9775b4c
Binary files /dev/null and b/public/boss-baby.jpeg differ
diff --git a/public/cats.gif b/public/cats.gif
new file mode 100644
index 0000000..1c235d8
Binary files /dev/null and b/public/cats.gif differ
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000..423fadd
Binary files /dev/null and b/public/favicon.ico differ
diff --git a/public/favicon.png b/public/favicon.png
new file mode 100644
index 0000000..3f9aa8c
Binary files /dev/null and b/public/favicon.png differ
diff --git a/public/marty.jpeg b/public/marty.jpeg
new file mode 100644
index 0000000..3b3d166
Binary files /dev/null and b/public/marty.jpeg differ
diff --git a/public/minecraft.jpg b/public/minecraft.jpg
new file mode 100644
index 0000000..03d4980
Binary files /dev/null and b/public/minecraft.jpg differ
diff --git a/public/pingpongpaddle.jpeg b/public/pingpongpaddle.jpeg
new file mode 100644
index 0000000..6764be1
Binary files /dev/null and b/public/pingpongpaddle.jpeg differ
diff --git a/public/robots.txt b/public/robots.txt
new file mode 100644
index 0000000..93baa20
--- /dev/null
+++ b/public/robots.txt
@@ -0,0 +1,4 @@
+User-agent: *
+Allow: /
+Host: https://liar.armandev.co.uk
+Sitemap: https://liar.armandev.co.uk/sitemap.xml
diff --git a/public/sitemap.xml b/public/sitemap.xml
new file mode 100644
index 0000000..c3e03a7
--- /dev/null
+++ b/public/sitemap.xml
@@ -0,0 +1,9 @@
+
+
+
+ https://liar.armandev.co.uk/
+ 2026-03-04
+ weekly
+ 1.0
+
+
diff --git a/public/sword.jpeg b/public/sword.jpeg
new file mode 100644
index 0000000..c1a3621
Binary files /dev/null and b/public/sword.jpeg differ
diff --git a/public/words.txt b/public/words.txt
new file mode 100644
index 0000000..549435c
--- /dev/null
+++ b/public/words.txt
@@ -0,0 +1,14855 @@
+aahed
+aalii
+aapas
+aargh
+aarti
+abaca
+abaci
+aback
+abacs
+abaft
+abaht
+abaka
+abamp
+aband
+abase
+abash
+abask
+abate
+abaya
+abbas
+abbed
+abbes
+abbey
+abbot
+abcee
+abeam
+abear
+abeat
+abeer
+abele
+abeng
+abers
+abets
+abeys
+abhor
+abide
+abies
+abius
+abjad
+abjud
+abled
+abler
+ables
+ablet
+ablow
+abmho
+abnet
+abode
+abohm
+aboil
+aboma
+aboon
+abord
+abore
+aborn
+abort
+about
+above
+abram
+abray
+abrim
+abrin
+abris
+absey
+absit
+abuna
+abune
+abura
+aburn
+abuse
+abuts
+abuzz
+abyes
+abysm
+abyss
+acais
+acara
+acari
+accas
+accha
+accoy
+accra
+acedy
+acene
+acerb
+acers
+aceta
+achar
+ached
+acher
+aches
+achey
+achoo
+acids
+acidy
+acies
+acing
+acini
+ackee
+acker
+acmes
+acmic
+acned
+acnes
+acock
+acoel
+acold
+acone
+acorn
+acral
+acred
+acres
+acrid
+acron
+acros
+acryl
+actas
+acted
+actin
+acton
+actor
+actus
+acute
+acyls
+adage
+adapt
+adats
+adawn
+adaws
+adays
+adbot
+addas
+addax
+added
+adder
+addin
+addio
+addle
+addra
+adead
+adeem
+adept
+adhan
+adhoc
+adieu
+adios
+adits
+adlib
+adman
+admen
+admin
+admit
+admix
+adnex
+adobe
+adobo
+adoon
+adopt
+adorb
+adore
+adorn
+adown
+adoze
+adrad
+adraw
+adred
+adret
+adrip
+adsum
+aduki
+adult
+adunc
+adust
+advew
+advts
+adyta
+adyts
+adzed
+adzes
+aecia
+aedes
+aeger
+aegis
+aeons
+aerie
+aeros
+aesir
+aevum
+afald
+afanc
+afara
+afars
+afear
+affix
+affly
+afion
+afire
+afizz
+aflaj
+aflap
+aflow
+afoam
+afoot
+afore
+afoul
+afret
+afrit
+afros
+after
+aftos
+again
+agals
+agama
+agami
+agamy
+agape
+agars
+agasp
+agast
+agate
+agaty
+agave
+agaze
+agbas
+agene
+agent
+agers
+aggag
+agger
+aggie
+aggri
+aggro
+aggry
+aghas
+agidi
+agila
+agile
+aging
+agios
+agism
+agist
+agita
+aglee
+aglet
+agley
+agloo
+aglow
+aglus
+agmas
+agoge
+agogo
+agone
+agons
+agony
+agood
+agora
+agree
+agria
+agrin
+agros
+agrum
+agued
+agues
+aguey
+aguna
+agush
+aguti
+ahead
+aheap
+ahent
+ahigh
+ahind
+ahing
+ahint
+ahold
+ahole
+ahull
+ahuru
+aidas
+aided
+aider
+aides
+aidoi
+aidos
+aiery
+aigas
+aight
+ailed
+aimag
+aimak
+aimed
+aimer
+ainee
+ainga
+aioli
+aired
+airer
+airns
+airth
+airts
+aisle
+aitch
+aitus
+aiver
+aixes
+aiyah
+aiyee
+aiyoh
+aiyoo
+aizle
+ajies
+ajiva
+ajuga
+ajupa
+ajwan
+akara
+akees
+akela
+akene
+aking
+akita
+akkas
+akker
+akoia
+akoja
+akoya
+aksed
+akses
+alaap
+alack
+alala
+alamo
+aland
+alane
+alang
+alans
+alant
+alapa
+alaps
+alarm
+alary
+alata
+alate
+alays
+albas
+albee
+albid
+album
+alcea
+alces
+alcid
+alcos
+aldea
+alder
+aldol
+aleak
+aleck
+alecs
+aleem
+alefs
+aleft
+aleph
+alert
+alews
+aleye
+alfas
+algae
+algal
+algas
+algid
+algin
+algor
+algos
+algum
+alias
+alibi
+alick
+alien
+alifs
+align
+alike
+alims
+aline
+alios
+alist
+alive
+aliya
+alkie
+alkin
+alkos
+alkyd
+alkyl
+allan
+allay
+allee
+allel
+allen
+aller
+alley
+allin
+allis
+allod
+allot
+allow
+alloy
+allus
+allyl
+almah
+almas
+almeh
+almes
+almud
+almug
+alods
+aloed
+aloes
+aloft
+aloha
+aloin
+alone
+along
+aloof
+aloos
+alose
+aloud
+alowe
+alpha
+altar
+alter
+altho
+altos
+alula
+alums
+alumy
+alure
+alurk
+alvar
+alway
+amahs
+amain
+amari
+amaro
+amass
+amate
+amaut
+amaze
+amban
+amber
+ambit
+amble
+ambos
+ambry
+ameba
+ameer
+amend
+amene
+amens
+ament
+amias
+amice
+amici
+amide
+amido
+amids
+amies
+amiga
+amigo
+amine
+amino
+amins
+amirs
+amiss
+amity
+amlas
+amman
+ammas
+ammon
+ammos
+amnia
+amnic
+amnio
+amoks
+amole
+among
+amore
+amort
+amour
+amove
+amowt
+amped
+ample
+amply
+ampul
+amrit
+amuck
+amuse
+amyls
+anana
+anata
+ancho
+ancle
+ancon
+andic
+andro
+anear
+anele
+anent
+angas
+angel
+anger
+angle
+anglo
+angry
+angst
+anigh
+anile
+anils
+anima
+anime
+animi
+anion
+anise
+anker
+ankhs
+ankle
+ankus
+anlas
+annal
+annan
+annas
+annat
+annex
+annoy
+annul
+annum
+annus
+anoas
+anode
+anole
+anomy
+ansae
+ansas
+antae
+antar
+antas
+anted
+antes
+antic
+antis
+antra
+antre
+antsy
+anura
+anvil
+anyon
+aorta
+apace
+apage
+apaid
+apart
+apayd
+apays
+apeak
+apeek
+apers
+apert
+apery
+apgar
+aphid
+aphis
+apian
+aping
+apiol
+apish
+apism
+apnea
+apode
+apods
+apols
+apoop
+aport
+appal
+appam
+appay
+appel
+apple
+apply
+appro
+appts
+appui
+appuy
+apres
+apron
+apses
+apsis
+apsos
+apted
+apter
+aptly
+aquae
+aquas
+araba
+araks
+arame
+arars
+arbah
+arbas
+arbor
+arced
+archi
+arcos
+arcus
+ardeb
+ardor
+ardri
+aread
+areae
+areal
+arear
+areas
+areca
+aredd
+arede
+arefy
+areic
+arena
+arene
+arepa
+arere
+arete
+arets
+arett
+argal
+argan
+argil
+argle
+argol
+argon
+argot
+argue
+argus
+arhat
+arias
+ariel
+ariki
+arils
+ariot
+arise
+arish
+arith
+arked
+arled
+arles
+armed
+armer
+armet
+armil
+armor
+arnas
+arnis
+arnut
+aroba
+aroha
+aroid
+aroma
+arose
+arpas
+arpen
+arrah
+arras
+array
+arret
+arris
+arrow
+arroz
+arsed
+arses
+arsey
+arsis
+arson
+artal
+artel
+arter
+artic
+artis
+artly
+artsy
+aruhe
+arums
+arval
+arvee
+arvos
+aryls
+asada
+asana
+ascon
+ascot
+ascus
+asdic
+ashed
+ashen
+ashes
+ashet
+aside
+asity
+askar
+asked
+asker
+askew
+askoi
+askos
+aspen
+asper
+aspic
+aspie
+aspis
+aspro
+assai
+assam
+assay
+assed
+asses
+asset
+assez
+assot
+aster
+astir
+astun
+asura
+asway
+aswim
+asyla
+ataps
+ataxy
+atigi
+atilt
+atimy
+atlas
+atman
+atmas
+atmos
+atocs
+atoke
+atoks
+atoll
+atoms
+atomy
+atone
+atony
+atopy
+atria
+atrip
+attap
+attar
+attas
+atter
+attic
+atuas
+aucht
+audad
+audax
+audio
+audit
+augen
+auger
+auges
+aught
+augur
+aulas
+aulic
+auloi
+aulos
+aumil
+aunes
+aunts
+aunty
+aurae
+aural
+aurar
+auras
+aurei
+aures
+auric
+auris
+aurum
+autos
+auxin
+avail
+avale
+avant
+avast
+avels
+avens
+avers
+avert
+avgas
+avian
+avine
+avion
+avise
+aviso
+avize
+avoid
+avows
+avyze
+await
+awake
+award
+aware
+awari
+awarn
+awash
+awato
+awave
+aways
+awdls
+aweel
+aweto
+awful
+awing
+awkin
+awmry
+awned
+awner
+awoke
+awols
+awork
+axels
+axial
+axile
+axils
+axing
+axiom
+axion
+axite
+axled
+axles
+axman
+axmen
+axoid
+axone
+axons
+ayahs
+ayaya
+ayelp
+aygre
+ayins
+aymag
+ayont
+ayres
+ayrie
+azans
+azide
+azido
+azine
+azlon
+azoic
+azole
+azons
+azote
+azoth
+azuki
+azure
+azurn
+azury
+azygy
+azyme
+azyms
+baaed
+baals
+baaps
+babas
+babby
+babel
+babes
+babka
+baboo
+babul
+babus
+bacca
+bacco
+baccy
+bacha
+bachs
+backs
+backy
+bacne
+bacon
+badam
+baddy
+badge
+badly
+baels
+baffs
+baffy
+bafta
+bafts
+bagel
+baggy
+baghs
+bagie
+bagsy
+bagua
+bahts
+bahus
+bahut
+baiks
+baile
+bails
+bairn
+baisa
+baith
+baits
+baiza
+baize
+bajan
+bajra
+bajri
+bajus
+baked
+baken
+baker
+bakes
+bakra
+balas
+balds
+baldy
+baled
+baler
+bales
+balks
+balky
+ballo
+balls
+bally
+balms
+balmy
+baloi
+balon
+baloo
+balot
+balsa
+balti
+balun
+balus
+balut
+bamas
+bambi
+bamma
+bammy
+banak
+banal
+banco
+bancs
+banda
+bandh
+bands
+bandy
+baned
+banes
+bangs
+bania
+banjo
+banks
+banky
+banns
+bants
+bantu
+banty
+bantz
+banya
+baons
+baozi
+bappu
+bapus
+barbe
+barbs
+barby
+barca
+barde
+bardo
+bards
+bardy
+bared
+barer
+bares
+barfi
+barfs
+barfy
+barge
+baric
+barks
+barky
+barms
+barmy
+barns
+barny
+baron
+barps
+barra
+barre
+barro
+barry
+barye
+basal
+basan
+basas
+based
+basen
+baser
+bases
+basha
+basho
+basic
+basij
+basil
+basin
+basis
+basks
+bason
+basse
+bassi
+basso
+bassy
+basta
+baste
+basti
+basto
+basts
+batch
+bated
+bates
+bathe
+baths
+batik
+baton
+batos
+batta
+batts
+battu
+batty
+bauds
+bauks
+baulk
+baurs
+bavin
+bawds
+bawdy
+bawks
+bawls
+bawns
+bawrs
+bawty
+bayas
+bayed
+bayer
+bayes
+bayle
+bayou
+bayts
+bazar
+bazas
+bazoo
+bball
+bdays
+beach
+beads
+beady
+beaks
+beaky
+beals
+beams
+beamy
+beano
+beans
+beany
+beard
+beare
+bears
+beast
+beath
+beats
+beaty
+beaus
+beaut
+beaux
+bebop
+becap
+becke
+becks
+bedad
+bedel
+bedes
+bedew
+bedim
+bedye
+beech
+beedi
+beefs
+beefy
+beeps
+beers
+beery
+beets
+befit
+befog
+begad
+began
+begar
+begat
+begem
+beget
+begin
+begob
+begot
+begum
+begun
+beige
+beigy
+being
+beins
+beira
+beisa
+bekah
+belah
+belar
+belay
+belch
+belee
+belga
+belie
+belit
+belle
+belli
+bello
+bells
+belly
+belon
+below
+belts
+belve
+bemad
+bemas
+bemix
+bemud
+bench
+bends
+bendy
+benes
+benet
+benga
+benis
+benji
+benne
+benni
+benny
+bento
+bents
+benty
+bepat
+beray
+beres
+beret
+bergs
+berko
+berks
+berme
+berms
+berob
+berry
+berth
+beryl
+besat
+besaw
+besee
+beses
+beset
+besit
+besom
+besot
+besti
+bests
+betas
+beted
+betel
+betes
+beths
+betid
+beton
+betta
+betty
+bevan
+bevel
+bever
+bevor
+bevue
+bevvy
+bewdy
+bewet
+bewig
+bezel
+bezes
+bezil
+bezzy
+bhais
+bhaji
+bhang
+bhats
+bhava
+bhels
+bhoot
+bhuna
+bhuts
+biach
+biali
+bialy
+bibbs
+bibes
+bibis
+bible
+biccy
+bicep
+bices
+bicky
+biddy
+bided
+bider
+bides
+bidet
+bidis
+bidon
+bidri
+bield
+biers
+biffo
+biffs
+biffy
+bifid
+bigae
+biggs
+biggy
+bigha
+bight
+bigly
+bigos
+bigot
+bihon
+bijou
+biked
+biker
+bikes
+bikie
+bikky
+bilal
+bilat
+bilbo
+bilby
+biled
+biles
+bilge
+bilgy
+bilks
+bills
+billy
+bimah
+bimas
+bimbo
+binal
+bindi
+binds
+biner
+bines
+binge
+bingo
+bings
+bingy
+binit
+binks
+binky
+bints
+biogs
+biome
+bions
+biont
+biose
+biota
+biped
+bipod
+bippy
+birch
+birdo
+birds
+biris
+birks
+birle
+birls
+biros
+birrs
+birse
+birsy
+birth
+birze
+birzz
+bises
+bisks
+bisom
+bison
+bitch
+biter
+bites
+bitey
+bitos
+bitou
+bitsy
+bitte
+bitts
+bitty
+bivia
+bivvy
+bizes
+bizzo
+bizzy
+blabs
+black
+blade
+blads
+blady
+blaer
+blaes
+blaff
+blags
+blahs
+blain
+blame
+blams
+blanc
+bland
+blank
+blare
+blart
+blase
+blash
+blast
+blate
+blats
+blatt
+blaud
+blawn
+blaws
+blays
+blaze
+bleah
+bleak
+blear
+bleat
+blebs
+blech
+bleed
+bleep
+blees
+blend
+blent
+blert
+bless
+blest
+blets
+bleys
+blimp
+blimy
+blind
+bling
+blini
+blink
+blins
+bliny
+blips
+bliss
+blist
+blite
+blits
+blitz
+blive
+bloat
+blobs
+block
+blocs
+blogs
+bloke
+blond
+blonx
+blood
+blook
+bloom
+bloop
+blore
+blots
+blown
+blows
+blowy
+blubs
+blude
+bluds
+bludy
+blued
+bluer
+blues
+bluet
+bluey
+bluff
+bluid
+blume
+blunk
+blunt
+blurb
+blurs
+blurt
+blush
+blype
+boabs
+boaks
+board
+boars
+boart
+boast
+boats
+boaty
+bobac
+bobak
+bobas
+bobby
+bobol
+bobos
+bocca
+bocce
+bocci
+boche
+bocks
+boded
+bodes
+bodge
+bodgy
+bodhi
+bodle
+bodoh
+boeps
+boers
+boeti
+boets
+boeuf
+boffo
+boffs
+bogan
+bogey
+boggy
+bogie
+bogle
+bogue
+bogus
+bohea
+bohos
+boils
+boing
+boink
+boite
+boked
+bokeh
+bokes
+bokos
+bolar
+bolas
+boldo
+bolds
+boles
+bolet
+bolix
+bolks
+bolls
+bolos
+bolts
+bolus
+bomas
+bombe
+bombo
+bombs
+bomoh
+bomor
+bonce
+bonds
+boned
+boner
+bones
+boney
+bongo
+bongs
+bonie
+bonks
+bonne
+bonny
+bonum
+bonus
+bonza
+bonze
+booai
+booay
+boobs
+booby
+boody
+booed
+boofy
+boogy
+boohs
+books
+booky
+bools
+booms
+boomy
+boong
+boons
+boord
+boors
+boose
+boost
+booth
+boots
+booty
+booze
+boozy
+boppy
+borak
+boral
+boras
+borax
+borde
+bords
+bored
+boree
+borek
+borel
+borer
+bores
+borgo
+boric
+borks
+borms
+borna
+borne
+boron
+borts
+borty
+bortz
+bosey
+bosie
+bosks
+bosky
+bosom
+boson
+bossa
+bossy
+bosun
+botas
+botch
+boteh
+botel
+botes
+botew
+bothy
+botos
+botte
+botts
+botty
+bouge
+bough
+bouks
+boule
+boult
+bound
+bouns
+bourd
+bourg
+bourn
+bouse
+bousy
+bouts
+boutu
+bovid
+bowat
+bowed
+bowel
+bower
+bowes
+bowet
+bowie
+bowls
+bowne
+bowrs
+bowse
+boxed
+boxen
+boxer
+boxes
+boxla
+boxty
+boyar
+boyau
+boyed
+boyey
+boyfs
+boygs
+boyla
+boyly
+boyos
+boysy
+bozos
+braai
+brace
+brach
+brack
+bract
+brads
+braes
+brags
+brahs
+braid
+brail
+brain
+brake
+braks
+braky
+brame
+brand
+brane
+brank
+brans
+brant
+brash
+brass
+brast
+brats
+brava
+brave
+bravi
+bravo
+brawl
+brawn
+braws
+braxy
+brays
+braza
+braze
+bread
+break
+bream
+brede
+breds
+breed
+breem
+breer
+brees
+breid
+breis
+breme
+brens
+brent
+brere
+brers
+breve
+brews
+breys
+briar
+bribe
+brick
+bride
+brief
+brier
+bries
+brigs
+briki
+briks
+brill
+brims
+brine
+bring
+brink
+brins
+briny
+brios
+brise
+brisk
+briss
+brith
+brits
+britt
+brize
+broad
+broch
+brock
+brods
+brogh
+brogs
+broil
+broke
+brome
+bromo
+bronc
+brond
+brood
+brook
+brool
+broom
+broos
+brose
+brosy
+broth
+brown
+brows
+bruck
+brugh
+bruhs
+bruin
+bruit
+bruja
+brujo
+brule
+brume
+brung
+brunt
+brush
+brusk
+brust
+brute
+bruts
+bruvs
+buats
+buaze
+bubal
+bubas
+bubba
+bubbe
+bubby
+bubus
+buchu
+bucko
+bucks
+bucku
+budas
+buddy
+buded
+budes
+budge
+budis
+budos
+buena
+buffa
+buffe
+buffi
+buffo
+buffs
+buffy
+bufos
+bufty
+bugan
+buggy
+bugle
+buhls
+buhrs
+buiks
+build
+built
+buist
+bukes
+bukos
+bulbs
+bulge
+bulgy
+bulks
+bulky
+bulla
+bulls
+bully
+bulse
+bumbo
+bumfs
+bumph
+bumps
+bumpy
+bunas
+bunce
+bunch
+bunco
+bunde
+bundh
+bunds
+bundt
+bundu
+bundy
+bungs
+bungy
+bunia
+bunje
+bunjy
+bunko
+bunks
+bunns
+bunny
+bunts
+bunty
+bunya
+buoys
+buppy
+buran
+buras
+burbs
+burds
+buret
+burfi
+burgh
+burgs
+burin
+burka
+burke
+burks
+burls
+burly
+burns
+burnt
+buroo
+burps
+burqa
+burra
+burro
+burrs
+burry
+bursa
+burse
+burst
+busby
+bused
+buses
+bushy
+busks
+busky
+bussu
+busti
+busts
+busty
+butch
+buteo
+butes
+butle
+butoh
+butte
+butts
+butty
+butut
+butyl
+buxom
+buyer
+buyin
+buzzy
+bwana
+bwazi
+byded
+bydes
+byked
+bykes
+bylaw
+byres
+byrls
+byssi
+bytes
+byway
+caaed
+cabal
+cabas
+cabby
+caber
+cabin
+cable
+cabob
+caboc
+cabre
+cacao
+cacas
+cache
+cacks
+cacky
+cacti
+caddy
+cadee
+cades
+cadet
+cadge
+cadgy
+cadie
+cadis
+cadre
+caeca
+caese
+cafes
+caffe
+caffs
+caged
+cager
+cages
+cagey
+cagot
+cahow
+caids
+cains
+caird
+cairn
+cajon
+cajun
+caked
+cakes
+cakey
+calfs
+calid
+calif
+calix
+calks
+calla
+calle
+calls
+calms
+calmy
+calos
+calpa
+calps
+calve
+calyx
+caman
+camas
+camel
+cameo
+cames
+camis
+camos
+campi
+campo
+camps
+campy
+camus
+canal
+cando
+candy
+caned
+caneh
+caner
+canes
+cangs
+canid
+canna
+canns
+canny
+canoe
+canon
+canso
+canst
+canti
+canto
+cants
+canty
+capas
+capax
+caped
+caper
+capes
+capex
+caphs
+capiz
+caple
+capon
+capos
+capot
+capri
+capul
+caput
+carap
+carat
+carbo
+carbs
+carby
+cardi
+cards
+cardy
+cared
+carer
+cares
+caret
+carex
+cargo
+carks
+carle
+carls
+carne
+carns
+carny
+carob
+carol
+carom
+caron
+carpe
+carpi
+carps
+carrs
+carry
+carse
+carta
+carte
+carts
+carve
+carvy
+casas
+casco
+cased
+caser
+cases
+casks
+casky
+caste
+casts
+casus
+catch
+cater
+cates
+catty
+cauda
+cauks
+cauld
+caulk
+cauls
+caums
+caups
+cauri
+causa
+cause
+cavas
+caved
+cavel
+caver
+caves
+cavie
+cavil
+cavus
+cawed
+cawks
+caxon
+cease
+ceaze
+cebid
+cecal
+cecum
+cedar
+ceded
+ceder
+cedes
+cedis
+ceiba
+ceili
+ceils
+celeb
+cella
+celli
+cello
+cells
+celly
+celom
+celts
+cense
+cento
+cents
+centu
+ceorl
+cepes
+cerci
+cered
+ceres
+cerge
+ceria
+ceric
+cerne
+ceroc
+ceros
+certs
+certy
+cesse
+cesta
+cesti
+cetes
+cetyl
+cezve
+chaap
+chaat
+chace
+chack
+chaco
+chado
+chads
+chafe
+chaff
+chaft
+chain
+chair
+chais
+chalk
+chals
+champ
+chams
+chana
+chang
+chank
+chant
+chaos
+chape
+chaps
+chapt
+chara
+chard
+chare
+chark
+charm
+charr
+chars
+chart
+chary
+chase
+chasm
+chats
+chava
+chave
+chavs
+chawk
+chawl
+chaws
+chaya
+chays
+cheap
+cheat
+cheba
+check
+chedi
+cheeb
+cheek
+cheep
+cheer
+cheet
+chefs
+cheka
+chela
+chelp
+chemo
+chems
+chere
+chert
+chess
+chest
+cheth
+chevy
+chews
+chewy
+chiao
+chias
+chiba
+chibs
+chica
+chich
+chick
+chico
+chics
+chide
+chief
+chiel
+chiko
+chiks
+child
+chile
+chili
+chill
+chimb
+chime
+chimo
+chimp
+china
+chine
+ching
+chink
+chino
+chins
+chips
+chirk
+chirl
+chirm
+chiro
+chirp
+chirr
+chirt
+chiru
+chiti
+chits
+chiva
+chive
+chivs
+chivy
+chizz
+chock
+choco
+chocs
+chode
+chogs
+choil
+choir
+choke
+choko
+choky
+chola
+choli
+cholo
+chomp
+chons
+choof
+chook
+choom
+choon
+chops
+chord
+chore
+chose
+choss
+chota
+chott
+chout
+choux
+chowk
+chows
+chubs
+chuck
+chufa
+chuff
+chugs
+chump
+chums
+chunk
+churl
+churn
+churr
+chuse
+chute
+chuts
+chyle
+chyme
+chynd
+cibol
+cided
+cider
+cides
+ciels
+cigar
+ciggy
+cilia
+cills
+cimar
+cimex
+cinch
+cinct
+cines
+cinqs
+cions
+cippi
+circa
+circs
+cires
+cirls
+cirri
+cisco
+cissy
+cists
+cital
+cited
+citee
+citer
+cites
+cives
+civet
+civic
+civie
+civil
+civvy
+clach
+clack
+clade
+clads
+claes
+clags
+claim
+clair
+clame
+clamp
+clams
+clang
+clank
+clans
+claps
+clapt
+claro
+clart
+clary
+clash
+clasp
+class
+clast
+clats
+claut
+clave
+clavi
+claws
+clays
+clean
+clear
+cleat
+cleck
+cleek
+cleep
+clefs
+cleft
+clegs
+cleik
+clems
+clepe
+clept
+clerk
+cleve
+clews
+click
+clied
+clies
+cliff
+clift
+climb
+clime
+cline
+cling
+clink
+clint
+clipe
+clips
+clipt
+clits
+cloak
+cloam
+clock
+clods
+cloff
+clogs
+cloke
+clomb
+clomp
+clone
+clonk
+clons
+cloop
+cloot
+clops
+close
+clote
+cloth
+clots
+cloud
+clour
+clous
+clout
+clove
+clown
+clows
+cloye
+cloys
+cloze
+clubs
+cluck
+clued
+clues
+cluey
+clump
+clung
+clunk
+clype
+cnida
+coach
+coact
+coady
+coala
+coals
+coaly
+coapt
+coarb
+coast
+coate
+coati
+coats
+cobbs
+cobby
+cobia
+coble
+cobot
+cobra
+cobza
+cocas
+cocci
+cocco
+cocks
+cocky
+cocoa
+cocos
+cocus
+codas
+codec
+coded
+coden
+coder
+codes
+codex
+codon
+coeds
+coffs
+cogie
+cogon
+cogue
+cohab
+cohen
+cohoe
+cohog
+cohos
+coifs
+coign
+coils
+coins
+coirs
+coits
+coked
+cokes
+cokey
+colas
+colby
+colds
+coled
+coles
+coley
+colic
+colin
+colle
+colls
+colly
+colog
+colon
+color
+colts
+colza
+comae
+comal
+comas
+combe
+combi
+combo
+combs
+comby
+comer
+comes
+comet
+comfy
+comic
+comix
+comma
+comme
+commo
+comms
+commy
+compo
+comps
+compt
+comte
+comus
+conch
+condo
+coned
+cones
+conex
+coney
+confs
+conga
+conge
+congo
+conia
+conic
+conin
+conks
+conky
+conne
+conns
+conte
+conto
+conus
+convo
+cooch
+cooed
+cooee
+cooer
+cooey
+coofs
+cooks
+cooky
+cools
+cooly
+coomb
+cooms
+coomy
+coons
+coops
+coopt
+coost
+coots
+cooty
+cooze
+copal
+copay
+coped
+copen
+coper
+copes
+copha
+coppy
+copra
+copse
+copsy
+coqui
+coral
+coram
+corbe
+corby
+corda
+cords
+cored
+corer
+cores
+corey
+corgi
+coria
+corks
+corky
+corms
+corni
+corno
+corns
+cornu
+corny
+corps
+corse
+corso
+cosec
+cosed
+coses
+coset
+cosey
+cosie
+costa
+coste
+costs
+cotan
+cotch
+coted
+cotes
+coths
+cotta
+cotts
+couch
+coude
+cough
+could
+count
+coupe
+coups
+courb
+courd
+coure
+cours
+court
+couta
+couth
+coved
+coven
+cover
+coves
+covet
+covey
+covin
+cowal
+cowan
+cowed
+cower
+cowks
+cowls
+cowps
+cowry
+coxae
+coxal
+coxed
+coxes
+coxib
+coyau
+coyed
+coyer
+coyly
+coypu
+cozed
+cozen
+cozes
+cozey
+cozie
+craal
+crabs
+crack
+craft
+crags
+craic
+craig
+crake
+crame
+cramp
+crams
+crane
+crank
+crans
+crape
+craps
+crapy
+crare
+crash
+crass
+crate
+crave
+crawl
+craws
+crays
+craze
+crazy
+creak
+cream
+credo
+creds
+creed
+creek
+creel
+creep
+crees
+crein
+crema
+creme
+crems
+crena
+crepe
+creps
+crept
+crepy
+cress
+crest
+crewe
+crews
+crias
+cribo
+cribs
+crick
+cried
+crier
+cries
+crime
+crimp
+crims
+crine
+crink
+crins
+crios
+cripe
+crips
+crise
+crisp
+criss
+crith
+crits
+croak
+croci
+crock
+crocs
+croft
+crogs
+cromb
+crome
+crone
+cronk
+crons
+crony
+crook
+crool
+croon
+crops
+crore
+cross
+crost
+croup
+crout
+crowd
+crowl
+crown
+crows
+croze
+cruck
+crude
+crudo
+cruds
+crudy
+cruel
+crues
+cruet
+cruft
+crumb
+crump
+crunk
+cruor
+crura
+cruse
+crush
+crust
+crusy
+cruve
+crwth
+cryer
+cryne
+crypt
+ctene
+cubby
+cubeb
+cubed
+cuber
+cubes
+cubic
+cubit
+cucks
+cudda
+cuddy
+cueca
+cuffo
+cuffs
+cuifs
+cuing
+cuish
+cuits
+cukes
+culch
+culet
+culex
+culls
+cully
+culms
+culpa
+culti
+cults
+culty
+cumec
+cumin
+cundy
+cunei
+cunit
+cunny
+cunts
+cupel
+cupid
+cuppa
+cuppy
+cupro
+curat
+curbs
+curch
+curds
+curdy
+cured
+curer
+cures
+curet
+curfs
+curia
+curie
+curio
+curli
+curls
+curly
+curns
+curny
+currs
+curry
+curse
+cursi
+curst
+curve
+curvy
+cusec
+cushy
+cusks
+cusps
+cuspy
+cusso
+cusum
+cutch
+cuter
+cutes
+cutey
+cutie
+cutin
+cutis
+cutto
+cutty
+cutup
+cuvee
+cuzes
+cwtch
+cyano
+cyans
+cyber
+cycad
+cycas
+cycle
+cyclo
+cyder
+cylix
+cymae
+cymar
+cymas
+cymes
+cymol
+cynic
+cysts
+cytes
+cyton
+czars
+daals
+dabba
+daces
+dacha
+dacks
+dadah
+dadas
+daddy
+dadis
+dadla
+dados
+daffs
+daffy
+dagga
+daggy
+dagos
+dahis
+dahls
+daiko
+daily
+daine
+daint
+dairy
+daisy
+daker
+daled
+dalek
+dales
+dalis
+dalle
+dally
+dalts
+daman
+damar
+dames
+damme
+damna
+damns
+damps
+dampy
+dance
+dancy
+danda
+dandy
+dangs
+danio
+danks
+danny
+danse
+dants
+dappy
+daraf
+darbs
+darcy
+dared
+darer
+dares
+darga
+dargs
+daric
+daris
+darks
+darky
+darls
+darns
+darre
+darts
+darzi
+dashi
+dashy
+datal
+dated
+dater
+dates
+datil
+datos
+datto
+datum
+daube
+daubs
+dauby
+dauds
+dault
+daunt
+daurs
+dauts
+daven
+davit
+dawah
+dawds
+dawed
+dawen
+dawgs
+dawks
+dawns
+dawts
+dayal
+dayan
+daych
+daynt
+dazed
+dazer
+dazes
+dbags
+deads
+deair
+deals
+dealt
+deans
+deare
+dearn
+dears
+deary
+deash
+death
+deave
+deaws
+deawy
+debag
+debar
+debby
+debel
+debes
+debit
+debts
+debud
+debug
+debur
+debus
+debut
+debye
+decad
+decaf
+decal
+decan
+decay
+decim
+decko
+decks
+decor
+decos
+decoy
+decry
+decyl
+dedal
+deeds
+deedy
+deely
+deems
+deens
+deeps
+deere
+deers
+deets
+deeve
+deevs
+defat
+defer
+deffo
+defis
+defog
+degas
+degum
+degus
+deice
+deids
+deify
+deign
+deils
+deink
+deism
+deist
+deity
+deked
+dekes
+dekko
+delay
+deled
+deles
+delfs
+delft
+delis
+della
+dells
+delly
+delos
+delph
+delta
+delts
+delve
+deman
+demes
+demic
+demit
+demob
+demoi
+demon
+demos
+demot
+dempt
+demur
+denar
+denay
+dench
+denes
+denet
+denim
+denis
+dense
+dente
+dents
+deoch
+deoxy
+depot
+depth
+derat
+deray
+derby
+dered
+deres
+derig
+derma
+derms
+derns
+derny
+deros
+derpy
+derro
+derry
+derth
+dervs
+desex
+deshi
+desis
+desks
+desse
+detag
+deter
+detox
+deuce
+devas
+devel
+devil
+devis
+devon
+devos
+devot
+dewan
+dewar
+dewax
+dewed
+dexes
+dexie
+dexys
+dhaba
+dhaks
+dhals
+dhikr
+dhobi
+dhole
+dholl
+dhols
+dhoni
+dhoti
+dhows
+dhuti
+diact
+dials
+diana
+diane
+diary
+diazo
+dibbs
+diced
+dicer
+dices
+dicey
+dicht
+dicks
+dicky
+dicot
+dicta
+dicto
+dicts
+dictu
+dicty
+diddy
+didie
+didis
+didos
+didst
+diebs
+diels
+diene
+diets
+diffs
+dight
+digit
+dikas
+diked
+diker
+dikes
+dikey
+dildo
+dilli
+dills
+dilly
+dimbo
+dimer
+dimes
+dimly
+dimps
+dinar
+dined
+diner
+dines
+dinge
+dingo
+dings
+dingy
+dinic
+dinks
+dinky
+dinlo
+dinna
+dinos
+dints
+dioch
+diode
+diols
+diota
+dippy
+dipso
+diram
+direr
+dirge
+dirke
+dirks
+dirls
+dirts
+dirty
+disas
+disci
+disco
+discs
+dishy
+disks
+disme
+dital
+ditas
+ditch
+dited
+dites
+ditsy
+ditto
+ditts
+ditty
+ditzy
+divan
+divas
+dived
+diver
+dives
+divey
+divis
+divna
+divos
+divot
+divvy
+diwan
+dixie
+dixit
+diyas
+dizen
+dizzy
+djinn
+djins
+doabs
+doats
+dobby
+dobes
+dobie
+dobla
+doble
+dobra
+dobro
+docht
+docks
+docos
+docus
+doddy
+dodge
+dodgy
+dodos
+doeks
+doers
+doest
+doeth
+doffs
+dogal
+dogan
+doges
+dogey
+doggo
+doggy
+dogie
+dogly
+dogma
+dohyo
+doilt
+doily
+doing
+doits
+dojos
+dolce
+dolci
+doled
+dolee
+doles
+doley
+dolia
+dolie
+dolls
+dolly
+dolma
+dolor
+dolos
+dolts
+domal
+domed
+domes
+domic
+donah
+donas
+donee
+doner
+donga
+dongs
+donko
+donna
+donne
+donny
+donor
+donsy
+donut
+doobs
+dooce
+doody
+doofs
+dooks
+dooky
+doole
+dools
+dooly
+dooms
+doomy
+doona
+doorn
+doors
+doozy
+dopas
+doped
+doper
+dopes
+dopey
+doppe
+dorad
+dorba
+dorbs
+doree
+dores
+doric
+doris
+dorje
+dorks
+dorky
+dorms
+dormy
+dorps
+dorrs
+dorsa
+dorse
+dorts
+dorty
+dosai
+dosas
+dosed
+doseh
+doser
+doses
+dosha
+dotal
+doted
+doter
+dotes
+dotty
+douar
+doubt
+douce
+doucs
+dough
+douks
+doula
+douma
+doums
+doups
+doura
+douse
+douts
+doved
+doven
+dover
+doves
+dovie
+dowak
+dowar
+dowds
+dowdy
+dowed
+dowel
+dower
+dowfs
+dowie
+dowle
+dowls
+dowly
+downa
+downs
+downy
+dowps
+dowry
+dowse
+dowts
+doxed
+doxes
+doxie
+doyen
+doyly
+dozed
+dozen
+dozer
+dozes
+drabs
+drack
+draco
+draff
+draft
+drags
+drail
+drain
+drake
+drama
+drams
+drank
+drant
+drape
+draps
+drapy
+drats
+drave
+drawl
+drawn
+draws
+drays
+dread
+dream
+drear
+dreck
+dreed
+dreer
+drees
+dregs
+dreks
+drent
+drere
+dress
+drest
+dreys
+dribs
+drice
+dried
+drier
+dries
+drift
+drill
+drily
+drink
+drips
+dript
+drive
+drock
+droid
+droil
+droit
+droke
+drole
+droll
+drome
+drone
+drony
+droob
+droog
+drook
+drool
+droop
+drops
+dropt
+dross
+drouk
+drove
+drown
+drows
+drubs
+drugs
+druid
+drums
+drunk
+drupe
+druse
+drusy
+druxy
+dryad
+dryas
+dryer
+dryly
+dsobo
+dsomo
+duads
+duals
+duans
+duars
+dubbo
+dubby
+ducal
+ducat
+duces
+duchy
+ducks
+ducky
+ducti
+ducts
+duddy
+duded
+dudes
+duels
+duets
+duett
+duffs
+dufus
+duing
+duits
+dukas
+duked
+dukes
+dukka
+dukun
+dulce
+dules
+dulia
+dulls
+dully
+dulse
+dumas
+dumbo
+dumbs
+dumka
+dumky
+dummy
+dumps
+dumpy
+dunam
+dunce
+dunch
+dunes
+dungs
+dungy
+dunks
+dunno
+dunny
+dunsh
+dunts
+duomi
+duomo
+duped
+duper
+dupes
+duple
+duply
+duppy
+dural
+duras
+dured
+dures
+durgy
+durns
+duroc
+duros
+duroy
+durra
+durrs
+durry
+durst
+durum
+durzi
+dusks
+dusky
+dusts
+dusty
+dutch
+duvet
+duxes
+dwaal
+dwale
+dwalm
+dwams
+dwamy
+dwang
+dwarf
+dwaum
+dweeb
+dwell
+dwelt
+dwile
+dwine
+dyads
+dyers
+dying
+dyked
+dykes
+dykey
+dykon
+dynel
+dynes
+dynos
+dzhos
+eager
+eagle
+eagly
+eagre
+ealed
+eales
+eaned
+eards
+eared
+earls
+early
+earns
+earnt
+earst
+earth
+eased
+easel
+easer
+eases
+easle
+easts
+eaten
+eater
+eathe
+eatin
+eaved
+eaver
+eaves
+ebank
+ebbed
+ebbet
+ebena
+ebene
+ebike
+ebons
+ebony
+ebook
+ecads
+ecard
+ecash
+eched
+eches
+echos
+ecigs
+eclat
+ecole
+ecrus
+edema
+edged
+edger
+edges
+edict
+edify
+edile
+edits
+educe
+educt
+eejit
+eensy
+eerie
+eeven
+eever
+eevns
+effed
+effer
+efits
+egads
+egers
+egest
+eggar
+egged
+egger
+egmas
+egret
+ehing
+eider
+eidos
+eight
+eigne
+eiked
+eikon
+eilds
+eiron
+eisel
+eject
+ejido
+ekdam
+eking
+ekkas
+elain
+eland
+elans
+elate
+elbow
+elchi
+elder
+eldin
+elect
+eleet
+elegy
+elemi
+elfed
+elfin
+eliad
+elide
+elint
+elite
+elmen
+eloge
+elogy
+eloin
+elope
+elops
+elpee
+elsin
+elude
+elute
+elvan
+elven
+elver
+elves
+emacs
+email
+embar
+embay
+embed
+ember
+embog
+embow
+embox
+embus
+emcee
+emeer
+emend
+emerg
+emery
+emeus
+emics
+emirs
+emits
+emmas
+emmer
+emmet
+emmew
+emmys
+emoji
+emong
+emote
+emove
+empts
+empty
+emule
+emure
+emyde
+emyds
+enact
+enarm
+enate
+ended
+ender
+endew
+endow
+endue
+enema
+enemy
+enews
+enfix
+eniac
+enjoy
+enlit
+enmew
+ennog
+ennui
+enoki
+enols
+enorm
+enows
+enrol
+ensew
+ensky
+ensue
+enter
+entia
+entre
+entry
+enure
+enurn
+envoi
+envoy
+enzym
+eolid
+eorls
+eosin
+epact
+epees
+epena
+epene
+ephah
+ephas
+ephod
+ephor
+epics
+epoch
+epode
+epopt
+epoxy
+eppie
+epris
+equal
+eques
+equid
+equip
+erase
+erbia
+erect
+erevs
+ergon
+ergos
+ergot
+erhus
+erica
+erick
+erics
+ering
+erned
+ernes
+erode
+erose
+erred
+error
+erses
+eruct
+erugo
+erupt
+eruvs
+erven
+ervil
+escar
+escot
+esile
+eskar
+esker
+esnes
+esrog
+essay
+esses
+ester
+estoc
+estop
+estro
+etage
+etape
+etats
+etens
+ethal
+ether
+ethic
+ethne
+ethos
+ethyl
+etics
+etnas
+etrog
+ettin
+ettle
+etude
+etuis
+etwee
+etyma
+eughs
+euked
+eupad
+euros
+eusol
+evade
+evegs
+evens
+event
+evert
+every
+evets
+evhoe
+evict
+evils
+evite
+evohe
+evoke
+ewers
+ewest
+ewhow
+ewked
+exact
+exalt
+exams
+excel
+exeat
+execs
+exeem
+exeme
+exert
+exfil
+exier
+exies
+exile
+exine
+exing
+exist
+exite
+exits
+exode
+exome
+exons
+expat
+expel
+expos
+extol
+extra
+exude
+exuls
+exult
+exurb
+eyass
+eyers
+eying
+eyots
+eyras
+eyres
+eyrie
+eyrir
+ezine
+fabbo
+fabby
+fable
+faced
+facer
+faces
+facet
+facey
+facia
+facie
+facta
+facto
+facts
+facty
+faddy
+faded
+fader
+fades
+fadge
+fados
+faena
+faery
+faffs
+faffy
+faggy
+fagin
+fagot
+faiks
+fails
+faine
+fains
+faint
+faire
+fairs
+fairy
+faith
+faked
+faker
+fakes
+fakey
+fakie
+fakir
+falaj
+fales
+falls
+false
+falsy
+famed
+fames
+fanal
+fancy
+fands
+fanes
+fanga
+fango
+fangs
+fanks
+fanny
+fanon
+fanos
+fanum
+faqir
+farad
+farce
+farci
+farcy
+fards
+fared
+farer
+fares
+farle
+farls
+farms
+faros
+farro
+farse
+farts
+fasci
+fasti
+fasts
+fatal
+fated
+fates
+fatly
+fatso
+fatty
+fatwa
+fauch
+faugh
+fauld
+fault
+fauna
+fauns
+faurd
+faute
+fauts
+fauve
+favas
+favel
+faver
+faves
+favor
+favus
+fawns
+fawny
+faxed
+faxes
+fayed
+fayer
+fayne
+fayre
+fazed
+fazes
+feals
+feard
+feare
+fears
+feart
+fease
+feast
+feats
+feaze
+fecal
+feces
+fecht
+fecit
+fecks
+fedai
+fedex
+feebs
+feeds
+feels
+feely
+feens
+feers
+feese
+feeze
+fehme
+feign
+feint
+feist
+felch
+felid
+felix
+fella
+fells
+felly
+felon
+felts
+felty
+femal
+femes
+femic
+femme
+femmy
+femur
+fence
+fends
+fendy
+fenis
+fenks
+fenny
+fents
+feods
+feoff
+feral
+ferer
+feres
+feria
+ferly
+fermi
+ferms
+ferns
+ferny
+ferox
+ferry
+fesse
+festa
+fests
+festy
+fetal
+fetas
+fetch
+feted
+fetes
+fetid
+fetor
+fetta
+fetts
+fetus
+fetwa
+feuar
+feuds
+feued
+fever
+fewer
+feyed
+feyer
+feyly
+fezes
+fezzy
+fiars
+fiats
+fiber
+fibre
+fibro
+fices
+fiche
+fichu
+ficin
+ficos
+ficta
+ficus
+fides
+fidge
+fidos
+fidus
+fiefs
+field
+fiend
+fient
+fiere
+fieri
+fiers
+fiery
+fiest
+fifed
+fifer
+fifes
+fifis
+fifth
+fifty
+figgy
+fight
+figos
+fiked
+fikes
+filar
+filch
+filed
+filer
+files
+filet
+filii
+filks
+fille
+fillo
+fills
+filly
+filmi
+films
+filmy
+filon
+filos
+filth
+filum
+final
+finca
+finch
+finds
+fined
+finer
+fines
+finis
+finks
+finny
+finos
+fiord
+fiqhs
+fique
+fired
+firer
+fires
+firie
+firks
+firma
+firms
+firni
+firns
+firry
+first
+firth
+fiscs
+fisho
+fishy
+fisks
+fists
+fisty
+fitch
+fitly
+fitna
+fitte
+fitts
+fiver
+fives
+fixed
+fixer
+fixes
+fixie
+fixit
+fizzy
+fjeld
+fjord
+flabs
+flack
+flaff
+flags
+flail
+flair
+flake
+flaks
+flaky
+flame
+flamm
+flams
+flamy
+flane
+flank
+flans
+flaps
+flare
+flary
+flash
+flask
+flats
+flava
+flawn
+flaws
+flawy
+flaxy
+flays
+fleam
+fleas
+fleck
+fleek
+fleer
+flees
+fleet
+flegs
+fleme
+flesh
+fleur
+flews
+flexi
+flexo
+fleys
+flick
+flics
+flied
+flier
+flies
+flimp
+flims
+fling
+flint
+flips
+flirs
+flirt
+flisk
+flite
+flits
+flitt
+float
+flobs
+flock
+flocs
+floes
+flogs
+flong
+flood
+floor
+flops
+flora
+flore
+flors
+flory
+flosh
+floss
+flota
+flote
+flour
+flout
+flown
+flows
+flowy
+flubs
+flued
+flues
+fluey
+fluff
+fluid
+fluke
+fluky
+flume
+flump
+flung
+flunk
+fluor
+flurr
+flush
+flute
+fluty
+fluyt
+flyby
+flyer
+flyin
+flype
+flyte
+fnarr
+foals
+foams
+foamy
+focal
+focus
+foehn
+fogey
+foggy
+fogie
+fogle
+fogos
+fogou
+fohns
+foids
+foils
+foins
+foist
+folds
+foley
+folia
+folic
+folie
+folio
+folks
+folky
+folly
+fomes
+fonda
+fonds
+fondu
+fones
+fonio
+fonly
+fonts
+foods
+foody
+fools
+foots
+footy
+foram
+foray
+forbs
+forby
+force
+fordo
+fords
+forel
+fores
+forex
+forge
+forgo
+forks
+forky
+forma
+forme
+forms
+forte
+forth
+forts
+forty
+forum
+forza
+forze
+fossa
+fosse
+fouat
+fouds
+fouer
+fouet
+foule
+fouls
+found
+fount
+fours
+fouth
+fovea
+fowls
+fowth
+foxed
+foxes
+foxie
+foyer
+foyle
+foyne
+frabs
+frack
+fract
+frags
+frail
+fraim
+frais
+frame
+franc
+frank
+frape
+fraps
+frass
+frate
+frati
+frats
+fraud
+fraus
+frays
+freak
+freed
+freer
+frees
+freet
+freit
+fremd
+frena
+freon
+frere
+fresh
+frets
+friar
+fribs
+fried
+frier
+fries
+frigs
+frill
+frise
+frisk
+frist
+frita
+frite
+frith
+frits
+fritt
+fritz
+frize
+frizz
+frock
+froes
+frogs
+fromm
+frond
+frons
+front
+froom
+frore
+frorn
+frory
+frosh
+frost
+froth
+frown
+frows
+frowy
+froyo
+froze
+frugs
+fruit
+frump
+frush
+frust
+fryer
+fubar
+fubby
+fubsy
+fucks
+fucus
+fuddy
+fudge
+fudgy
+fuels
+fuero
+fuffs
+fuffy
+fugal
+fuggy
+fugie
+fugio
+fugis
+fugle
+fugly
+fugue
+fugus
+fujis
+fulla
+fulls
+fully
+fulth
+fulwa
+fumed
+fumer
+fumes
+fumet
+funda
+fundi
+fundo
+funds
+fundy
+fungi
+fungo
+fungs
+funic
+funis
+funks
+funky
+funny
+funsy
+funts
+fural
+furan
+furca
+furls
+furol
+furor
+furos
+furrs
+furry
+furth
+furze
+furzy
+fused
+fusee
+fusel
+fuses
+fusil
+fusks
+fussy
+fusts
+fusty
+futon
+fuzed
+fuzee
+fuzes
+fuzil
+fuzzy
+fyces
+fyked
+fykes
+fyles
+fyrds
+fytte
+gabba
+gabby
+gable
+gaddi
+gades
+gadge
+gadgy
+gadid
+gadis
+gadje
+gadjo
+gadso
+gaffe
+gaffs
+gaged
+gager
+gages
+gaids
+gaily
+gains
+gairs
+gaita
+gaits
+gaitt
+gajos
+galah
+galas
+galax
+galea
+galed
+gales
+galia
+galis
+galls
+gally
+galop
+galut
+galvo
+gamas
+gamay
+gamba
+gambe
+gambo
+gambs
+gamed
+gamer
+games
+gamey
+gamic
+gamin
+gamma
+gamme
+gammy
+gamps
+gamut
+ganch
+gandy
+ganef
+ganev
+gangs
+ganja
+ganks
+ganof
+gants
+gaols
+gaped
+gaper
+gapes
+gapos
+gappy
+garam
+garba
+garbe
+garbo
+garbs
+garda
+garde
+gares
+garis
+garms
+garni
+garre
+garri
+garth
+garum
+gases
+gashy
+gasps
+gaspy
+gassy
+gasts
+gatch
+gated
+gater
+gates
+gaths
+gator
+gauch
+gaucy
+gauds
+gaudy
+gauge
+gauje
+gault
+gaums
+gaumy
+gaunt
+gaups
+gaurs
+gauss
+gauze
+gauzy
+gavel
+gavot
+gawcy
+gawds
+gawks
+gawky
+gawps
+gawsy
+gayal
+gayer
+gayly
+gazal
+gazar
+gazed
+gazer
+gazes
+gazon
+gazoo
+geals
+geans
+geare
+gears
+geasa
+geats
+gebur
+gecko
+gecks
+geeks
+geeky
+geeps
+geese
+geest
+geist
+geits
+gelds
+gelee
+gelid
+gelly
+gelts
+gemel
+gemma
+gemmy
+gemot
+genae
+genal
+genas
+genes
+genet
+genic
+genie
+genii
+genin
+genio
+genip
+genny
+genoa
+genom
+genre
+genro
+gents
+genty
+genua
+genus
+geode
+geoid
+gerah
+gerbe
+geres
+gerle
+germs
+germy
+gerne
+gesse
+gesso
+geste
+gests
+getas
+getup
+geums
+geyan
+geyer
+ghast
+ghats
+ghaut
+ghazi
+ghees
+ghest
+ghost
+ghoul
+ghusl
+ghyll
+giant
+gibed
+gibel
+giber
+gibes
+gibli
+gibus
+giddy
+gifts
+gigas
+gighe
+gigot
+gigue
+gilas
+gilds
+gilet
+gilia
+gills
+gilly
+gilpy
+gilts
+gimel
+gimme
+gimps
+gimpy
+ginch
+ginga
+ginge
+gings
+ginks
+ginny
+ginzo
+gipon
+gippo
+gippy
+gipsy
+girds
+girlf
+girls
+girly
+girns
+giron
+giros
+girrs
+girsh
+girth
+girts
+gismo
+gisms
+gists
+gitch
+gites
+giust
+gived
+given
+giver
+gives
+gizmo
+glace
+glade
+glads
+glady
+glaik
+glair
+glamp
+glams
+gland
+glans
+glare
+glary
+glass
+glatt
+glaum
+glaur
+glaze
+glazy
+gleam
+glean
+gleba
+glebe
+gleby
+glede
+gleds
+gleed
+gleek
+glees
+gleet
+gleis
+glens
+glent
+gleys
+glial
+glias
+glibs
+glide
+gliff
+glift
+glike
+glime
+glims
+glint
+glisk
+glits
+glitz
+gloam
+gloat
+globe
+globi
+globs
+globy
+glode
+glogg
+gloms
+gloom
+gloop
+glops
+glory
+gloss
+glost
+glout
+glove
+glows
+glowy
+gloze
+glued
+gluer
+glues
+gluey
+glugg
+glugs
+glume
+glums
+gluon
+glute
+gluts
+glyph
+gnapi
+gnarl
+gnarr
+gnars
+gnash
+gnats
+gnawn
+gnaws
+gnome
+gnows
+goads
+goafs
+goaft
+goals
+goary
+goats
+goaty
+goave
+goban
+gobar
+gobbe
+gobbi
+gobbo
+gobby
+gobis
+gobos
+godet
+godly
+godso
+goels
+goers
+goest
+goeth
+goety
+gofer
+goffs
+gogga
+gogos
+goier
+going
+gojis
+gokes
+golds
+goldy
+golem
+goles
+golfs
+golly
+golpe
+golps
+gombo
+gomer
+gompa
+gonad
+gonch
+gonef
+goner
+gongs
+gonia
+gonif
+gonks
+gonna
+gonof
+gonys
+gonzo
+gooby
+goodo
+goods
+goody
+gooey
+goofs
+goofy
+googs
+gooks
+gooky
+goold
+gools
+gooly
+goomy
+goons
+goony
+goops
+goopy
+goors
+goory
+goose
+goosy
+gopak
+gopik
+goral
+goras
+goray
+gorbs
+gordo
+gored
+gores
+gorge
+goris
+gorms
+gormy
+gorps
+gorse
+gorsy
+gosht
+gosse
+gotch
+goths
+gothy
+gotta
+gouch
+gouge
+gouks
+goura
+gourd
+gouts
+gouty
+goved
+goves
+gowan
+gowds
+gowfs
+gowks
+gowls
+gowns
+goxes
+goyim
+goyle
+graal
+grabs
+grace
+grade
+grads
+graff
+graft
+grail
+grain
+graip
+grama
+grame
+gramp
+grams
+grana
+grand
+grano
+grans
+grant
+grape
+graph
+grapy
+grasp
+grass
+grata
+grate
+grats
+grave
+gravs
+gravy
+grays
+graze
+great
+grebe
+grebo
+grece
+greed
+greek
+green
+grees
+greet
+grege
+grego
+grein
+grens
+greps
+grese
+greve
+grews
+greys
+grice
+gride
+grids
+grief
+griff
+grift
+grigs
+grike
+grill
+grime
+grimy
+grind
+grins
+griot
+gripe
+grips
+gript
+gripy
+grise
+grist
+grisy
+grith
+grits
+grize
+groan
+groat
+grody
+grogs
+groin
+groks
+groma
+groms
+grone
+groof
+groom
+grope
+gross
+grosz
+grots
+grouf
+group
+grout
+grove
+grovy
+growl
+grown
+grows
+grrls
+grrrl
+grubs
+grued
+gruel
+grues
+grufe
+gruff
+grume
+grump
+grund
+grunt
+gryce
+gryde
+gryke
+grype
+grypt
+guaco
+guana
+guano
+guans
+guard
+guars
+guava
+gubba
+gucks
+gucky
+gudes
+guess
+guest
+guffs
+gugas
+guggl
+guide
+guido
+guids
+guild
+guile
+guilt
+guimp
+guiro
+guise
+gulab
+gulag
+gular
+gulas
+gulch
+gules
+gulet
+gulfs
+gulfy
+gulls
+gully
+gulph
+gulps
+gulpy
+gumbo
+gumma
+gummi
+gummy
+gumps
+gunas
+gundi
+gundy
+gunge
+gungy
+gunks
+gunky
+gunny
+guppy
+guqin
+gurdy
+gurge
+gurks
+gurls
+gurly
+gurns
+gurry
+gursh
+gurus
+gushy
+gusla
+gusle
+gusli
+gussy
+gusto
+gusts
+gusty
+gutsy
+gutta
+gutty
+guyed
+guyle
+guyot
+guyse
+gwine
+gyals
+gyans
+gybed
+gybes
+gyeld
+gymps
+gynae
+gynie
+gynny
+gynos
+gyoza
+gypes
+gypos
+gyppo
+gyppy
+gypsy
+gyral
+gyred
+gyres
+gyron
+gyros
+gyrus
+gytes
+gyved
+gyver
+gyves
+haafs
+haars
+haats
+habit
+hable
+habus
+hacek
+hacks
+hacky
+hadal
+haded
+hades
+hadji
+hadst
+haems
+haere
+haets
+haffs
+hafiz
+hafta
+hafts
+haggs
+haham
+hahas
+haick
+haika
+haiks
+haiku
+hails
+haily
+hains
+haint
+hairs
+hairy
+haith
+hajes
+hajis
+hajji
+hakam
+hakas
+hakea
+hakes
+hakim
+hakus
+halal
+haldi
+haled
+haler
+hales
+halfa
+halfs
+halid
+hallo
+halls
+halma
+halms
+halon
+halos
+halse
+halsh
+halts
+halva
+halve
+halwa
+hamal
+hamba
+hamed
+hamel
+hames
+hammy
+hamza
+hanap
+hance
+hanch
+handi
+hands
+handy
+hangi
+hangs
+hanks
+hanky
+hansa
+hanse
+hants
+haole
+haoma
+hapas
+hapax
+haply
+happi
+happy
+hapus
+haram
+hards
+hardy
+hared
+harem
+hares
+harim
+harks
+harls
+harms
+harns
+haros
+harps
+harpy
+harry
+harsh
+harts
+hashy
+hasks
+hasps
+hasta
+haste
+hasty
+hatch
+hated
+hater
+hates
+hatha
+hathi
+hatty
+hauds
+haufs
+haugh
+haugo
+hauld
+haulm
+hauls
+hault
+hauns
+haunt
+hause
+haute
+havan
+havel
+haven
+haver
+haves
+havoc
+hawed
+hawks
+hawms
+hawse
+hayed
+hayer
+hayey
+hayle
+hazan
+hazed
+hazel
+hazer
+hazes
+hazle
+heads
+heady
+heald
+heals
+heame
+heaps
+heapy
+heard
+heare
+hears
+heart
+heast
+heath
+heats
+heaty
+heave
+heavy
+heben
+hebes
+hecht
+hecks
+heder
+hedge
+hedgy
+heeds
+heedy
+heels
+heeze
+hefte
+hefts
+hefty
+heiau
+heids
+heigh
+heils
+heirs
+heist
+hejab
+hejra
+heled
+heles
+helio
+helix
+hella
+hello
+hells
+helly
+helms
+helos
+helot
+helps
+helve
+hemal
+hemes
+hemic
+hemin
+hemps
+hempy
+hence
+hench
+hends
+henge
+henna
+henny
+henry
+hents
+hepar
+herbs
+herby
+herds
+heres
+herls
+herma
+herms
+herns
+heron
+heros
+herps
+herry
+herse
+hertz
+herye
+hesps
+hests
+hetes
+heths
+heuch
+heugh
+hevea
+hevel
+hewed
+hewer
+hewgh
+hexad
+hexed
+hexer
+hexes
+hexyl
+heyed
+hiant
+hibas
+hicks
+hided
+hider
+hides
+hiems
+hifis
+highs
+hight
+hijab
+hijra
+hiked
+hiker
+hikes
+hikoi
+hilar
+hilch
+hillo
+hills
+hilly
+hilsa
+hilts
+hilum
+hilus
+himbo
+hinau
+hinds
+hinge
+hings
+hinky
+hinny
+hints
+hiois
+hiped
+hiper
+hipes
+hiply
+hippo
+hippy
+hired
+hiree
+hirer
+hires
+hissy
+hists
+hitch
+hithe
+hived
+hiver
+hives
+hizen
+hoach
+hoaed
+hoagy
+hoard
+hoars
+hoary
+hoast
+hobby
+hobos
+hocks
+hocus
+hodad
+hodja
+hoers
+hogan
+hogen
+hoggs
+hoghs
+hogoh
+hogos
+hohed
+hoick
+hoied
+hoiks
+hoing
+hoise
+hoist
+hokas
+hoked
+hokes
+hokey
+hokis
+hokku
+hokum
+holds
+holed
+holes
+holey
+holks
+holla
+hollo
+holly
+holme
+holms
+holon
+holos
+holts
+homas
+homed
+homer
+homes
+homey
+homie
+homme
+homos
+honan
+honda
+honds
+honed
+honer
+hones
+honey
+hongi
+hongs
+honks
+honky
+honor
+hooch
+hoods
+hoody
+hooey
+hoofs
+hoogo
+hooha
+hooka
+hooks
+hooky
+hooly
+hoons
+hoops
+hoord
+hoors
+hoosh
+hoots
+hooty
+hoove
+hopak
+hoped
+hoper
+hopes
+hoppy
+horah
+horal
+horas
+horde
+horis
+horks
+horme
+horns
+horny
+horse
+horst
+horsy
+hosed
+hosel
+hosen
+hoser
+hoses
+hosey
+hosta
+hosts
+hotch
+hotel
+hoten
+hotis
+hotly
+hotte
+hotty
+houff
+houfs
+hough
+hound
+houri
+hours
+house
+houts
+hovea
+hoved
+hovel
+hoven
+hover
+hoves
+howay
+howbe
+howdy
+howes
+howff
+howfs
+howks
+howls
+howre
+howso
+howto
+hoxed
+hoxes
+hoyas
+hoyed
+hoyle
+hubba
+hubby
+hucks
+hudna
+hudud
+huers
+huffs
+huffy
+huger
+huggy
+huhus
+huias
+huies
+hukou
+hulas
+hules
+hulks
+hulky
+hullo
+hulls
+hully
+human
+humas
+humfs
+humic
+humid
+humor
+humph
+humps
+humpy
+humus
+hunch
+hundo
+hunks
+hunky
+hunts
+hurds
+hurls
+hurly
+hurra
+hurry
+hurst
+hurts
+hurty
+hushy
+husks
+husky
+husos
+hussy
+hutch
+hutia
+huzza
+huzzy
+hwyls
+hydel
+hydra
+hydro
+hyena
+hyens
+hygge
+hying
+hykes
+hylas
+hyleg
+hyles
+hylic
+hymen
+hymns
+hynde
+hyoid
+hyped
+hyper
+hypes
+hypha
+hyphy
+hypos
+hyrax
+hyson
+hythe
+iambi
+iambs
+ibrik
+icers
+iched
+iches
+ichor
+icier
+icily
+icing
+icker
+ickle
+icons
+ictal
+ictic
+ictus
+idant
+iddah
+iddat
+iddut
+ideal
+ideas
+idees
+ident
+idiom
+idiot
+idled
+idler
+idles
+idlis
+idola
+idols
+idyll
+idyls
+iftar
+igapo
+igged
+igloo
+iglus
+ignis
+ihram
+iiwis
+ikans
+ikats
+ikons
+ileac
+ileal
+ileum
+ileus
+iliac
+iliad
+ilial
+ilium
+iller
+illth
+image
+imago
+imagy
+imams
+imari
+imaum
+imbar
+imbed
+imbos
+imbue
+imide
+imido
+imids
+imine
+imino
+imlis
+immew
+immit
+immix
+imped
+impel
+impis
+imply
+impot
+impro
+imshi
+imshy
+inane
+inapt
+inarm
+inbox
+inbye
+incas
+incel
+incle
+incog
+incur
+incus
+incut
+indew
+index
+india
+indie
+indol
+indow
+indri
+indue
+inept
+inerm
+inert
+infer
+infix
+infos
+infra
+ingan
+ingle
+ingot
+inion
+inked
+inker
+inkle
+inlay
+inlet
+inned
+inner
+innie
+innit
+inorb
+input
+inros
+inrun
+insee
+inset
+inspo
+intel
+inter
+intil
+intis
+intra
+intro
+inula
+inure
+inurn
+inust
+invar
+inver
+inwit
+iodic
+iodid
+iodin
+ionic
+ioras
+iotas
+ippon
+irade
+irate
+irids
+iring
+irked
+iroko
+irone
+irons
+irony
+isbas
+ishes
+isled
+isles
+islet
+isnae
+issei
+issue
+istle
+itchy
+items
+ither
+ivied
+ivies
+ivory
+ixias
+ixnay
+ixora
+ixtle
+izard
+izars
+izzat
+jaaps
+jabot
+jacal
+jacet
+jacks
+jacky
+jaded
+jades
+jafas
+jaffa
+jagas
+jager
+jaggs
+jaggy
+jagir
+jagra
+jails
+jaker
+jakes
+jakey
+jakie
+jalap
+jaleo
+jalop
+jambe
+jambo
+jambs
+jambu
+james
+jammy
+jamon
+jamun
+janes
+janky
+janns
+janny
+janty
+japan
+japed
+japer
+japes
+jarks
+jarls
+jarps
+jarta
+jarul
+jasey
+jaspe
+jasps
+jatha
+jatis
+jatos
+jauks
+jaune
+jaunt
+jaups
+javas
+javel
+jawan
+jawed
+jawns
+jaxie
+jazzy
+jeans
+jeats
+jebel
+jedis
+jeels
+jeely
+jeeps
+jeera
+jeers
+jeeze
+jefes
+jeffs
+jehad
+jehus
+jelab
+jello
+jells
+jelly
+jembe
+jemmy
+jenny
+jeons
+jerid
+jerks
+jerky
+jerry
+jesse
+jessy
+jests
+jesus
+jetee
+jetes
+jeton
+jetty
+jeune
+jewed
+jewel
+jewie
+jhala
+jheel
+jhils
+jiaos
+jibba
+jibbs
+jibed
+jiber
+jibes
+jiffs
+jiffy
+jiggy
+jigot
+jihad
+jills
+jilts
+jimmy
+jimpy
+jingo
+jings
+jinks
+jinne
+jinni
+jinns
+jirds
+jirga
+jirre
+jisms
+jitis
+jitty
+jived
+jiver
+jives
+jivey
+jnana
+jobed
+jobes
+jocko
+jocks
+jocky
+jocos
+jodel
+joeys
+johns
+joins
+joint
+joist
+joked
+joker
+jokes
+jokey
+jokol
+joled
+joles
+jolie
+jollo
+jolls
+jolly
+jolts
+jolty
+jomon
+jomos
+jones
+jongs
+jonty
+jooks
+joram
+jorts
+jorum
+jotas
+jotty
+jotun
+joual
+jougs
+jouks
+joule
+jours
+joust
+jowar
+jowed
+jowls
+jowly
+joyed
+jubas
+jubes
+jucos
+judas
+judge
+judgy
+judos
+jugal
+jugum
+juice
+juicy
+jujus
+juked
+jukes
+jukus
+julep
+julia
+jumar
+jumbo
+jumby
+jumps
+jumpy
+junco
+junks
+junky
+junta
+junto
+jupes
+jupon
+jural
+jurat
+jurel
+jures
+juris
+juror
+juste
+justs
+jutes
+jutty
+juves
+juvie
+kaama
+kabab
+kabar
+kabob
+kacha
+kacks
+kadai
+kades
+kadis
+kafir
+kagos
+kagus
+kahal
+kaiak
+kaids
+kaies
+kaifs
+kaika
+kaiks
+kails
+kaims
+kaing
+kains
+kajal
+kakas
+kakis
+kalam
+kalas
+kales
+kalif
+kalis
+kalpa
+kalua
+kamas
+kames
+kamik
+kamis
+kamme
+kanae
+kanal
+kanas
+kanat
+kandy
+kaneh
+kanes
+kanga
+kangs
+kanji
+kants
+kanzu
+kaons
+kapai
+kapas
+kapha
+kaphs
+kapok
+kapow
+kappa
+kapur
+kapus
+kaput
+karai
+karas
+karat
+karee
+karez
+karks
+karma
+karns
+karoo
+karos
+karri
+karst
+karsy
+karts
+karzy
+kasha
+kasme
+katal
+katas
+katis
+katti
+kaugh
+kauri
+kauru
+kaury
+kaval
+kavas
+kawas
+kawau
+kawed
+kayak
+kayle
+kayos
+kazis
+kazoo
+kbars
+kcals
+keaki
+kebab
+kebar
+kebob
+kecks
+kedge
+kedgy
+keech
+keefs
+keeks
+keels
+keema
+keeno
+keens
+keeps
+keets
+keeve
+kefir
+kehua
+keirs
+kelep
+kelim
+kells
+kelly
+kelps
+kelpy
+kelts
+kelty
+kembo
+kembs
+kemps
+kempt
+kempy
+kenaf
+kench
+kendo
+kenos
+kente
+kents
+kepis
+kerbs
+kerel
+kerfs
+kerky
+kerma
+kerne
+kerns
+keros
+kerry
+kerve
+kesar
+kests
+ketas
+ketch
+ketes
+ketol
+kevel
+kevil
+kexes
+keyed
+keyer
+khadi
+khads
+khafs
+khaki
+khana
+khans
+khaph
+khats
+khaya
+khazi
+kheda
+kheer
+kheth
+khets
+khirs
+khoja
+khors
+khoum
+khuds
+khula
+khyal
+kiaat
+kiack
+kiaki
+kiang
+kiasu
+kibbe
+kibbi
+kibei
+kibes
+kibla
+kicks
+kicky
+kiddo
+kiddy
+kidel
+kideo
+kidge
+kiefs
+kiers
+kieve
+kievs
+kight
+kikay
+kikes
+kikoi
+kiley
+kilig
+kilim
+kills
+kilns
+kilos
+kilps
+kilts
+kilty
+kimbo
+kimet
+kinas
+kinda
+kinds
+kindy
+kines
+kings
+kingy
+kinin
+kinks
+kinky
+kinos
+kiore
+kiosk
+kipah
+kipas
+kipes
+kippa
+kipps
+kipsy
+kirby
+kirks
+kirns
+kirri
+kisan
+kissy
+kists
+kitab
+kited
+kiter
+kites
+kithe
+kiths
+kitke
+kitty
+kitul
+kivas
+kiwis
+klang
+klaps
+klett
+klick
+klieg
+kliks
+klong
+kloof
+kluge
+klutz
+knack
+knags
+knaps
+knarl
+knars
+knaur
+knave
+knawe
+knead
+kneed
+kneel
+knees
+knell
+knelt
+knick
+knife
+knish
+knits
+knive
+knobs
+knock
+knoll
+knoop
+knops
+knosp
+knots
+knoud
+knout
+knowd
+knowe
+known
+knows
+knubs
+knule
+knurl
+knurr
+knurs
+knuts
+koala
+koans
+koaps
+koban
+kobos
+koels
+koffs
+kofta
+kogal
+kohas
+kohen
+kohls
+koine
+koiwi
+kojis
+kokam
+kokas
+koker
+kokra
+kokum
+kolas
+kolos
+kombi
+kombu
+konbu
+kondo
+konks
+kooks
+kooky
+koori
+kopek
+kophs
+kopje
+koppa
+korai
+koran
+koras
+korat
+kores
+koris
+korma
+koros
+korun
+korus
+koses
+kotch
+kotos
+kotow
+koura
+kraal
+krabs
+kraft
+krais
+krait
+krang
+krans
+kranz
+kraut
+krays
+kreef
+kreen
+kreep
+kreng
+krewe
+krill
+kriol
+krona
+krone
+kroon
+krubi
+krump
+krunk
+ksars
+kubie
+kudos
+kudus
+kudzu
+kufis
+kugel
+kuias
+kukri
+kukus
+kulak
+kulan
+kulas
+kulfi
+kumis
+kumys
+kunas
+kunds
+kuris
+kurre
+kurta
+kurus
+kusso
+kusti
+kutai
+kutas
+kutch
+kutis
+kutus
+kuyas
+kuzus
+kvass
+kvell
+kwaai
+kwela
+kwink
+kwirl
+kyack
+kyaks
+kyang
+kyars
+kyats
+kybos
+kydst
+kyles
+kylie
+kylin
+kylix
+kyloe
+kynde
+kynds
+kypes
+kyrie
+kytes
+kythe
+kyudo
+laarf
+laari
+labda
+label
+labia
+labis
+labne
+labor
+labra
+laccy
+laced
+lacer
+laces
+lacet
+lacey
+lacis
+lacka
+lacks
+lacky
+laddu
+laddy
+laded
+ladee
+laden
+lader
+lades
+ladle
+ladoo
+laers
+laevo
+lagan
+lagar
+lager
+laggy
+lahal
+lahar
+laich
+laics
+laide
+laids
+laigh
+laika
+laiks
+laird
+lairs
+lairy
+laith
+laity
+laked
+laker
+lakes
+lakhs
+lakin
+laksa
+laldy
+lalls
+lamas
+lambs
+lamby
+lamed
+lamer
+lames
+lamia
+lammy
+lamps
+lanai
+lanas
+lance
+lanch
+lande
+lands
+laned
+lanes
+lanks
+lanky
+lants
+lapas
+lapel
+lapin
+lapis
+lapje
+lappa
+lappy
+lapse
+larch
+lards
+lardy
+laree
+lares
+larfs
+larga
+large
+largo
+laris
+larks
+larky
+larns
+larnt
+larum
+larva
+lased
+laser
+lases
+lassi
+lasso
+lassu
+lassy
+lasts
+latah
+latch
+lated
+laten
+later
+latex
+lathe
+lathi
+laths
+lathy
+latke
+latte
+latus
+lauan
+lauch
+laude
+lauds
+laufs
+laugh
+laund
+laura
+laval
+lavas
+laved
+laver
+laves
+lavra
+lavvy
+lawed
+lawer
+lawin
+lawks
+lawns
+lawny
+lawsy
+laxed
+laxer
+laxes
+laxly
+layby
+layed
+layer
+layin
+layup
+lazar
+lazed
+lazes
+lazos
+lazzi
+lazzo
+leach
+leads
+leady
+leafs
+leafy
+leaks
+leaky
+leams
+leans
+leant
+leany
+leaps
+leapt
+leare
+learn
+lears
+leary
+lease
+leash
+least
+leats
+leave
+leavy
+leaze
+leben
+leccy
+leche
+ledes
+ledge
+ledgy
+ledum
+leear
+leech
+leeks
+leeps
+leers
+leery
+leese
+leets
+leeze
+lefte
+lefts
+lefty
+legal
+leger
+leges
+legge
+leggo
+leggy
+legit
+legno
+lehrs
+lehua
+leirs
+leish
+leman
+lemed
+lemel
+lemes
+lemma
+lemme
+lemon
+lemur
+lends
+lenes
+lengs
+lenis
+lenos
+lense
+lenti
+lento
+leone
+lepak
+leper
+lepid
+lepra
+lepta
+lered
+leres
+lerps
+lesbo
+leses
+lesos
+lests
+letch
+lethe
+letty
+letup
+leuch
+leuco
+leuds
+leugh
+levas
+levee
+level
+lever
+leves
+levin
+levis
+lewis
+lexes
+lexis
+lezes
+lezza
+lezzo
+lezzy
+liana
+liane
+liang
+liard
+liars
+liart
+libel
+liber
+libor
+libra
+libre
+libri
+licet
+lichi
+licht
+licit
+licks
+lidar
+lidos
+liefs
+liege
+liens
+liers
+lieus
+lieve
+lifer
+lifes
+lifey
+lifts
+ligan
+liger
+ligge
+light
+ligne
+liked
+liken
+liker
+likes
+likin
+lilac
+lills
+lilos
+lilts
+lilty
+liman
+limas
+limax
+limba
+limbi
+limbo
+limbs
+limby
+limed
+limen
+limes
+limey
+limit
+limma
+limns
+limos
+limpa
+limps
+linac
+linch
+linds
+lindy
+lined
+linen
+liner
+lines
+liney
+linga
+lingo
+lings
+lingy
+linin
+links
+linky
+linns
+linny
+linos
+lints
+linty
+linum
+linux
+lions
+lipas
+lipes
+lipid
+lipin
+lipos
+lippy
+liras
+lirks
+lirot
+lises
+lisks
+lisle
+lisps
+lists
+litai
+litas
+lited
+litem
+liter
+lites
+lithe
+litho
+liths
+litie
+litre
+lived
+liven
+liver
+lives
+livid
+livor
+livre
+liwaa
+liwas
+llama
+llano
+loach
+loads
+loafs
+loams
+loamy
+loans
+loast
+loath
+loave
+lobar
+lobby
+lobed
+lobes
+lobos
+lobus
+local
+loche
+lochs
+lochy
+locie
+locis
+locks
+locky
+locos
+locum
+locus
+loden
+lodes
+lodge
+loess
+lofts
+lofty
+logan
+loges
+loggy
+logia
+logic
+logie
+login
+logoi
+logon
+logos
+lohan
+loids
+loins
+loipe
+loirs
+lokes
+lokey
+lokum
+lolas
+loled
+lollo
+lolls
+lolly
+lolog
+lolos
+lomas
+lomed
+lomes
+loner
+longa
+longe
+longs
+looby
+looed
+looey
+loofa
+loofs
+looie
+looks
+looky
+looms
+loons
+loony
+loops
+loopy
+loord
+loose
+loots
+loped
+loper
+lopes
+loppy
+loral
+loran
+lords
+lordy
+lorel
+lores
+loric
+loris
+lorry
+losed
+losel
+losen
+loser
+loses
+lossy
+lotah
+lotas
+lotes
+lotic
+lotos
+lotsa
+lotta
+lotte
+lotto
+lotus
+loued
+lough
+louie
+louis
+louma
+lound
+louns
+loupe
+loups
+loure
+lours
+loury
+louse
+lousy
+louts
+lovat
+loved
+lovee
+lover
+loves
+lovey
+lovie
+lowan
+lowed
+lowen
+lower
+lowes
+lowly
+lownd
+lowne
+lowns
+lowps
+lowry
+lowse
+lowth
+lowts
+loxed
+loxes
+loyal
+lozen
+luach
+luaus
+lubed
+lubes
+lubra
+luces
+lucid
+lucks
+lucky
+lucre
+ludes
+ludic
+ludos
+luffa
+luffs
+luged
+luger
+luges
+lulls
+lulus
+lumas
+lumbi
+lumen
+lumme
+lummy
+lumps
+lumpy
+lunar
+lunas
+lunch
+lunes
+lunet
+lunge
+lungi
+lungs
+lunks
+lunts
+lupin
+lupus
+lurch
+lured
+lurer
+lures
+lurex
+lurgi
+lurgy
+lurid
+lurks
+lurry
+lurve
+luser
+lushy
+lusks
+lusts
+lusty
+lusus
+lutea
+luted
+luter
+lutes
+luvvy
+luxed
+luxer
+luxes
+lweis
+lyams
+lyard
+lyart
+lyase
+lycea
+lycee
+lycra
+lying
+lymes
+lymph
+lynch
+lynes
+lyres
+lyric
+lysed
+lyses
+lysin
+lysis
+lysol
+lyssa
+lyted
+lytes
+lythe
+lytic
+lytta
+maaed
+maare
+maars
+maban
+mabes
+macas
+macaw
+macca
+maced
+macer
+maces
+mache
+machi
+macho
+machs
+macka
+macks
+macle
+macon
+macro
+macte
+madal
+madam
+madar
+maddy
+madge
+madid
+madly
+mados
+madre
+maedi
+maerl
+mafia
+mafic
+mafts
+magas
+mages
+maggs
+magic
+magma
+magna
+magot
+magus
+mahal
+mahem
+mahis
+mahoe
+mahrs
+mahua
+mahwa
+maids
+maiko
+maiks
+maile
+maill
+mailo
+mails
+maims
+mains
+maire
+mairs
+maise
+maist
+maize
+majas
+majat
+majoe
+major
+majos
+makaf
+makai
+makan
+makar
+makee
+maker
+makes
+makie
+makis
+makos
+malae
+malai
+malam
+malar
+malas
+malax
+maleo
+males
+malic
+malik
+malis
+malky
+malls
+malms
+malmy
+malts
+malty
+malus
+malva
+malwa
+mamak
+mamas
+mamba
+mambo
+mambu
+mamee
+mamey
+mamie
+mamil
+mamma
+mammy
+manas
+manat
+mandi
+mands
+mandy
+maneb
+maned
+maneh
+manes
+manet
+manga
+mange
+mangi
+mango
+mangs
+mangy
+mania
+manic
+manie
+manis
+manks
+manky
+manly
+manna
+manny
+manoa
+manor
+manos
+manse
+manso
+manta
+mante
+manto
+mants
+manty
+manul
+manus
+manzo
+mapau
+mapes
+maple
+mapou
+mappy
+maqam
+maqui
+marae
+marah
+maral
+maran
+maras
+maray
+march
+marcs
+mards
+mardy
+mares
+marga
+marge
+margo
+margs
+maria
+marid
+maril
+marka
+marks
+marle
+marls
+marly
+marma
+marms
+maron
+maror
+marra
+marri
+marry
+marse
+marsh
+marts
+marua
+marvy
+masas
+mased
+maser
+mases
+masha
+mashy
+masks
+mason
+massa
+masse
+massy
+masts
+masty
+masur
+masus
+masut
+matai
+match
+mated
+mater
+mates
+matey
+mathe
+maths
+matin
+matlo
+matra
+matsu
+matte
+matts
+matty
+matza
+matzo
+mauby
+mauds
+mauka
+maula
+mauls
+maums
+maumy
+maund
+maunt
+mauri
+mausy
+mauts
+mauve
+mauvy
+mauzy
+maven
+mavie
+mavin
+mavis
+mawed
+mawks
+mawky
+mawla
+mawns
+mawps
+mawrs
+maxed
+maxes
+maxim
+maxis
+mayan
+mayas
+maybe
+mayed
+mayor
+mayos
+mayst
+mazac
+mazak
+mazar
+mazas
+mazed
+mazel
+mazer
+mazes
+mazet
+mazey
+mazut
+mbari
+mbars
+mbila
+mbira
+mbret
+mbube
+mbuga
+meads
+meake
+meaks
+meals
+mealy
+meane
+means
+meant
+meany
+meare
+mease
+meath
+meats
+meaty
+mebbe
+mebos
+mecca
+mecha
+mechs
+mecks
+mecum
+medal
+media
+medic
+medii
+medin
+medle
+meech
+meeds
+meeja
+meeps
+meers
+meets
+meffs
+meids
+meiko
+meils
+meins
+meint
+meiny
+meism
+meith
+mekka
+melam
+melas
+melba
+melch
+melds
+melee
+meles
+melic
+melik
+mells
+meloe
+melon
+melos
+melts
+melty
+memes
+memic
+memos
+menad
+mence
+mends
+mened
+menes
+menge
+mengs
+menil
+mensa
+mense
+mensh
+menta
+mento
+ments
+menus
+meous
+meows
+merch
+mercs
+mercy
+merde
+merds
+mered
+merel
+merer
+meres
+merge
+meril
+meris
+merit
+merks
+merle
+merls
+merry
+merse
+mersk
+mesad
+mesal
+mesas
+mesca
+mesel
+mesem
+meses
+meshy
+mesia
+mesic
+mesne
+meson
+messy
+mesto
+mesyl
+metal
+metas
+meted
+meteg
+metel
+meter
+metes
+methi
+metho
+meths
+methy
+metic
+metif
+metis
+metol
+metre
+metro
+metta
+meums
+meuse
+meved
+meves
+mewed
+mewls
+meynt
+mezes
+mezza
+mezze
+mezzo
+mgals
+mhorr
+miais
+miaou
+miaow
+miasm
+miaul
+micas
+miche
+michi
+micht
+micks
+micky
+micos
+micra
+micro
+middy
+midge
+midgy
+midis
+midst
+miens
+mieux
+mieve
+miffs
+miffy
+mifty
+miggs
+might
+migma
+migod
+mihas
+mihis
+mikan
+miked
+mikes
+mikos
+mikra
+mikva
+milch
+milds
+miler
+miles
+milfs
+milia
+milko
+milks
+milky
+mille
+mills
+milly
+milor
+milos
+milpa
+milts
+milty
+miltz
+mimed
+mimeo
+mimer
+mimes
+mimic
+mimis
+mimsy
+minae
+minar
+minas
+mince
+mincy
+mindi
+minds
+mined
+miner
+mines
+minge
+mingi
+mings
+mingy
+minim
+minis
+minke
+minks
+minny
+minor
+minos
+minse
+mints
+minty
+minus
+minxy
+miraa
+mirah
+mirch
+mired
+mires
+mirex
+mirid
+mirin
+mirkn
+mirks
+mirky
+mirls
+mirly
+miros
+mirrl
+mirrs
+mirth
+mirvs
+mirza
+misal
+misch
+misdo
+miser
+mises
+misgo
+misky
+misls
+misos
+missa
+missy
+misto
+mists
+misty
+mitas
+mitch
+miter
+mites
+mitey
+mitie
+mitis
+mitre
+mitry
+mitta
+mitts
+mivey
+mivvy
+mixed
+mixen
+mixer
+mixes
+mixie
+mixis
+mixte
+mixup
+miyas
+mizen
+mizes
+mizzy
+mmkay
+mneme
+moais
+moaky
+moals
+moana
+moans
+moany
+moars
+moats
+mobby
+mobed
+mobee
+mobes
+mobey
+mobie
+moble
+mobos
+mocap
+mocha
+mochi
+mochs
+mochy
+mocks
+mocky
+mocos
+mocus
+modal
+model
+modem
+moder
+modes
+modge
+modii
+modin
+modoc
+modom
+modus
+moeni
+moers
+mofos
+mogar
+mogas
+moggy
+mogos
+mogra
+mogue
+mogul
+mohar
+mohel
+mohos
+mohrs
+mohua
+mohur
+moile
+moils
+moira
+moire
+moist
+moits
+moity
+mojos
+moker
+mokes
+mokey
+mokis
+mokky
+mokos
+mokus
+molal
+molar
+molas
+molds
+moldy
+moled
+moler
+moles
+moley
+molie
+molla
+molle
+mollo
+molls
+molly
+moloi
+molos
+molto
+molts
+molue
+molvi
+molys
+momes
+momie
+momma
+momme
+mommy
+momos
+mompe
+momus
+monad
+monal
+monas
+monde
+mondo
+moner
+money
+mongo
+mongs
+monic
+monie
+monks
+monos
+monpe
+monte
+month
+monty
+moobs
+mooch
+moods
+moody
+mooed
+mooey
+mooks
+moola
+mooli
+mools
+mooly
+moong
+mooni
+moons
+moony
+moops
+moors
+moory
+moose
+mooth
+moots
+moove
+moped
+moper
+mopes
+mopey
+moppy
+mopsy
+mopus
+morae
+morah
+moral
+moran
+moras
+morat
+moray
+moree
+morel
+mores
+morgy
+moria
+morin
+mormo
+morna
+morne
+morns
+moron
+moror
+morph
+morra
+morro
+morse
+morts
+moruk
+mosed
+moses
+mosey
+mosks
+mosso
+mossy
+moste
+mosto
+mosts
+moted
+motel
+moten
+motes
+motet
+motey
+moths
+mothy
+motif
+motis
+moton
+motor
+motte
+motto
+motts
+motty
+motus
+motza
+mouch
+moues
+moufs
+mould
+moule
+mouls
+moult
+mouly
+mound
+mount
+moups
+mourn
+mouse
+moust
+mousy
+mouth
+moved
+mover
+moves
+movie
+mowas
+mowed
+mower
+mowie
+mowra
+moxas
+moxie
+moyas
+moyle
+moyls
+mozed
+mozes
+mozos
+mpret
+mrads
+msasa
+mtepe
+mucho
+mucic
+mucid
+mucin
+mucko
+mucks
+mucky
+mucor
+mucro
+mucus
+mudar
+muddy
+mudge
+mudif
+mudim
+mudir
+mudra
+muffs
+muffy
+mufti
+mugga
+muggs
+muggy
+mugho
+mugil
+mugos
+muhly
+muids
+muils
+muirs
+muiry
+muist
+mujik
+mukim
+mukti
+mulai
+mulch
+mulct
+muled
+mules
+muley
+mulga
+mulie
+mulla
+mulls
+mulse
+mulsh
+mumbo
+mumms
+mummy
+mumph
+mumps
+mumsy
+mumus
+munch
+munds
+mundu
+munga
+munge
+mungi
+mungo
+mungs
+mungy
+munia
+munis
+munja
+munjs
+munts
+muntu
+muons
+mural
+muras
+mured
+mures
+murex
+murgh
+murgi
+murid
+murks
+murky
+murls
+murly
+murra
+murre
+murri
+murrs
+murry
+murth
+murti
+muruk
+murva
+musar
+musca
+mused
+musee
+muser
+muses
+muset
+musha
+mushy
+music
+musit
+musks
+musky
+musos
+musse
+mussy
+musta
+musth
+musts
+musty
+mutas
+mutch
+muted
+muter
+mutes
+mutha
+mutic
+mutis
+muton
+mutti
+mutts
+mutum
+muvva
+muxed
+muxes
+muzak
+muzzy
+mvula
+mvule
+mvuli
+myall
+myals
+mylar
+mynah
+mynas
+myoid
+myoma
+myons
+myope
+myops
+myopy
+myrrh
+mysid
+mysie
+mythi
+myths
+mythy
+myxos
+mzees
+naams
+naans
+naats
+nabam
+nabby
+nabes
+nabis
+nabks
+nabla
+nabob
+nache
+nacho
+nacre
+nadas
+nadir
+naeve
+naevi
+naffs
+nagar
+nagas
+nages
+naggy
+nagor
+nahal
+naiad
+naibs
+naice
+naids
+naieo
+naifs
+naiks
+nails
+naily
+nains
+naios
+naira
+nairu
+naive
+najib
+nakas
+naked
+naker
+nakfa
+nalas
+naled
+nalla
+namad
+namak
+namaz
+named
+namer
+names
+namma
+namus
+nanas
+nance
+nancy
+nandu
+nanna
+nanny
+nanos
+nante
+nanti
+nanto
+nants
+nanty
+nanua
+napas
+naped
+napes
+napoh
+napoo
+nappa
+nappe
+nappy
+naras
+narco
+narcs
+nards
+nares
+naric
+naris
+narks
+narky
+narod
+narra
+narre
+nasal
+nashi
+nasho
+nasis
+nason
+nasty
+nasus
+natak
+natal
+natch
+nates
+natis
+natto
+natty
+natya
+nauch
+naunt
+naval
+navar
+naved
+navel
+naves
+navew
+navvy
+nawab
+nawal
+nazar
+nazes
+nazir
+nazis
+nazzy
+nduja
+neafe
+neals
+neant
+neaps
+nears
+neath
+neato
+neats
+nebby
+nebek
+nebel
+neche
+necks
+neddy
+neebs
+needs
+needy
+neefs
+neeld
+neele
+neemb
+neems
+neeps
+neese
+neeze
+nefie
+negri
+negro
+negus
+neifs
+neigh
+neist
+neive
+nelia
+nelis
+nelly
+nemas
+nemic
+nemns
+nempt
+nenes
+nenta
+neons
+neosa
+neoza
+neper
+nepit
+neral
+neram
+nerds
+nerdy
+nerfs
+nerka
+nerks
+nerol
+nerts
+nertz
+nerve
+nervy
+neski
+nests
+nesty
+netas
+netes
+netop
+netta
+netts
+netty
+neuks
+neume
+neums
+nevel
+never
+neves
+nevis
+nevus
+nevvy
+newbs
+newed
+newel
+newer
+newie
+newly
+newsy
+newts
+nexal
+nexin
+nexts
+nexum
+nexus
+ngaio
+ngaka
+ngana
+ngapi
+ngati
+ngege
+ngoma
+ngoni
+ngram
+ngwee
+nibby
+nicad
+niced
+nicer
+nicey
+niche
+nicht
+nicks
+nicky
+nicol
+nidal
+nided
+nides
+nidor
+nidus
+niece
+niefs
+niess
+nieve
+nifes
+niffs
+niffy
+nifle
+nifty
+niger
+nigga
+nighs
+night
+nigre
+nigua
+nihil
+nikab
+nikah
+nikau
+nilas
+nills
+nimbi
+nimbs
+nimby
+nimps
+niner
+nines
+ninja
+ninny
+ninon
+ninta
+ninth
+niopo
+nioza
+nipas
+nipet
+nippy
+niqab
+nirls
+nirly
+nisei
+nisin
+nisse
+nisus
+nital
+niter
+nites
+nitid
+niton
+nitre
+nitro
+nitry
+nitta
+nitto
+nitty
+nival
+nivas
+nivel
+nixed
+nixer
+nixes
+nixie
+nizam
+njirl
+nkosi
+nmoli
+nmols
+noahs
+nobby
+noble
+nobly
+nocks
+nodal
+noddy
+noded
+nodes
+nodum
+nodus
+noels
+noema
+noeme
+nogal
+noggs
+noggy
+nohow
+noias
+noils
+noily
+noint
+noire
+noirs
+noise
+noisy
+nokes
+noles
+nolle
+nolls
+nolos
+nomad
+nomas
+nomen
+nomes
+nomic
+nomoi
+nomos
+nonan
+nonas
+nonce
+noncy
+nonda
+nondo
+nones
+nonet
+nongs
+nonic
+nonis
+nonna
+nonno
+nonny
+nonyl
+noobs
+noois
+nooit
+nooks
+nooky
+noone
+noons
+noops
+noose
+noove
+nopal
+noria
+norie
+noris
+norks
+norma
+norms
+north
+nosed
+noser
+noses
+nosey
+noshi
+nosir
+notal
+notam
+notch
+noted
+noter
+notes
+notum
+nougs
+nouja
+nould
+noule
+nouls
+nouns
+nouny
+noups
+noust
+novae
+novas
+novel
+novia
+novio
+novum
+noway
+nowds
+nowed
+nowls
+nowts
+nowty
+noxal
+noxas
+noxes
+noyau
+noyed
+noyes
+nrtta
+nrtya
+nsima
+nubby
+nubia
+nucha
+nucin
+nuddy
+nuder
+nudes
+nudge
+nudgy
+nudie
+nudzh
+nuevo
+nuffs
+nugae
+nujol
+nuked
+nukes
+nulla
+nullo
+nulls
+nully
+numbs
+numen
+nummy
+numps
+nunks
+nunky
+nunny
+nunus
+nuque
+nurds
+nurdy
+nurls
+nurrs
+nurse
+nurts
+nurtz
+nused
+nuses
+nutso
+nutsy
+nutty
+nyaff
+nyala
+nyams
+nying
+nylon
+nymph
+nyong
+nyssa
+nyung
+nyuse
+nyuze
+oafos
+oaked
+oaken
+oaker
+oakum
+oared
+oarer
+oasal
+oases
+oasis
+oasts
+oaten
+oater
+oaths
+oaves
+obang
+obbos
+obeah
+obeli
+obese
+obeys
+obias
+obied
+obiit
+obits
+objet
+oboes
+obole
+oboli
+obols
+occam
+occur
+ocean
+ocher
+oches
+ochre
+ochry
+ocker
+ocote
+ocrea
+octad
+octal
+octan
+octas
+octet
+octic
+octli
+octyl
+oculi
+odahs
+odals
+odder
+oddly
+odeon
+odeum
+odism
+odist
+odium
+odoom
+odors
+odour
+odums
+odyle
+odyls
+ofays
+offal
+offed
+offer
+offie
+oflag
+often
+ofter
+ofuro
+ogams
+ogeed
+ogees
+oggin
+ogham
+ogive
+ogled
+ogler
+ogles
+ogmic
+ogres
+ohelo
+ohias
+ohing
+ohmic
+ohone
+oicks
+oidia
+oiled
+oiler
+oilet
+oinks
+oints
+oiran
+ojime
+okapi
+okays
+okehs
+okies
+oking
+okole
+okras
+okrug
+oktas
+olate
+olden
+older
+oldie
+oldly
+olehs
+oleic
+olein
+olent
+oleos
+oleum
+oleyl
+oligo
+olios
+oliva
+olive
+ollas
+ollav
+oller
+ollie
+ology
+olona
+olpae
+olpes
+omasa
+omber
+ombre
+ombus
+omdah
+omdas
+omdda
+omdeh
+omees
+omega
+omens
+omers
+omiai
+omits
+omlah
+ommel
+ommin
+omnes
+omovs
+omrah
+omuls
+oncer
+onces
+oncet
+oncus
+ondes
+ondol
+onely
+oners
+onery
+ongon
+onion
+onium
+onkus
+onlap
+onlay
+onmun
+onned
+onsen
+onset
+ontal
+ontic
+ooaas
+oobit
+oohed
+ooids
+oojah
+oomph
+oonts
+oopak
+ooped
+oopsy
+oorie
+ooses
+ootid
+ooyah
+oozed
+oozes
+oozie
+oozle
+opahs
+opals
+opens
+opepe
+opera
+opery
+opgaf
+opihi
+opine
+oping
+opium
+oppos
+opsat
+opsin
+opsit
+opted
+opter
+optic
+opzit
+orach
+oracy
+orals
+orang
+orans
+orant
+orate
+orbat
+orbed
+orbic
+orbit
+orcas
+orcin
+order
+ordie
+ordos
+oread
+orfes
+orful
+organ
+orgia
+orgic
+orgue
+oribi
+oriel
+origo
+orixa
+orles
+orlon
+orlop
+ormer
+ornee
+ornis
+orped
+orpin
+orris
+ortet
+ortho
+orval
+orzos
+osars
+oscar
+osetr
+oseys
+oshac
+osier
+oskin
+oslin
+osmic
+osmol
+osone
+ossia
+ostia
+otaku
+otary
+other
+othyl
+otium
+ottar
+otter
+ottos
+oubit
+ouche
+oucht
+oueds
+ouens
+ought
+ouija
+oulks
+oumas
+ounce
+oundy
+oupas
+ouped
+ouphe
+ouphs
+ourey
+ourie
+ousel
+ousia
+ousts
+outby
+outdo
+outed
+outen
+outer
+outgo
+outie
+outre
+outro
+outta
+ouzel
+ouzos
+ovals
+ovary
+ovate
+ovels
+ovens
+overs
+overt
+ovine
+ovism
+ovist
+ovoid
+ovoli
+ovolo
+ovule
+oware
+owari
+owche
+owers
+owies
+owing
+owled
+owler
+owlet
+owned
+owner
+ownio
+owres
+owrie
+owsen
+oxbow
+oxeas
+oxers
+oxeye
+oxide
+oxids
+oxies
+oxime
+oxims
+oxine
+oxlip
+oxman
+oxmen
+oxter
+oyama
+oyers
+ozeki
+ozena
+ozone
+ozzie
+paaho
+paals
+paans
+pacai
+pacas
+pacay
+paced
+pacer
+paces
+pacey
+pacha
+packs
+packy
+pacos
+pacta
+pacts
+padam
+padas
+paddo
+paddy
+padis
+padle
+padma
+padou
+padre
+padri
+paean
+paedo
+paeon
+pagan
+paged
+pager
+pages
+pagle
+pagne
+pagod
+pagri
+pahit
+pahos
+pahus
+paiks
+pails
+pains
+paint
+paipe
+paips
+paire
+pairs
+paisa
+paise
+pakay
+pakka
+pakki
+pakua
+pakul
+palak
+palar
+palas
+palay
+palea
+paled
+paler
+pales
+palet
+palis
+palki
+palla
+palls
+pallu
+pally
+palms
+palmy
+palpi
+palps
+palsa
+palsy
+palus
+pamby
+pampa
+panax
+pance
+panch
+panda
+pands
+pandy
+paned
+panel
+panes
+panga
+pangs
+panic
+panim
+panir
+panko
+panks
+panna
+panne
+panni
+panny
+pansy
+panto
+pants
+panty
+paoli
+paolo
+papad
+papal
+papas
+papaw
+paper
+papes
+papey
+pappi
+pappy
+papri
+parae
+paras
+parch
+parcs
+pardi
+pards
+pardy
+pared
+paren
+pareo
+parer
+pares
+pareu
+parev
+parge
+pargo
+parid
+paris
+parka
+parki
+parks
+parky
+parle
+parly
+parma
+parmo
+parms
+parol
+parps
+parra
+parrs
+parry
+parse
+parte
+parti
+parts
+party
+parve
+parvo
+pasag
+pasar
+pasch
+paseo
+pases
+pasha
+pashm
+paska
+pasmo
+paspy
+passe
+passu
+pasta
+paste
+pasts
+pasty
+patas
+patch
+pated
+patee
+patel
+paten
+pater
+pates
+paths
+patia
+patin
+patio
+patka
+patly
+patsy
+patta
+patte
+pattu
+patty
+patus
+pauas
+pauls
+pause
+pauxi
+pavan
+pavas
+paved
+paven
+paver
+paves
+pavid
+pavie
+pavin
+pavis
+pavon
+pavvy
+pawas
+pawaw
+pawed
+pawer
+pawks
+pawky
+pawls
+pawns
+paxes
+payed
+payee
+payer
+payor
+paysd
+peace
+peach
+peage
+peags
+peake
+peaks
+peaky
+peals
+peans
+peare
+pearl
+pears
+peart
+pease
+peasy
+peats
+peaty
+peavy
+peaze
+pebas
+pecan
+pechs
+pecia
+pecke
+pecks
+pecky
+pects
+pedal
+pedes
+pedis
+pedon
+pedos
+pedro
+peece
+peeks
+peeky
+peels
+peely
+peens
+peent
+peeoy
+peepe
+peeps
+peepy
+peers
+peery
+peeve
+peevo
+peggy
+peghs
+pegma
+pegos
+peine
+peins
+peise
+peisy
+peize
+pekan
+pekau
+pekea
+pekes
+pekid
+pekin
+pekoe
+pelas
+pelau
+pelch
+peles
+pelfs
+pells
+pelma
+pelog
+pelon
+pelsh
+pelta
+pelts
+pelus
+penal
+pence
+pends
+pendu
+pened
+penes
+pengo
+penie
+penis
+penks
+penna
+penne
+penni
+penny
+pense
+pensy
+pents
+peola
+peons
+peony
+pepla
+peple
+pepon
+pepos
+peppy
+pepsi
+pequi
+perae
+perai
+perce
+perch
+percs
+perdu
+perdy
+perea
+peres
+perfs
+peril
+peris
+perks
+perky
+perle
+perls
+perms
+permy
+perne
+perns
+perog
+perps
+perry
+perse
+persp
+perst
+perts
+perve
+pervo
+pervs
+pervy
+pesch
+pesky
+pesos
+pesta
+pesto
+pests
+pesty
+petal
+petar
+peter
+petit
+petos
+petre
+petri
+petti
+petto
+petty
+pewed
+pewee
+pewit
+peyse
+pfftt
+phage
+phang
+phare
+pharm
+phase
+phasm
+pheer
+pheme
+phene
+pheon
+phese
+phial
+phies
+phish
+phizz
+phlox
+phobe
+phoca
+phone
+phono
+phons
+phony
+phooh
+phooo
+phota
+photo
+phots
+photy
+phpht
+phubs
+phuts
+phutu
+phwat
+phyla
+phyle
+phyma
+phynx
+physa
+piais
+piani
+piano
+pians
+pibal
+pical
+picas
+piccy
+picey
+pichi
+picks
+picky
+picon
+picot
+picra
+picul
+piece
+pieds
+piend
+piers
+piert
+pieta
+piets
+piety
+piezo
+piggy
+pight
+pigly
+pigmy
+piing
+pikas
+pikau
+piked
+pikel
+piker
+pikes
+pikey
+pikis
+pikul
+pilae
+pilaf
+pilao
+pilar
+pilau
+pilaw
+pilch
+pilea
+piled
+pilei
+piler
+piles
+piley
+pilin
+pilis
+pills
+pilon
+pilot
+pilow
+pilum
+pilus
+pimas
+pimps
+pinas
+pinax
+pince
+pinch
+pinda
+pinds
+pined
+piner
+pines
+piney
+pinga
+pinge
+pingo
+pings
+pinko
+pinks
+pinky
+pinna
+pinny
+pinol
+pinon
+pinot
+pinta
+pinto
+pints
+pinup
+pions
+piony
+pious
+pioye
+pioys
+pipal
+pipas
+piped
+piper
+pipes
+pipet
+pipid
+pipis
+pipit
+pippy
+pipul
+pique
+piqui
+pirai
+pirks
+pirls
+pirns
+pirog
+pirre
+pirri
+pirrs
+pisco
+pises
+pisky
+pisos
+pissy
+piste
+pitas
+pitch
+piths
+pithy
+piton
+pitot
+pitso
+pitsu
+pitta
+pittu
+piuma
+piums
+pivos
+pivot
+pixel
+pixes
+pixie
+piyut
+pized
+pizer
+pizes
+pizza
+plaas
+place
+plack
+plaga
+plage
+plaid
+plaig
+plain
+plait
+planc
+plane
+planh
+plank
+plans
+plant
+plaps
+plash
+plasm
+plast
+plate
+plats
+platt
+platy
+plaud
+plaur
+plavs
+playa
+plays
+plaza
+plead
+pleas
+pleat
+plebe
+plebs
+pleck
+pleep
+plein
+plena
+plene
+pleno
+pleon
+plesh
+plets
+plews
+plexi
+plica
+plied
+plier
+plies
+pligs
+plims
+pling
+plink
+plips
+plish
+ploat
+ploce
+plock
+plods
+ploit
+plomb
+plong
+plonk
+plook
+ploot
+plops
+plore
+plots
+plotz
+plouk
+plout
+plows
+plowt
+ploye
+ploys
+pluck
+pluds
+plues
+pluff
+plugs
+pluke
+plumb
+plume
+plump
+plums
+plumy
+plung
+plunk
+pluot
+plups
+plush
+plute
+pluto
+pluty
+plyer
+pneus
+poach
+poaka
+poake
+poalo
+pobby
+poboy
+pocan
+poche
+pocho
+pocks
+pocky
+podal
+poddy
+podex
+podge
+podgy
+podia
+podos
+podus
+poems
+poena
+poeps
+poesy
+poete
+poets
+pogey
+pogge
+poggy
+pogos
+pogue
+pohed
+poilu
+poind
+point
+poire
+poise
+pokal
+poked
+poker
+pokes
+pokey
+pokie
+pokit
+polar
+poled
+poler
+poles
+poley
+polio
+polis
+polje
+polka
+polks
+pollo
+polls
+polly
+polos
+polts
+polyp
+polys
+pomas
+pombe
+pomes
+pomme
+pommy
+pomos
+pompa
+pomps
+ponce
+poncy
+ponds
+pondy
+pones
+poney
+ponga
+pongo
+pongs
+pongy
+ponks
+ponor
+ponto
+ponts
+ponty
+ponzu
+pooay
+pooch
+poods
+pooed
+pooey
+poofs
+poofy
+poohs
+poohy
+pooja
+pooka
+pooks
+pools
+pooly
+poons
+poopa
+poops
+poopy
+poori
+poort
+poots
+pooty
+poove
+poovy
+popes
+popia
+popos
+poppa
+poppy
+popsy
+popup
+porae
+poral
+porch
+pored
+porer
+pores
+porey
+porge
+porgy
+porin
+porks
+porky
+porno
+porns
+porny
+porta
+porte
+porth
+ports
+porty
+porus
+posca
+posed
+poser
+poses
+poset
+posey
+posho
+posit
+posol
+posse
+poste
+posts
+potae
+potai
+potch
+poted
+potes
+potin
+potoo
+potro
+potsy
+potto
+potts
+potty
+pouce
+pouch
+pouff
+poufs
+poufy
+pouis
+pouke
+pouks
+poule
+poulp
+poult
+pound
+poupe
+poupt
+pours
+pousy
+pouts
+pouty
+povos
+powan
+power
+powie
+powin
+powis
+powlt
+pownd
+powns
+powny
+powre
+powsy
+poxed
+poxes
+poyas
+poynt
+poyou
+poyse
+pozzy
+praam
+prads
+prags
+prahu
+prams
+prana
+prang
+prank
+praos
+praps
+prase
+prate
+prats
+pratt
+praty
+praus
+prawn
+prays
+preak
+predy
+preed
+preem
+preen
+prees
+preif
+preke
+prems
+premy
+prent
+preon
+preop
+preps
+presa
+prese
+press
+prest
+preta
+preux
+preve
+prexy
+preys
+prial
+prian
+price
+prick
+pricy
+pride
+pridy
+pried
+prief
+prier
+pries
+prigs
+prill
+prima
+prime
+primi
+primo
+primp
+prims
+primy
+pring
+prink
+print
+prion
+prior
+prise
+prism
+priss
+prius
+privy
+prize
+proal
+proas
+probe
+probs
+proby
+prodd
+prods
+proem
+profs
+progs
+proin
+proke
+prole
+proll
+promo
+proms
+prone
+prong
+pronk
+proof
+prook
+proot
+props
+prora
+prore
+prose
+proso
+pross
+prost
+prosy
+proto
+proud
+proul
+prove
+prowk
+prowl
+prows
+proxy
+proyn
+prude
+prune
+pruno
+prunt
+pruny
+pruta
+pryan
+pryer
+pryse
+psalm
+pseud
+pshaw
+pshut
+psias
+psion
+psoae
+psoai
+psoas
+psora
+psych
+psyop
+ptish
+ptype
+pubby
+pubco
+pubes
+pubic
+pubis
+pubsy
+pucan
+pucer
+puces
+pucka
+pucks
+puddy
+pudge
+pudgy
+pudic
+pudor
+pudsy
+pudus
+puers
+puffa
+puffs
+puffy
+puggy
+pugil
+puhas
+pujah
+pujas
+pukas
+puked
+puker
+pukes
+pukey
+pukka
+pukus
+pulao
+pulas
+puled
+puler
+pules
+pulik
+pulis
+pulka
+pulks
+pulli
+pulls
+pully
+pulmo
+pulps
+pulpy
+pulse
+pulus
+pulut
+pumas
+pumie
+pumps
+pumpy
+punas
+punce
+punch
+punga
+pungi
+pungo
+pungs
+pungy
+punim
+punji
+punka
+punks
+punky
+punny
+punto
+punts
+punty
+pupae
+pupal
+pupas
+pupil
+puppa
+puppy
+pupus
+purao
+purau
+purda
+purdy
+pured
+puree
+purer
+pures
+purga
+purge
+purin
+puris
+purls
+puros
+purps
+purpy
+purre
+purrs
+purry
+purse
+pursy
+purty
+puses
+pushy
+pusle
+pussy
+putas
+puter
+putid
+putin
+puton
+putos
+putti
+putto
+putts
+puttu
+putty
+putza
+puuko
+puyas
+puzel
+puzta
+pwned
+pyats
+pyets
+pygal
+pygmy
+pyins
+pylon
+pyned
+pynes
+pyoid
+pyots
+pyral
+pyran
+pyres
+pyrex
+pyric
+pyros
+pyrus
+pyuff
+pyxed
+pyxes
+pyxie
+pyxis
+pzazz
+qadis
+qaids
+qajaq
+qanat
+qapik
+qibla
+qilas
+qipao
+qophs
+qorma
+quabs
+quack
+quads
+quaff
+quags
+quail
+quair
+quais
+quake
+quaky
+quale
+qualm
+qualy
+quank
+quant
+quare
+quark
+quarl
+quart
+quash
+quasi
+quass
+quate
+quats
+quawk
+quaws
+quayd
+quays
+qubit
+quean
+queck
+queek
+queem
+queen
+queer
+quell
+queme
+quena
+quern
+query
+queso
+quest
+quete
+queue
+queyn
+queys
+queyu
+quibs
+quich
+quick
+quids
+quies
+quiet
+quiff
+quila
+quill
+quilt
+quims
+quina
+quine
+quink
+quino
+quins
+quint
+quipo
+quips
+quipu
+quire
+quirk
+quirl
+quirt
+quist
+quite
+quits
+quoad
+quods
+quoif
+quoin
+quois
+quoit
+quoll
+quonk
+quops
+quork
+quorl
+quota
+quote
+quoth
+quouk
+quoys
+quran
+qursh
+quyte
+raads
+raake
+rabat
+rabbi
+rabic
+rabid
+rabis
+raced
+racer
+races
+rache
+racks
+racon
+radar
+raddi
+raddy
+radge
+radgy
+radif
+radii
+radio
+radix
+radon
+rafee
+raffs
+raffy
+rafik
+rafiq
+rafts
+rafty
+ragas
+ragde
+raged
+ragee
+rager
+rages
+ragga
+raggs
+raggy
+ragis
+ragus
+rahed
+rahui
+raiah
+raias
+raids
+raike
+raiks
+raile
+rails
+raine
+rains
+rainy
+raird
+raise
+raita
+raith
+raits
+rajah
+rajas
+rajes
+raked
+rakee
+raker
+rakes
+rakhi
+rakia
+rakis
+rakki
+raksi
+rakus
+rales
+ralli
+rally
+ralph
+ramal
+ramee
+ramen
+rames
+ramet
+ramie
+ramin
+ramis
+rammy
+ramon
+ramps
+ramse
+ramsh
+ramus
+ranas
+rance
+ranch
+rando
+rands
+randy
+raned
+ranee
+ranes
+ranga
+range
+rangi
+rangs
+rangy
+ranid
+ranis
+ranke
+ranks
+ranns
+ranny
+ranse
+rants
+ranty
+raped
+rapee
+raper
+rapes
+raphe
+rapid
+rapin
+rappe
+rapso
+rared
+raree
+rarer
+rares
+rarks
+rasam
+rasas
+rased
+raser
+rases
+rasps
+raspy
+rasse
+rasta
+ratal
+ratan
+ratas
+ratch
+rated
+ratel
+rater
+rates
+ratha
+rathe
+raths
+ratio
+ratoo
+ratos
+ratti
+ratty
+ratus
+rauli
+rauns
+raupo
+raved
+ravel
+raven
+raver
+raves
+ravey
+ravin
+rawdy
+rawer
+rawin
+rawks
+rawly
+rawns
+raxed
+raxes
+rayah
+rayas
+rayed
+rayle
+rayls
+rayne
+rayon
+razai
+razed
+razee
+razer
+razes
+razet
+razoo
+razor
+reach
+react
+readd
+reads
+ready
+reais
+reaks
+realm
+realo
+reals
+reame
+reams
+reamy
+reans
+reaps
+reard
+rearm
+rears
+reast
+reata
+reate
+reave
+rebab
+rebar
+rebbe
+rebec
+rebel
+rebid
+rebit
+rebop
+rebud
+rebus
+rebut
+rebuy
+recal
+recap
+recce
+recco
+reccy
+recep
+recit
+recks
+recon
+recta
+recte
+recti
+recto
+recue
+recur
+recut
+redan
+redds
+reddy
+reded
+redes
+redia
+redid
+redif
+redig
+redip
+redly
+redon
+redos
+redox
+redry
+redub
+redug
+redux
+redye
+reeaf
+reech
+reede
+reeds
+reedy
+reefs
+reefy
+reeks
+reeky
+reels
+reely
+reems
+reens
+reerd
+reest
+reeve
+reeze
+refan
+refed
+refel
+refer
+reffo
+refis
+refit
+refix
+refly
+refry
+regal
+regar
+reges
+reget
+regex
+reggo
+regia
+regie
+regle
+regma
+regna
+regos
+regot
+regur
+rehab
+rehem
+reifs
+reify
+reign
+reiki
+reiks
+reine
+reing
+reink
+reins
+reird
+reist
+reive
+rejas
+rejig
+rejon
+reked
+rekes
+rekey
+relax
+relay
+relet
+relic
+relie
+relit
+rello
+relos
+reman
+remap
+remen
+remet
+remex
+remit
+remix
+remou
+renal
+renay
+rends
+rendu
+renew
+reney
+renga
+rengs
+renig
+renin
+renks
+renne
+renos
+rente
+rents
+reoil
+reorg
+repas
+repat
+repay
+repeg
+repel
+repen
+repin
+repla
+reply
+repos
+repot
+repps
+repro
+repun
+reput
+reran
+rerig
+rerun
+resam
+resat
+resaw
+resay
+resee
+reses
+reset
+resew
+resid
+resin
+resit
+resod
+resol
+resow
+resto
+rests
+resty
+resue
+resus
+retag
+retam
+retax
+retch
+retem
+retia
+retie
+retin
+retip
+retox
+retro
+retry
+reune
+reups
+reuse
+revel
+revet
+revie
+revow
+revue
+rewan
+rewax
+rewed
+rewet
+rewin
+rewon
+rewth
+rexes
+rezes
+rhabd
+rheas
+rheid
+rheme
+rheum
+rhies
+rhime
+rhine
+rhino
+rhody
+rhomb
+rhone
+rhumb
+rhyme
+rhymy
+rhyne
+rhyta
+riads
+rials
+riant
+riata
+riato
+ribas
+ribby
+ribes
+riced
+ricer
+rices
+ricey
+riche
+richt
+ricin
+ricks
+rider
+rides
+ridge
+ridgy
+ridic
+riels
+riems
+rieve
+rifer
+riffs
+riffy
+rifle
+rifte
+rifts
+rifty
+riggs
+right
+rigid
+rigmo
+rigol
+rigor
+rikka
+rikwa
+riled
+riles
+riley
+rille
+rills
+rilly
+rimae
+rimed
+rimer
+rimes
+rimon
+rimus
+rince
+rinds
+rindy
+rines
+ringe
+rings
+ringy
+rinks
+rinse
+rioja
+rione
+riots
+rioty
+riped
+ripen
+riper
+ripes
+ripps
+riqqs
+risen
+riser
+rises
+rishi
+risks
+risky
+risps
+rists
+risus
+rites
+rithe
+ritts
+ritzy
+rival
+rivas
+rived
+rivel
+riven
+river
+rives
+rivet
+riyal
+rizas
+roach
+roads
+roady
+roake
+roaky
+roams
+roans
+roany
+roars
+roary
+roast
+roate
+robbo
+robed
+rober
+robes
+robin
+roble
+robot
+robug
+robur
+roche
+rocks
+rocky
+roded
+rodeo
+rodes
+rodny
+roers
+rogan
+roger
+rogue
+roguy
+rohan
+rohes
+rohun
+rohus
+roids
+roils
+roily
+roins
+roist
+rojak
+rojis
+roked
+roker
+rokes
+rokey
+rokos
+rolag
+roleo
+roles
+rolfs
+rolls
+rolly
+romal
+roman
+romeo
+romer
+romps
+rompu
+rompy
+ronde
+rondo
+roneo
+rones
+ronin
+ronne
+ronte
+ronts
+ronuk
+roods
+roofs
+roofy
+rooks
+rooky
+rooms
+roomy
+roons
+roops
+roopy
+roosa
+roose
+roost
+roots
+rooty
+roped
+roper
+ropes
+ropey
+roque
+roral
+rores
+roric
+rorid
+rorie
+rorts
+rorty
+rosal
+rosco
+rosed
+roses
+roset
+rosha
+roshi
+rosin
+rosit
+rosps
+rossa
+rosso
+rosti
+rosts
+rotal
+rotan
+rotas
+rotch
+roted
+rotes
+rotis
+rotls
+roton
+rotor
+rotos
+rotta
+rotte
+rotto
+rotty
+rouen
+roues
+rouet
+roufs
+rouge
+rough
+rougy
+rouks
+rouky
+roule
+rouls
+roums
+round
+roups
+roupy
+rouse
+roust
+route
+routh
+routs
+roved
+roven
+rover
+roves
+rowan
+rowdy
+rowed
+rowel
+rowen
+rower
+rowet
+rowie
+rowme
+rownd
+rowns
+rowth
+rowts
+royal
+royet
+royne
+royst
+rozes
+rozet
+rozit
+ruach
+ruana
+rubai
+ruban
+rubby
+rubel
+rubes
+rubin
+rubio
+ruble
+rubli
+rubor
+rubus
+ruche
+ruchy
+rucks
+rudas
+rudds
+ruddy
+ruder
+rudes
+rudie
+rudis
+rueda
+ruers
+ruffe
+ruffs
+ruffy
+rufus
+rugae
+rugal
+rugas
+rugby
+ruggy
+ruice
+ruing
+ruins
+rukhs
+ruled
+ruler
+rules
+rully
+rumal
+rumba
+rumbo
+rumen
+rumes
+rumly
+rummy
+rumor
+rumpo
+rumps
+rumpy
+runce
+runch
+runds
+runed
+runer
+runes
+rungs
+runic
+runny
+runos
+runts
+runty
+runup
+ruote
+rupee
+rupia
+rural
+rurps
+rurus
+rusas
+ruses
+rushy
+rusks
+rusky
+rusma
+russe
+rusts
+rusty
+ruths
+rutin
+rutty
+ruvid
+ryals
+rybat
+ryiji
+ryijy
+ryked
+rykes
+rymer
+rymme
+rynds
+ryoti
+ryots
+ryper
+rypin
+rythe
+ryugi
+saags
+sabal
+sabed
+saber
+sabes
+sabha
+sabin
+sabir
+sabji
+sable
+sabos
+sabot
+sabra
+sabre
+sabzi
+sacks
+sacra
+sacre
+saddo
+saddy
+sades
+sadhe
+sadhu
+sadic
+sadis
+sadly
+sados
+sadza
+saeta
+safed
+safer
+safes
+sagar
+sagas
+sager
+sages
+saggy
+sagos
+sagum
+sahab
+saheb
+sahib
+saice
+saick
+saics
+saids
+saiga
+sails
+saims
+saine
+sains
+saint
+sairs
+saist
+saith
+sajou
+sakai
+saker
+sakes
+sakia
+sakis
+sakti
+salad
+salal
+salas
+salat
+salep
+sales
+salet
+salic
+salis
+salix
+salle
+sally
+salmi
+salol
+salon
+salop
+salpa
+salps
+salsa
+salse
+salto
+salts
+salty
+salud
+salue
+salut
+salve
+salvo
+saman
+samas
+samba
+sambo
+samek
+samel
+samen
+sames
+samey
+samfi
+samfu
+sammy
+sampi
+samps
+sanad
+sands
+sandy
+saned
+saner
+sanes
+sanga
+sangh
+sango
+sangs
+sanko
+sansa
+santo
+sants
+saola
+sapan
+sapid
+sapor
+sappy
+saran
+sards
+sared
+saree
+sarge
+sargo
+sarin
+sarir
+saris
+sarks
+sarky
+sarod
+saros
+sarus
+sarvo
+saser
+sasin
+sasse
+sassy
+satai
+satay
+sated
+satem
+sater
+sates
+satin
+satis
+satyr
+sauba
+sauce
+sauch
+saucy
+saugh
+sauls
+sault
+sauna
+saunf
+saunt
+saury
+saute
+sauts
+sauve
+saved
+saver
+saves
+savey
+savin
+savor
+savoy
+savvy
+sawah
+sawed
+sawer
+saxes
+sayas
+sayed
+sayee
+sayer
+sayid
+sayne
+sayon
+sayst
+sazes
+scabs
+scads
+scaff
+scags
+scail
+scala
+scald
+scale
+scall
+scalp
+scaly
+scamp
+scams
+scand
+scans
+scant
+scapa
+scape
+scapi
+scare
+scarf
+scarp
+scars
+scart
+scary
+scath
+scats
+scatt
+scaud
+scaup
+scaur
+scaws
+sceat
+scena
+scend
+scene
+scent
+schav
+schif
+schmo
+schul
+schwa
+scifi
+scind
+scion
+scire
+sclim
+scobe
+scody
+scoff
+scogs
+scold
+scone
+scoog
+scoop
+scoot
+scopa
+scope
+scops
+score
+scorn
+scorp
+scote
+scots
+scoug
+scoup
+scour
+scout
+scowl
+scowp
+scows
+scrab
+scrae
+scrag
+scram
+scran
+scrap
+scrat
+scraw
+scray
+scree
+screw
+scrim
+scrip
+scrob
+scrod
+scrog
+scroo
+scrow
+scrub
+scrum
+scuba
+scudi
+scudo
+scuds
+scuff
+scuft
+scugs
+sculk
+scull
+sculp
+sculs
+scums
+scups
+scurf
+scurs
+scuse
+scuta
+scute
+scuts
+scuzz
+scyes
+sdayn
+sdein
+seals
+seame
+seams
+seamy
+seans
+seare
+sears
+sease
+seats
+seaze
+sebum
+secco
+sechs
+sects
+sedan
+seder
+sedes
+sedge
+sedgy
+sedum
+seeds
+seedy
+seeks
+seeld
+seels
+seely
+seems
+seeps
+seepy
+seers
+sefer
+segar
+segas
+segni
+segno
+segol
+segos
+segue
+sehri
+seifs
+seils
+seine
+seirs
+seise
+seism
+seity
+seiza
+seize
+sekos
+sekts
+selah
+seles
+selfs
+selfy
+selky
+sella
+selle
+sells
+selva
+semas
+semee
+semen
+semes
+semie
+semis
+senas
+sends
+senes
+senex
+sengi
+senna
+senor
+sensa
+sense
+sensi
+sensu
+sente
+senti
+sents
+senvy
+senza
+sepad
+sepal
+sepia
+sepic
+sepoy
+seppo
+septa
+septs
+serac
+serai
+seral
+sered
+serer
+seres
+serfs
+serge
+seria
+seric
+serif
+serin
+serir
+serks
+seron
+serow
+serra
+serre
+serrs
+serry
+serum
+serve
+servo
+sesey
+sessa
+setae
+setal
+seter
+seths
+seton
+setts
+setup
+sevak
+seven
+sever
+sevir
+sewan
+sewar
+sewed
+sewel
+sewen
+sewer
+sewin
+sexed
+sexer
+sexes
+sexor
+sexto
+sexts
+seyen
+sezes
+shack
+shade
+shads
+shady
+shaft
+shags
+shahs
+shaka
+shake
+shako
+shakt
+shaky
+shale
+shall
+shalm
+shalt
+shaly
+shama
+shame
+shams
+shand
+shank
+shans
+shape
+shaps
+shard
+share
+shark
+sharn
+sharp
+shart
+shash
+shaul
+shave
+shawl
+shawm
+shawn
+shaws
+shaya
+shays
+shchi
+sheaf
+sheal
+shear
+sheas
+sheds
+sheel
+sheen
+sheep
+sheer
+sheet
+sheik
+shelf
+shell
+shend
+sheng
+shent
+sheol
+sherd
+shere
+shero
+shets
+sheva
+shewn
+shews
+shiai
+shied
+shiel
+shier
+shies
+shift
+shill
+shily
+shims
+shine
+shins
+shiny
+shiok
+ships
+shire
+shirk
+shirr
+shirs
+shirt
+shish
+shiso
+shist
+shite
+shits
+shiur
+shiva
+shive
+shivs
+shlep
+shlub
+shmek
+shmoe
+shoal
+shoat
+shock
+shoed
+shoer
+shoes
+shogi
+shogs
+shoji
+shojo
+shola
+shone
+shonk
+shook
+shool
+shoon
+shoos
+shoot
+shope
+shops
+shore
+shorl
+shorn
+short
+shote
+shots
+shott
+shoud
+shout
+shove
+showd
+shown
+shows
+showy
+shoyu
+shred
+shrew
+shris
+shrow
+shrub
+shrug
+shtar
+shtik
+shtum
+shtup
+shuba
+shuck
+shule
+shuln
+shuls
+shuns
+shunt
+shura
+shush
+shute
+shuts
+shwas
+shyer
+shyly
+sials
+sibbs
+sibia
+sibyl
+sices
+sicht
+sicko
+sicks
+sicky
+sidas
+sided
+sider
+sides
+sidey
+sidha
+sidhe
+sidle
+siege
+sield
+siens
+sient
+sieth
+sieur
+sieve
+sifts
+sighs
+sight
+sigil
+sigla
+sigma
+signa
+signs
+sigri
+sijos
+sikas
+siker
+sikes
+silds
+siled
+silen
+siler
+siles
+silex
+silks
+silky
+sills
+silly
+silos
+silts
+silty
+silva
+simar
+simas
+simba
+simis
+simps
+simul
+since
+sinds
+sined
+sines
+sinew
+singe
+sings
+sinhs
+sinks
+sinky
+sinsi
+sinus
+siped
+sipes
+sippy
+sired
+siree
+siren
+sires
+sirih
+siris
+siroc
+sirra
+sirup
+sisal
+sises
+sissy
+sista
+sists
+sitar
+sitch
+sited
+sites
+sithe
+sitka
+situp
+situs
+siver
+sixer
+sixes
+sixmo
+sixte
+sixth
+sixty
+sizar
+sized
+sizel
+sizer
+sizes
+skags
+skail
+skald
+skank
+skarn
+skart
+skate
+skats
+skatt
+skaws
+skean
+skear
+skeds
+skeed
+skeef
+skeen
+skeer
+skees
+skeet
+skeev
+skeez
+skegg
+skegs
+skein
+skelf
+skell
+skelm
+skelp
+skene
+skens
+skeos
+skeps
+skerm
+skers
+skets
+skews
+skids
+skied
+skier
+skies
+skiey
+skiff
+skill
+skimo
+skimp
+skims
+skink
+skins
+skint
+skios
+skips
+skirl
+skirr
+skirt
+skite
+skits
+skive
+skivy
+sklim
+skoal
+skobe
+skody
+skoff
+skofs
+skogs
+skols
+skool
+skort
+skosh
+skran
+skrik
+skroo
+skuas
+skugs
+skulk
+skull
+skunk
+skyed
+skyer
+skyey
+skyfs
+skyre
+skyrs
+skyte
+slabs
+slack
+slade
+slaes
+slags
+slaid
+slain
+slake
+slams
+slane
+slang
+slank
+slant
+slaps
+slart
+slash
+slate
+slats
+slaty
+slave
+slaws
+slays
+slebs
+sleds
+sleek
+sleep
+sleer
+sleet
+slept
+slews
+sleys
+slice
+slick
+slide
+slier
+slily
+slime
+slims
+slimy
+sling
+slink
+slipe
+slips
+slipt
+slish
+slits
+slive
+sloan
+slobs
+sloes
+slogs
+sloid
+slojd
+sloka
+slomo
+sloom
+sloop
+sloot
+slope
+slops
+slopy
+slorm
+slosh
+sloth
+slots
+slove
+slows
+sloyd
+slubb
+slubs
+slued
+slues
+sluff
+slugs
+sluit
+slump
+slums
+slung
+slunk
+slurb
+slurp
+slurs
+sluse
+slush
+sluts
+slyer
+slyly
+slype
+smaak
+smack
+smaik
+small
+smalm
+smalt
+smarm
+smart
+smash
+smaze
+smear
+smeek
+smees
+smeik
+smeke
+smell
+smelt
+smerk
+smews
+smick
+smile
+smily
+smirk
+smirr
+smirs
+smite
+smith
+smits
+smize
+smock
+smogs
+smoke
+smoko
+smoky
+smolt
+smoor
+smoot
+smore
+smorg
+smote
+smout
+smowt
+smugs
+smurs
+smush
+smuts
+snabs
+snack
+snafu
+snags
+snail
+snake
+snaky
+snaps
+snare
+snarf
+snark
+snarl
+snars
+snary
+snash
+snath
+snaws
+snead
+sneak
+sneap
+snebs
+sneck
+sneds
+sneed
+sneer
+snees
+snell
+snibs
+snick
+snide
+snied
+snies
+sniff
+snift
+snigs
+snipe
+snips
+snipy
+snirt
+snits
+snive
+snobs
+snods
+snoek
+snoep
+snogs
+snoke
+snood
+snook
+snool
+snoop
+snoot
+snore
+snort
+snots
+snout
+snowk
+snows
+snowy
+snubs
+snuck
+snuff
+snugs
+snush
+snyes
+soaks
+soaps
+soapy
+soare
+soars
+soave
+sobas
+sober
+socas
+soces
+socia
+socko
+socks
+socle
+sodas
+soddy
+sodic
+sodom
+sofar
+sofas
+softa
+softs
+softy
+soger
+soggy
+sohur
+soils
+soily
+sojas
+sojus
+sokah
+soken
+sokes
+sokol
+solah
+solan
+solar
+solas
+solde
+soldi
+soldo
+solds
+soled
+solei
+soler
+soles
+solid
+solon
+solos
+solum
+solus
+solve
+soman
+somas
+sonar
+sonce
+sonde
+sones
+songo
+songs
+songy
+sonic
+sonly
+sonne
+sonny
+sonse
+sonsy
+sooey
+sooks
+sooky
+soole
+sools
+sooms
+soops
+soote
+sooth
+soots
+sooty
+sophs
+sophy
+sopor
+soppy
+sopra
+soral
+soras
+sorbi
+sorbo
+sorbs
+sorda
+sordo
+sords
+sored
+soree
+sorel
+sorer
+sores
+sorex
+sorgo
+sorns
+sorra
+sorry
+sorta
+sorts
+sorus
+soths
+sotol
+sotto
+souce
+souct
+sough
+souks
+souls
+souly
+soums
+sound
+soups
+soupy
+sours
+souse
+south
+souts
+sowar
+sowce
+sowed
+sower
+sowff
+sowfs
+sowle
+sowls
+sowms
+sownd
+sowne
+sowps
+sowse
+sowth
+soxes
+soyas
+soyle
+soyuz
+sozin
+space
+spack
+spacy
+spade
+spado
+spads
+spaed
+spaer
+spaes
+spags
+spahi
+spail
+spain
+spait
+spake
+spald
+spale
+spall
+spalt
+spams
+spane
+spang
+spank
+spans
+spard
+spare
+spark
+spars
+spart
+spasm
+spate
+spats
+spaul
+spawl
+spawn
+spaws
+spayd
+spays
+spaza
+spazz
+speak
+speal
+spean
+spear
+speat
+speck
+specs
+spect
+speed
+speel
+speer
+speil
+speir
+speks
+speld
+spelk
+spell
+spelt
+spend
+spent
+speos
+sperm
+spesh
+spets
+speug
+spews
+spewy
+spial
+spica
+spice
+spick
+spics
+spicy
+spide
+spied
+spiel
+spier
+spies
+spiff
+spifs
+spike
+spiks
+spiky
+spile
+spill
+spilt
+spims
+spina
+spine
+spink
+spins
+spiny
+spire
+spirt
+spiry
+spite
+spits
+spitz
+spivs
+splat
+splay
+split
+splog
+spode
+spods
+spoil
+spoke
+spoof
+spook
+spool
+spoom
+spoon
+spoor
+spoot
+spore
+spork
+sport
+sposa
+sposh
+sposo
+spots
+spout
+sprad
+sprag
+sprat
+spray
+spred
+spree
+sprew
+sprig
+sprit
+sprod
+sprog
+sprue
+sprug
+spuds
+spued
+spuer
+spues
+spugs
+spule
+spume
+spumy
+spunk
+spurn
+spurs
+spurt
+sputa
+spyal
+spyre
+squab
+squad
+squat
+squaw
+squee
+squeg
+squib
+squid
+squit
+squiz
+srsly
+stabs
+stack
+stade
+staff
+stage
+stags
+stagy
+staid
+staig
+stain
+stair
+stake
+stale
+stalk
+stall
+stamp
+stand
+stane
+stang
+stank
+stans
+staph
+staps
+stare
+stark
+starn
+starr
+stars
+start
+stary
+stash
+state
+stats
+statu
+staun
+stave
+staws
+stays
+stead
+steak
+steal
+steam
+stean
+stear
+stedd
+stede
+steds
+steed
+steek
+steel
+steem
+steen
+steep
+steer
+steez
+steik
+steil
+stein
+stela
+stele
+stell
+steme
+stems
+stend
+steno
+stens
+stent
+steps
+stept
+stere
+stern
+stets
+stews
+stewy
+steys
+stich
+stick
+stied
+sties
+stiff
+stilb
+stile
+still
+stilt
+stime
+stims
+stimy
+sting
+stink
+stint
+stipa
+stipe
+stire
+stirk
+stirp
+stirs
+stive
+stivy
+stoae
+stoai
+stoas
+stoat
+stobs
+stock
+stoep
+stogs
+stogy
+stoic
+stoit
+stoke
+stole
+stoln
+stoma
+stomp
+stond
+stone
+stong
+stonk
+stonn
+stony
+stood
+stook
+stool
+stoop
+stoor
+stope
+stops
+stopt
+store
+stork
+storm
+story
+stoss
+stots
+stott
+stoun
+stoup
+stour
+stout
+stove
+stown
+stowp
+stows
+strad
+strae
+strag
+strak
+strap
+straw
+stray
+strep
+strew
+stria
+strig
+strim
+strip
+strop
+strow
+stroy
+strum
+strut
+stubs
+stuck
+stucs
+stude
+studs
+study
+stuff
+stull
+stulm
+stumm
+stump
+stums
+stung
+stunk
+stuns
+stunt
+stupa
+stupe
+sture
+sturt
+stush
+styed
+styes
+style
+styli
+stylo
+styme
+stymy
+styre
+styte
+suave
+subah
+subak
+subas
+subby
+suber
+subha
+succi
+sucks
+sucky
+sucre
+sudan
+sudds
+sudor
+sudsy
+suede
+suent
+suers
+suete
+suets
+suety
+sugan
+sugar
+sughs
+sugos
+suhur
+suids
+suing
+suint
+suite
+suits
+sujee
+sukhs
+sukis
+sukuk
+sulci
+sulfa
+sulfo
+sulks
+sulky
+sulls
+sully
+sulph
+sulus
+sumac
+sumis
+summa
+sumos
+sumph
+sumps
+sunis
+sunks
+sunna
+sunns
+sunny
+sunts
+sunup
+suona
+suped
+super
+supes
+supra
+surah
+sural
+suras
+surat
+surds
+sured
+surer
+sures
+surfs
+surfy
+surge
+surgy
+surly
+surra
+sused
+suses
+sushi
+susus
+sutor
+sutra
+sutta
+swabs
+swack
+swads
+swage
+swags
+swail
+swain
+swale
+swaly
+swami
+swamp
+swamy
+swang
+swank
+swans
+swaps
+swapt
+sward
+sware
+swarf
+swarm
+swart
+swash
+swath
+swats
+swayl
+sways
+sweal
+swear
+sweat
+swede
+sweed
+sweel
+sweep
+sweer
+swees
+sweet
+sweir
+swell
+swelt
+swept
+swerf
+sweys
+swies
+swift
+swigs
+swile
+swill
+swims
+swine
+swing
+swink
+swipe
+swire
+swirl
+swish
+swiss
+swith
+swits
+swive
+swizz
+swobs
+swole
+swoll
+swoln
+swoon
+swoop
+swops
+swopt
+sword
+swore
+sworn
+swots
+swoun
+swung
+sybbe
+sybil
+syboe
+sybow
+sycee
+syces
+sycon
+syeds
+syens
+syker
+sykes
+sylis
+sylph
+sylva
+symar
+synch
+syncs
+synds
+syned
+synes
+synod
+synth
+syped
+sypes
+syphs
+syrah
+syren
+syrup
+sysop
+sythe
+syver
+taals
+taata
+tabac
+tabby
+taber
+tabes
+tabid
+tabis
+tabla
+table
+tabls
+taboo
+tabor
+tabos
+tabun
+tabus
+tacan
+taces
+tacet
+tache
+tachi
+tacho
+tachs
+tacit
+tacks
+tacky
+tacos
+tacts
+tadah
+taels
+taffy
+tafia
+taggy
+tagma
+tagua
+tahas
+tahrs
+taiga
+taigs
+taiko
+tails
+tains
+taint
+taira
+taish
+taits
+tajes
+takas
+taken
+taker
+takes
+takhi
+takht
+takin
+takis
+takky
+talak
+talaq
+talar
+talas
+talcs
+talcy
+talea
+taler
+tales
+talik
+talks
+talky
+talls
+tally
+talma
+talon
+talpa
+taluk
+talus
+tamal
+tamas
+tamed
+tamer
+tames
+tamin
+tamis
+tammy
+tamps
+tanas
+tanga
+tangi
+tango
+tangs
+tangy
+tanhs
+tania
+tanka
+tanks
+tanky
+tanna
+tansu
+tansy
+tante
+tanti
+tanto
+tanty
+tapas
+taped
+tapen
+taper
+tapes
+tapet
+tapir
+tapis
+tappa
+tapus
+taras
+tardo
+tards
+tardy
+tared
+tares
+targa
+targe
+tarka
+tarns
+taroc
+tarok
+taros
+tarot
+tarps
+tarre
+tarry
+tarse
+tarsi
+tarte
+tarts
+tarty
+tarzy
+tasar
+tasca
+tased
+taser
+tases
+tasks
+tassa
+tasse
+tasso
+taste
+tasto
+tasty
+tatar
+tater
+tates
+taths
+tatie
+tatou
+tatts
+tatty
+tatus
+taube
+tauld
+taunt
+tauon
+taupe
+tauts
+tauty
+tavah
+tavas
+taver
+tawaf
+tawai
+tawas
+tawed
+tawer
+tawie
+tawny
+tawse
+tawts
+taxed
+taxer
+taxes
+taxis
+taxol
+taxon
+taxor
+taxus
+tayra
+tazza
+tazze
+teach
+teade
+teads
+teaed
+teaks
+teals
+teams
+tears
+teary
+tease
+teats
+teaze
+techs
+techy
+tecta
+tecum
+teddy
+teels
+teems
+teend
+teene
+teens
+teeny
+teers
+teeth
+teets
+teffs
+teggs
+tegua
+tegus
+tehee
+tehrs
+teiid
+teils
+teind
+teins
+tekke
+telae
+telco
+teles
+telex
+telia
+telic
+tells
+telly
+teloi
+telos
+temed
+temes
+tempi
+tempo
+temps
+tempt
+temse
+tench
+tends
+tendu
+tenes
+tenet
+tenge
+tenia
+tenne
+tenno
+tenny
+tenon
+tenor
+tense
+tenth
+tents
+tenty
+tenue
+tepal
+tepas
+tepee
+tepid
+tepoy
+terai
+teras
+terce
+terek
+teres
+terfe
+terfs
+terga
+terms
+terne
+terns
+terra
+terre
+terry
+terse
+terts
+terza
+tesla
+testa
+teste
+tests
+testy
+tetes
+teths
+tetra
+tetri
+teuch
+teugh
+tewed
+tewel
+tewit
+texas
+texes
+texta
+texts
+thack
+thagi
+thaim
+thale
+thali
+thana
+thane
+thang
+thank
+thans
+thanx
+tharm
+thars
+thaws
+thawt
+thawy
+thebe
+theca
+theed
+theek
+thees
+theft
+thegn
+theic
+thein
+their
+thelf
+thema
+theme
+thens
+theor
+theow
+there
+therm
+these
+thesp
+theta
+thete
+thews
+thewy
+thick
+thief
+thigh
+thigs
+thilk
+thill
+thine
+thing
+think
+thins
+thiol
+third
+thirl
+thoft
+thole
+tholi
+thong
+thorn
+thoro
+thorp
+those
+thots
+thous
+thowl
+thrae
+thraw
+three
+threw
+thrid
+thrip
+throb
+throe
+throw
+thrum
+thuds
+thugs
+thuja
+thumb
+thump
+thunk
+thurl
+thuya
+thyme
+thymi
+thymy
+tians
+tiara
+tiare
+tiars
+tibia
+tical
+ticca
+ticed
+tices
+tichy
+ticks
+ticky
+tidal
+tiddy
+tided
+tides
+tiefs
+tiers
+tiffs
+tifos
+tifts
+tiger
+tiges
+tight
+tigon
+tikas
+tikes
+tikia
+tikis
+tikka
+tilak
+tilde
+tiled
+tiler
+tiles
+tills
+tilly
+tilth
+tilts
+timbo
+timed
+timer
+times
+timid
+timon
+timps
+tinas
+tinct
+tinds
+tinea
+tined
+tines
+tinge
+tings
+tinks
+tinny
+tinto
+tints
+tinty
+tipis
+tippy
+tipsy
+tipup
+tired
+tires
+tirls
+tiros
+tirrs
+tirth
+titan
+titar
+titas
+titch
+titer
+tithe
+tithi
+titin
+titir
+titis
+title
+titre
+titty
+titup
+tiyin
+tiyns
+tizes
+tizzy
+toads
+toady
+toast
+toaze
+tocks
+tocky
+tocos
+today
+todde
+toddy
+todea
+todos
+toeas
+toffs
+toffy
+tofts
+tofus
+togae
+togas
+toged
+toges
+togue
+tohos
+toidy
+toile
+toils
+toing
+toise
+toits
+toity
+tokay
+toked
+token
+toker
+tokes
+tokos
+tolan
+tolar
+tolas
+toled
+toles
+tolls
+tolly
+tolts
+tolus
+tolyl
+toman
+tombo
+tombs
+tomen
+tomes
+tomia
+tomin
+tomme
+tommy
+tomos
+tomoz
+tonal
+tondi
+tondo
+toned
+toner
+tones
+toney
+tonga
+tongs
+tonic
+tonka
+tonks
+tonne
+tonus
+tools
+tooms
+toons
+tooth
+toots
+topaz
+toped
+topee
+topek
+toper
+topes
+tophe
+tophi
+tophs
+topic
+topis
+topoi
+topos
+toppy
+toque
+torah
+toran
+toras
+torch
+torcs
+tores
+toric
+torii
+toros
+torot
+torrs
+torse
+torsi
+torsk
+torso
+torta
+torte
+torts
+torus
+tosas
+tosed
+toses
+toshy
+tossy
+tosyl
+total
+toted
+totem
+toter
+totes
+totty
+touch
+tough
+touks
+touns
+tours
+touse
+tousy
+touts
+touze
+touzy
+towai
+towed
+towel
+tower
+towie
+towno
+towns
+towny
+towse
+towsy
+towts
+towze
+towzy
+toxic
+toxin
+toyed
+toyer
+toyon
+toyos
+tozed
+tozes
+tozie
+trabs
+trace
+track
+tract
+trade
+trads
+trady
+traga
+tragi
+trags
+tragu
+traik
+trail
+train
+trait
+tramp
+trams
+trank
+tranq
+trans
+trant
+trape
+trapo
+traps
+trapt
+trash
+trass
+trats
+tratt
+trave
+trawl
+trayf
+trays
+tread
+treat
+treck
+treed
+treen
+trees
+trefa
+treif
+treks
+trema
+trems
+trend
+tress
+trest
+trets
+trews
+treyf
+treys
+triac
+triad
+trial
+tribe
+trice
+trick
+tride
+tried
+trier
+tries
+trifa
+triff
+trigo
+trigs
+trike
+trild
+trill
+trims
+trine
+trins
+triol
+trior
+trios
+tripe
+trips
+tripy
+trist
+trite
+troad
+troak
+troat
+trock
+trode
+trods
+trogs
+trois
+troke
+troll
+tromp
+trona
+tronc
+trone
+tronk
+trons
+troop
+trooz
+trope
+tropo
+troth
+trots
+trout
+trove
+trows
+troys
+truce
+truck
+trued
+truer
+trues
+trugo
+trugs
+trull
+truly
+trump
+trunk
+truss
+trust
+truth
+tryer
+tryke
+tryma
+tryps
+tryst
+tsade
+tsadi
+tsars
+tsked
+tsuba
+tsubo
+tuans
+tuart
+tuath
+tubae
+tubal
+tubar
+tubas
+tubby
+tubed
+tuber
+tubes
+tucks
+tufas
+tuffe
+tuffs
+tufts
+tufty
+tugra
+tuile
+tuina
+tuism
+tuktu
+tules
+tulip
+tulle
+tulpa
+tulps
+tulsi
+tumid
+tummy
+tumor
+tumps
+tumpy
+tunas
+tunds
+tuned
+tuner
+tunes
+tungs
+tunic
+tunny
+tupek
+tupik
+tuple
+tuque
+turbo
+turds
+turfs
+turfy
+turks
+turme
+turms
+turns
+turnt
+turon
+turps
+turrs
+tushy
+tusks
+tusky
+tutee
+tutes
+tutor
+tutti
+tutty
+tutus
+tuxes
+tuyer
+twaes
+twain
+twals
+twang
+twank
+twats
+tways
+tweak
+tweed
+tweel
+tween
+tweep
+tweer
+tweet
+twerk
+twerp
+twice
+twier
+twigs
+twill
+twilt
+twine
+twink
+twins
+twiny
+twire
+twirk
+twirl
+twirp
+twist
+twite
+twits
+twixt
+twocs
+twoer
+twonk
+twyer
+tyees
+tyers
+tying
+tyiyn
+tykes
+tyler
+tymps
+tynde
+tyned
+tynes
+typal
+typed
+types
+typey
+typic
+typos
+typps
+typto
+tyran
+tyred
+tyres
+tyros
+tythe
+tzars
+ubacs
+ubity
+udals
+udder
+udons
+udyog
+ugali
+ugged
+uhlan
+uhuru
+ukase
+ulama
+ulans
+ulcer
+ulema
+ulmin
+ulmos
+ulnad
+ulnae
+ulnar
+ulnas
+ulpan
+ultra
+ulvas
+ulyie
+ulzie
+umami
+umbel
+umber
+umble
+umbos
+umbra
+umbre
+umiac
+umiak
+umiaq
+ummah
+ummas
+ummed
+umped
+umphs
+umpie
+umpty
+umrah
+umras
+unagi
+unais
+unapt
+unarm
+unary
+unaus
+unbag
+unban
+unbar
+unbed
+unbid
+unbox
+uncap
+unces
+uncia
+uncle
+uncos
+uncoy
+uncus
+uncut
+undam
+undee
+under
+undid
+undos
+undue
+undug
+uneth
+unfed
+unfit
+unfix
+ungag
+unget
+ungod
+ungot
+ungum
+unhat
+unhip
+unica
+unify
+union
+unios
+unite
+units
+unity
+unjam
+unked
+unket
+unkey
+unkid
+unkut
+unlap
+unlaw
+unlay
+unled
+unleg
+unlet
+unlid
+unlit
+unmad
+unman
+unmet
+unmew
+unmix
+unode
+unold
+unown
+unpay
+unpeg
+unpen
+unpin
+unply
+unpot
+unput
+unred
+unrid
+unrig
+unrip
+unsaw
+unsay
+unsee
+unset
+unsew
+unsex
+unsod
+unsub
+untag
+untax
+untie
+until
+untin
+unwed
+unwet
+unwit
+unwon
+unzip
+upbow
+upbye
+updos
+updry
+upend
+upful
+upjet
+uplay
+upled
+uplit
+upped
+upper
+upran
+uprun
+upsee
+upset
+upsey
+uptak
+upter
+uptie
+uraei
+urali
+uraos
+urare
+urari
+urase
+urate
+urban
+urbex
+urbia
+urdee
+ureal
+ureas
+uredo
+ureic
+ureid
+urena
+urent
+urged
+urger
+urges
+urial
+urine
+urite
+urman
+urnal
+urned
+urped
+ursae
+ursid
+urson
+urubu
+urupa
+urvas
+usage
+usens
+users
+useta
+usher
+using
+usnea
+usnic
+usque
+ustad
+uster
+usual
+usure
+usurp
+usury
+uteri
+utero
+utile
+utter
+uveal
+uveas
+uvula
+vacas
+vacay
+vacua
+vacui
+vacuo
+vadas
+vaded
+vades
+vadge
+vagal
+vague
+vagus
+vaids
+vails
+vaire
+vairs
+vairy
+vajra
+vakas
+vakil
+vales
+valet
+valid
+valis
+valli
+valor
+valse
+value
+valve
+vamps
+vampy
+vanda
+vaned
+vanes
+vanga
+vangs
+vants
+vaped
+vaper
+vapes
+vapid
+vapor
+varan
+varas
+varda
+vardo
+vardy
+varec
+vares
+varia
+varix
+varna
+varus
+varve
+vasal
+vases
+vasts
+vasty
+vatas
+vatha
+vatic
+vatje
+vatos
+vatus
+vauch
+vault
+vaunt
+vaute
+vauts
+vawte
+vaxes
+veale
+veals
+vealy
+veena
+veeps
+veers
+veery
+vegan
+vegas
+veges
+veggo
+vegie
+vegos
+vehme
+veils
+veily
+veins
+veiny
+velar
+velds
+veldt
+veles
+vells
+velum
+venae
+venal
+venas
+vends
+vendu
+veney
+venge
+venin
+venom
+venti
+vents
+venue
+venus
+verba
+verbs
+verde
+verge
+verra
+verre
+verry
+versa
+verse
+verso
+verst
+verte
+verts
+vertu
+verve
+vespa
+vesta
+vests
+vetch
+veuve
+veves
+vexed
+vexer
+vexes
+vexil
+vezir
+vials
+viand
+vibed
+vibes
+vibex
+vibey
+vicar
+viced
+vices
+vichy
+vicus
+video
+viers
+vieux
+views
+viewy
+vifda
+viffs
+vigas
+vigia
+vigil
+vigor
+vilde
+viler
+villa
+ville
+villi
+vills
+vimen
+vinal
+vinas
+vinca
+vined
+viner
+vines
+vinew
+vinho
+vinic
+vinny
+vinos
+vints
+vinyl
+viola
+viold
+viols
+viper
+viral
+vired
+vireo
+vires
+virga
+virge
+virgo
+virid
+virls
+virtu
+virus
+visas
+vised
+vises
+visie
+visit
+visna
+visne
+vison
+visor
+vista
+visto
+vitae
+vital
+vitas
+vitex
+vitro
+vitta
+vivas
+vivat
+vivda
+viver
+vives
+vivid
+vivos
+vivre
+vixen
+vizir
+vizor
+vlast
+vleis
+vlies
+vlogs
+voars
+vobla
+vocab
+vocal
+voces
+voddy
+vodka
+vodou
+vodun
+voema
+vogie
+vogue
+voice
+voici
+voids
+voila
+voile
+voips
+volae
+volar
+voled
+voles
+volet
+volke
+volks
+volta
+volte
+volti
+volts
+volva
+volve
+vomer
+vomit
+voted
+voter
+votes
+vouch
+vouge
+voulu
+vowed
+vowel
+vower
+voxel
+voxes
+vozhd
+vraic
+vrils
+vroom
+vrous
+vrouw
+vrows
+vuggs
+vuggy
+vughs
+vughy
+vulgo
+vulns
+vulva
+vutty
+vygie
+vying
+waacs
+wacke
+wacko
+wacks
+wacky
+wadas
+wadds
+waddy
+waded
+wader
+wades
+wadge
+wadis
+wadts
+wafer
+waffs
+wafts
+waged
+wager
+wages
+wagga
+wagon
+wagyu
+wahay
+wahey
+wahoo
+waide
+waifs
+waift
+wails
+wains
+wairs
+waist
+waite
+waits
+waive
+wakas
+waked
+waken
+waker
+wakes
+wakfs
+waldo
+walds
+waled
+waler
+wales
+walie
+walis
+walks
+walla
+walls
+wally
+walty
+waltz
+wamed
+wames
+wamus
+wands
+waned
+wanes
+waney
+wangs
+wanks
+wanky
+wanle
+wanly
+wanna
+wanta
+wants
+wanty
+wanze
+waqfs
+warbs
+warby
+wards
+wared
+wares
+warez
+warks
+warms
+warns
+warps
+warre
+warst
+warts
+warty
+wases
+washi
+washy
+wasms
+wasps
+waspy
+waste
+wasts
+watap
+watch
+water
+watts
+wauff
+waugh
+wauks
+waulk
+wauls
+waurs
+waved
+waver
+waves
+wavey
+wawas
+wawes
+wawls
+waxed
+waxen
+waxer
+waxes
+wayed
+wazir
+wazoo
+weald
+weals
+weamb
+weans
+wears
+weary
+weave
+webby
+weber
+wecht
+wedel
+wedge
+wedgy
+weeds
+weedy
+weeis
+weeke
+weeks
+weels
+weems
+weens
+weeny
+weeps
+weepy
+weest
+weete
+weets
+wefte
+wefts
+weids
+weigh
+weils
+weird
+weirs
+weise
+weize
+wekas
+welch
+welds
+welke
+welks
+welkt
+wells
+welly
+welsh
+welts
+wembs
+wench
+wends
+wenge
+wenny
+wents
+werfs
+weros
+wersh
+wests
+wetas
+wetly
+wexed
+wexes
+whack
+whale
+whamo
+whams
+whang
+whaps
+whare
+wharf
+whata
+whats
+whaup
+whaur
+wheal
+whear
+wheat
+wheek
+wheel
+wheen
+wheep
+wheft
+whelk
+whelm
+whelp
+whens
+where
+whets
+whews
+wheys
+which
+whids
+whies
+whiff
+whift
+whigs
+while
+whilk
+whims
+whine
+whins
+whiny
+whios
+whips
+whipt
+whirl
+whirr
+whirs
+whish
+whisk
+whiss
+whist
+white
+whits
+whity
+whizz
+whole
+whomp
+whoof
+whoop
+whoot
+whops
+whore
+whorl
+whort
+whose
+whoso
+whows
+whump
+whups
+whyda
+wicca
+wicks
+wicky
+widdy
+widen
+wider
+wides
+widow
+width
+wield
+wiels
+wifed
+wifes
+wifey
+wifie
+wifts
+wifty
+wigan
+wigga
+wiggy
+wight
+wikis
+wilco
+wilds
+wiled
+wiles
+wilga
+wilis
+wilja
+wills
+willy
+wilts
+wimps
+wimpy
+wince
+winch
+winds
+windy
+wined
+wines
+winey
+winge
+wings
+wingy
+winks
+winky
+winna
+winns
+winos
+winze
+wiped
+wiper
+wipes
+wired
+wirer
+wires
+wirra
+wirri
+wised
+wiser
+wises
+wisha
+wisht
+wisps
+wispy
+wists
+witan
+witch
+wited
+wites
+withe
+withs
+withy
+witty
+wived
+wiver
+wives
+wizen
+wizes
+wizzo
+woads
+woady
+woald
+wocks
+wodge
+wodgy
+woful
+wojus
+woken
+woker
+wokka
+wolds
+wolfs
+wolly
+wolve
+woman
+womas
+wombs
+womby
+women
+womyn
+wonga
+wongi
+wonks
+wonky
+wonts
+woods
+woody
+wooed
+wooer
+woofs
+woofy
+woold
+wools
+wooly
+woons
+woops
+woopy
+woose
+woosh
+wootz
+woozy
+words
+wordy
+works
+worky
+world
+worms
+wormy
+worry
+worse
+worst
+worth
+worts
+would
+wound
+woven
+wowed
+wowee
+wowse
+woxen
+wrack
+wrang
+wraps
+wrapt
+wrast
+wrate
+wrath
+wrawl
+wreak
+wreck
+wrens
+wrest
+wrick
+wried
+wrier
+wries
+wring
+wrist
+write
+writs
+wroke
+wrong
+wroot
+wrote
+wroth
+wrung
+wryer
+wryly
+wuddy
+wudus
+wuffs
+wulls
+wunga
+wurst
+wuses
+wushu
+wussy
+wuxia
+wyled
+wyles
+wynds
+wynns
+wyted
+wytes
+wythe
+xebec
+xenia
+xenic
+xenon
+xeric
+xerox
+xerus
+xoana
+xolos
+xrays
+xviii
+xylan
+xylem
+xylic
+xylol
+xylyl
+xysti
+xysts
+yaars
+yaass
+yabas
+yabba
+yabby
+yacca
+yacht
+yacka
+yacks
+yadda
+yaffs
+yager
+yages
+yagis
+yagna
+yahoo
+yaird
+yajna
+yakka
+yakow
+yales
+yamen
+yampa
+yampy
+yamun
+yandy
+yangs
+yanks
+yapok
+yapon
+yapps
+yappy
+yarak
+yarco
+yards
+yarer
+yarfa
+yarks
+yarns
+yarra
+yarrs
+yarta
+yarto
+yates
+yatra
+yauds
+yauld
+yaups
+yawed
+yawey
+yawls
+yawns
+yawny
+yawps
+yayas
+ybore
+yclad
+ycled
+ycond
+ydrad
+ydred
+yeads
+yeahs
+yealm
+yeans
+yeard
+yearn
+years
+yeast
+yecch
+yechs
+yechy
+yedes
+yeeds
+yeeek
+yeesh
+yeggs
+yelks
+yells
+yelms
+yelps
+yelts
+yenta
+yente
+yerba
+yerds
+yerks
+yeses
+yesks
+yests
+yesty
+yetis
+yetts
+yeuch
+yeuks
+yeuky
+yeven
+yeves
+yewen
+yexed
+yexes
+yfere
+yield
+yiked
+yikes
+yills
+yince
+yipes
+yippy
+yirds
+yirks
+yirrs
+yirth
+yites
+yitie
+ylems
+ylide
+ylids
+ylike
+ylkes
+ymolt
+ympes
+yobbo
+yobby
+yocks
+yodel
+yodhs
+yodle
+yogas
+yogee
+yoghs
+yogic
+yogin
+yogis
+yohah
+yohay
+yoick
+yojan
+yokan
+yoked
+yokeg
+yokel
+yoker
+yokes
+yokul
+yolks
+yolky
+yolps
+yomim
+yomps
+yonic
+yonis
+yonks
+yonny
+yoofs
+yoops
+yopos
+yoppo
+yores
+yorga
+yorks
+yorps
+youks
+young
+yourn
+yours
+yourt
+youse
+youth
+yowed
+yowes
+yowie
+yowls
+yowsa
+yowza
+yoyos
+yrapt
+yrent
+yrivd
+yrneh
+ysame
+ytost
+yuans
+yucas
+yucca
+yucch
+yucko
+yucks
+yucky
+yufts
+yugas
+yuked
+yukes
+yukky
+yukos
+yulan
+yules
+yummo
+yummy
+yumps
+yupon
+yuppy
+yurta
+yurts
+yuzus
+zabra
+zacks
+zaida
+zaide
+zaidy
+zaire
+zakat
+zamac
+zamak
+zaman
+zambo
+zamia
+zamis
+zanja
+zante
+zanza
+zanze
+zappy
+zarda
+zarfs
+zaris
+zatis
+zawns
+zaxes
+zayde
+zayin
+zazen
+zeals
+zebec
+zebra
+zebub
+zebus
+zedas
+zeera
+zeins
+zendo
+zerda
+zerks
+zeros
+zests
+zesty
+zetas
+zexes
+zezes
+zhomo
+zhush
+zhuzh
+zibet
+ziffs
+zigan
+zikrs
+zilas
+zilch
+zilla
+zills
+zimbi
+zimbs
+zinco
+zincs
+zincy
+zineb
+zines
+zings
+zingy
+zinke
+zinky
+zinos
+zippo
+zippy
+ziram
+zitis
+zitty
+zizel
+zizit
+zlote
+zloty
+zoaea
+zobos
+zobus
+zocco
+zoeae
+zoeal
+zoeas
+zoism
+zoist
+zokor
+zolle
+zombi
+zonae
+zonal
+zonda
+zoned
+zoner
+zones
+zonks
+zooea
+zooey
+zooid
+zooks
+zooms
+zoomy
+zoons
+zooty
+zoppa
+zoppo
+zoril
+zoris
+zorro
+zorse
+zouks
+zowee
+zowie
+zulus
+zupan
+zupas
+zuppa
+zurfs
+zuzim
+zygal
+zygon
+zymes
+zymic
diff --git a/public/zoomscreenshare.png b/public/zoomscreenshare.png
new file mode 100644
index 0000000..3050294
Binary files /dev/null and b/public/zoomscreenshare.png differ
diff --git a/src/App.css b/src/App.css
new file mode 100644
index 0000000..b9d355d
--- /dev/null
+++ b/src/App.css
@@ -0,0 +1,42 @@
+#root {
+ max-width: 1280px;
+ margin: 0 auto;
+ padding: 2rem;
+ text-align: center;
+}
+
+.logo {
+ height: 6em;
+ padding: 1.5em;
+ will-change: filter;
+ transition: filter 300ms;
+}
+.logo:hover {
+ filter: drop-shadow(0 0 2em #646cffaa);
+}
+.logo.react:hover {
+ filter: drop-shadow(0 0 2em #61dafbaa);
+}
+
+@keyframes logo-spin {
+ from {
+ transform: rotate(0deg);
+ }
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+@media (prefers-reduced-motion: no-preference) {
+ a:nth-of-type(2) .logo {
+ animation: logo-spin infinite 20s linear;
+ }
+}
+
+.card {
+ padding: 2em;
+}
+
+.read-the-docs {
+ color: #888;
+}
diff --git a/src/App.tsx b/src/App.tsx
new file mode 100644
index 0000000..4c74568
--- /dev/null
+++ b/src/App.tsx
@@ -0,0 +1,28 @@
+import { Toaster } from "@/components/ui/toaster";
+import { Toaster as Sonner } from "@/components/ui/sonner";
+import { TooltipProvider } from "@/components/ui/tooltip";
+import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
+import { BrowserRouter, Routes, Route } from "react-router-dom";
+import Index from "./pages/index";
+import ErrorPage from "./pages/ErrorPage";
+
+const queryClient = new QueryClient();
+
+const App = () => (
+
+
+
+
+
+
+ } />
+ } />
+ {/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */}
+ } />
+
+
+
+
+);
+
+export default App;
diff --git a/src/components/NavLink.tsx b/src/components/NavLink.tsx
new file mode 100644
index 0000000..d94d547
--- /dev/null
+++ b/src/components/NavLink.tsx
@@ -0,0 +1,32 @@
+import { NavLink as RouterNavLink, NavLinkProps } from "react-router-dom";
+import { forwardRef } from "react";
+import { cn } from "@/lib/utils";
+
+interface NavLinkCompatProps extends Omit {
+ className?: string;
+ activeClassName?: string;
+ pendingClassName?: string;
+}
+
+const NavLink = forwardRef(
+ ({ className, activeClassName, pendingClassName, to, ...props }, ref) => {
+ return (
+
+ cn(
+ className,
+ isActive && activeClassName,
+ isPending && pendingClassName,
+ )
+ }
+ {...props}
+ />
+ );
+ },
+);
+
+NavLink.displayName = "NavLink";
+
+export { NavLink };
diff --git a/src/components/game/BossBaby.tsx b/src/components/game/BossBaby.tsx
new file mode 100644
index 0000000..e4405fc
--- /dev/null
+++ b/src/components/game/BossBaby.tsx
@@ -0,0 +1,119 @@
+import React, { useEffect, useState } from "react";
+import { Baby } from "lucide-react";
+
+interface BossBabyProps {
+ message: string;
+ onDismiss: () => void;
+ autoAdvanceDelay?: number;
+ altButton?: { label: string; onAlt: () => void };
+ dismissLabel?: string;
+}
+
+export const BossBaby: React.FC = ({
+ message,
+ onDismiss,
+ autoAdvanceDelay,
+ altButton,
+ dismissLabel,
+}) => {
+ const [displayedText, setDisplayedText] = useState("");
+ const [index, setIndex] = useState(0);
+
+ // Typewriter Effect
+ useEffect(() => {
+ if (index < message.length) {
+ const timeout = setTimeout(() => {
+ setDisplayedText((prev) => prev + message[index]);
+ setIndex(index + 1);
+ }, 25); // typing speed
+ return () => clearTimeout(timeout);
+ }
+ }, [index, message]);
+
+ // Auto-advance after typing completes
+ useEffect(() => {
+ if (
+ autoAdvanceDelay !== undefined &&
+ displayedText === message &&
+ message.length > 0
+ ) {
+ const t = setTimeout(onDismiss, autoAdvanceDelay);
+ return () => clearTimeout(t);
+ }
+ }, [displayedText, message, autoAdvanceDelay, onDismiss]);
+
+ return (
+
+
+ {/* XP Title Bar */}
+
+
+

+
+ LIAR... CHEATER... FIRED.
+
+
+
+ {/*
+
+
+ {/* Dialogue Body */}
+
+
+ {/* Left: Dialogue Text */}
+
+
+ {displayedText}
+ β
+
+
+ {/* Continue Button β hidden when auto-advancing */}
+ {displayedText === message && autoAdvanceDelay === undefined && (
+
+ {altButton && (
+
+ )}
+
+
+ )}
+
+
+ {/* Right: Character */}
+
+
+

+
+
+ {/* Name Tag */}
+
+ Boss Baby
+
+
+
+
+
+
+ );
+};
diff --git a/src/components/game/DesktopIcons.tsx b/src/components/game/DesktopIcons.tsx
new file mode 100644
index 0000000..cfbc793
--- /dev/null
+++ b/src/components/game/DesktopIcons.tsx
@@ -0,0 +1,50 @@
+import React from "react";
+import {
+ Monitor,
+ Trash2,
+ FolderOpen,
+ FileSpreadsheet,
+ MessageSquare,
+ Calendar,
+} from "lucide-react";
+
+const icons = [
+ { icon:
, label: "My Computer", bg: "#1a6db5" },
+ { icon:
, label: "Recycle Bin", bg: "#6b7280" },
+ { icon:
, label: "My Documents", bg: "#d97706" },
+ {
+ icon:
,
+ label: "Sprint_FINAL_v3.xls",
+ bg: "#16a34a",
+ },
+ { icon:
, label: "Slack", bg: "#7c3aed" },
+ { icon:
, label: "Standup.exe", bg: "#dc2626" },
+];
+
+export const DesktopIcons: React.FC = () => {
+ const isMobile = typeof window !== "undefined" && window.innerWidth < 768;
+ if (isMobile) return null;
+ return (
+
+ {icons.map((item) => (
+
+
+ {item.icon}
+
+
+ {item.label}
+
+
+ ))}
+
+ );
+};
diff --git a/src/components/game/DraggableWindow.tsx b/src/components/game/DraggableWindow.tsx
new file mode 100644
index 0000000..1687c2d
--- /dev/null
+++ b/src/components/game/DraggableWindow.tsx
@@ -0,0 +1,107 @@
+import React, { useState, useRef, useCallback } from "react";
+import { X } from "lucide-react";
+
+interface DraggableWindowProps {
+ title: string;
+ icon?: React.ReactNode;
+ children: React.ReactNode;
+ onClose?: () => void;
+ width?: number;
+ height?: number;
+ initialX?: number;
+ initialY?: number;
+ active?: boolean;
+ closable?: boolean;
+ bodyStyle?: React.CSSProperties;
+}
+
+export const DraggableWindow: React.FC
= ({
+ title,
+ icon,
+ children,
+ onClose,
+ width = 400,
+ height,
+ initialX,
+ initialY,
+ active = true,
+ closable = true,
+ bodyStyle,
+}) => {
+ const isMobile = typeof window !== "undefined" && window.innerWidth < 768;
+ const effectiveWidth = isMobile
+ ? Math.min(width, window.innerWidth - 16)
+ : width;
+
+ const [pos, setPos] = useState({
+ x: isMobile
+ ? Math.max(8, (window.innerWidth - effectiveWidth) / 2)
+ : (initialX ??
+ Math.max(
+ 50,
+ (window.innerWidth - width) / 2 + Math.random() * 60 - 30,
+ )),
+ y: isMobile
+ ? 155
+ : (initialY ??
+ Math.max(30, window.innerHeight / 2 - 200 + Math.random() * 60 - 30)),
+ });
+ const dragging = useRef(false);
+ const offset = useRef({ x: 0, y: 0 });
+
+ const onMouseDown = useCallback(
+ (e: React.MouseEvent) => {
+ if (isMobile) return;
+ dragging.current = true;
+ offset.current = { x: e.clientX - pos.x, y: e.clientY - pos.y };
+
+ const onMove = (ev: MouseEvent) => {
+ if (dragging.current) {
+ setPos({
+ x: ev.clientX - offset.current.x,
+ y: ev.clientY - offset.current.y,
+ });
+ }
+ };
+ const onUp = () => {
+ dragging.current = false;
+ window.removeEventListener("mousemove", onMove);
+ window.removeEventListener("mouseup", onUp);
+ };
+ window.addEventListener("mousemove", onMove);
+ window.addEventListener("mouseup", onUp);
+ },
+ [pos, isMobile],
+ );
+
+ return (
+
+
+
+ {icon}
+ {title}
+
+
+ {closable && (
+
+ )}
+
+
+
+ {children}
+
+
+ );
+};
diff --git a/src/components/game/EndScreen.tsx b/src/components/game/EndScreen.tsx
new file mode 100644
index 0000000..241b424
--- /dev/null
+++ b/src/components/game/EndScreen.tsx
@@ -0,0 +1,119 @@
+import React, { useEffect, useState } from "react";
+import { PartyPopper, Frown } from "lucide-react";
+
+interface EndScreenProps {
+ type: "fired" | "promoted";
+ onRestart: () => void;
+}
+
+const CONFETTI_COLORS = [
+ "#f72585",
+ "#7209b7",
+ "#3a0ca3",
+ "#4361ee",
+ "#4cc9f0",
+ "#f77f00",
+ "#fcbf49",
+];
+
+export const EndScreen: React.FC = ({ type, onRestart }) => {
+ const [confetti, setConfetti] = useState<
+ { id: number; x: number; color: string; delay: number; size: number }[]
+ >([]);
+
+ useEffect(() => {
+ if (type === "fired") {
+ setConfetti(
+ Array.from({ length: 50 }, (_, i) => ({
+ id: i,
+ x: Math.random() * 100,
+ color:
+ CONFETTI_COLORS[Math.floor(Math.random() * CONFETTI_COLORS.length)],
+ delay: Math.random() * 2,
+ size: Math.random() * 8 + 4,
+ })),
+ );
+ }
+ }, [type]);
+
+ if (type === "fired") {
+ return (
+
+ {confetti.map((c) => (
+
0.5 ? "50%" : "0",
+ }}
+ />
+ ))}
+
+
+
Office Simulator.exe
+
Γ
+
+
+
+
+ YOU'RE FIRED!
+
+
+ Congratulations! You successfully avoided all productivity and
+ earned your freedom.
+
+
+
+
+
+ );
+ }
+
+ return (
+
+
+
+
+
+
+ WOW. CONGRATULATIONS.
+
+
+ You were way too competent at your job. As a
+ reward, you've been promoted to
+
+
+ Senior Vice President of Meetings
+
+
+
+ Dream big. Now spend forever in back-to-back status calls.
+
+
+
+
+
+ );
+};
diff --git a/src/components/game/FailMeter.tsx b/src/components/game/FailMeter.tsx
new file mode 100644
index 0000000..8074ab8
--- /dev/null
+++ b/src/components/game/FailMeter.tsx
@@ -0,0 +1,232 @@
+import React from "react";
+import { STAGE_METER_POINT_CUTOF } from "@/pages/index";
+
+interface FailMeterProps {
+ value: number; // -100 (FIRED) to +100 (PROMOTED)
+}
+
+export const FailMeter: React.FC
= ({ value }) => {
+ const angle = 90 - (value / 100) * 90;
+ const radians = (angle * Math.PI) / 180;
+
+ const cx = 130;
+ const cy = 115;
+ const r = 95;
+ const needleX = cx + r * 0.82 * Math.cos(radians);
+ const needleY = cy - r * 0.82 * Math.sin(radians);
+
+ const status =
+ value <= -STAGE_METER_POINT_CUTOF
+ ? "CRITICAL"
+ : value <= STAGE_METER_POINT_CUTOF
+ ? "NEUTRAL"
+ : "EXCELLENT";
+
+ const statusColor =
+ value <= -STAGE_METER_POINT_CUTOF
+ ? "hsl(0, 70%, 50%)"
+ : value <= STAGE_METER_POINT_CUTOF
+ ? "hsl(45, 90%, 50%)"
+ : "hsl(120, 60%, 40%)";
+
+ return (
+
+
+
+ π₯ Fire-O-Meterβ’
+
+
+
+ {/* Sunken panel */}
+
+ {/* Label bar */}
+
+ AM I GETTING FIRED?
+
+
+ {/* viewBox starts at y=-15 to give clearance above the arc top */}
+
+
+ {/* Status readout */}
+
+ Status:
+
+ {status}
+
+
+ [{value > 0 ? "+" : ""}
+ {value}]
+
+
+
+
+
+ );
+};
diff --git a/src/components/game/HowToPlay.tsx b/src/components/game/HowToPlay.tsx
new file mode 100644
index 0000000..230be2a
--- /dev/null
+++ b/src/components/game/HowToPlay.tsx
@@ -0,0 +1,32 @@
+import React from "react";
+
+interface HowToPlayProps {
+ title: string;
+ instructions: string[];
+ onStart: () => void;
+}
+
+export const HowToPlay: React.FC = ({
+ title,
+ instructions,
+ onStart,
+}) => {
+ return (
+
+
+ π How to Play: {title}
+
+
+ {instructions.map((inst, i) => (
+ -
+ {i + 1}.
+ {inst}
+
+ ))}
+
+
+
+ );
+};
diff --git a/src/components/game/IntroScreen.tsx b/src/components/game/IntroScreen.tsx
new file mode 100644
index 0000000..ce1e2b4
--- /dev/null
+++ b/src/components/game/IntroScreen.tsx
@@ -0,0 +1,212 @@
+import { Settings } from "lucide-react";
+import React, { useState } from "react";
+
+interface IntroScreenProps {
+ onStart: () => void;
+ skipTutorials: boolean;
+ setSkipTutorials: (skip: boolean) => void;
+ volume: number;
+ setVolume: (value: number) => void;
+}
+
+export const IntroScreen: React.FC = ({
+ onStart,
+ skipTutorials,
+ setSkipTutorials,
+ volume,
+ setVolume,
+}) => {
+ const [settingsOpen, setSettingsOpen] = useState(false);
+ const isMobile = typeof window !== "undefined" && window.innerWidth < 768;
+ const isLandscape =
+ typeof window !== "undefined" && window.innerWidth > window.innerHeight;
+ const isMobileLandscape = isMobile && isLandscape;
+ const settingsPanelWidth = isMobile
+ ? Math.max(180, window.innerWidth - 80)
+ : 320;
+
+ return (
+
+
+
+
+
+
+
+

+
Manager - Workstation Alert
+
+
+
+
+
+
+
+ LIAR...
+
+
+ CHEATER...
+
+
+ FIRED.
+
+
+
+
+
+
+
+
+
+ "I hate liars and cheaters. Why are you hired if you don't
+ do your job?{" "}
+ Focus on work!"
+
+
+
+
+
+
+
+

+
+
+ Boss Baby
+
+
+
+
+
+
+
+
+
+
+
+
+ (Disclaimer: This is not representative of us developers; we are
+ very, very, very good employees.)
+
+
+
+
+
+
+ Tutorials
+
+
+
+
+ Volume
+
+ setVolume(Number(event.target.value) / 100)
+ }
+ className="w-32 accent-primary"
+ />
+
+ {Math.round(volume * 100)}%
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/src/components/game/OutlookMockup.tsx b/src/components/game/OutlookMockup.tsx
new file mode 100644
index 0000000..8b7f85e
--- /dev/null
+++ b/src/components/game/OutlookMockup.tsx
@@ -0,0 +1,256 @@
+import React, { useMemo } from "react";
+
+const UNREAD_EMAILS = [
+ {
+ from: "Michael (VP)",
+ subject: "RE: RE: RE: Q3 Sprint Planning - URGENT",
+ },
+ {
+ from: "Sandra (HR)",
+ subject: "Mandatory Fun: Team Building Next Friday",
+ },
+ {
+ from: "Dave (ED)",
+ subject: "Quick sync? (will take 2 hrs)",
+ },
+ {
+ from: "Karen (SE)",
+ subject: "Budget cuts - please review ASAP",
+ },
+ {
+ from: "Brian (VP)",
+ subject: "Why is prod down again???",
+ },
+ { from: "Tom (MD)", subject: "Can you stay late tonight?" },
+ {
+ from: "Jenny (ED)",
+ subject: "Git blame says this is your fault",
+ },
+];
+
+const READ_EMAILS = [
+ {
+ from: "IT Support",
+ subject: "Your password expires in 1 day",
+ time: "Yesterday",
+ },
+ {
+ from: "Noreply (HR)",
+ subject: "Updated: Holiday policy 2026 (please read)",
+ time: "Yesterday",
+ },
+ {
+ from: "Michael (VP)",
+ subject: "RE: Team offsite β venue confirmed",
+ time: "Mon",
+ },
+ {
+ from: "All Staff",
+ subject: "Reminder: submit timesheets by Friday",
+ time: "Mon",
+ },
+ {
+ from: "Facilities",
+ subject: "AC on floor 2 is fixed (finally)",
+ time: "Sun",
+ },
+];
+
+interface OutlookMockupProps {
+ onPlayAgain: () => void;
+}
+
+export const OutlookMockup: React.FC = ({
+ onPlayAgain,
+}) => {
+ const unreadEmails = useMemo(() => {
+ const now = Date.now();
+ const oneDayMs = 24 * 60 * 60 * 1000;
+ const minOffsetMs = 60 * 1000;
+
+ const withDates = UNREAD_EMAILS.map((email) => {
+ const randomOffset =
+ minOffsetMs + Math.floor(Math.random() * (oneDayMs - minOffsetMs + 1));
+ const timestamp = new Date(now - randomOffset);
+ return { ...email, timestamp };
+ }).sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
+
+ const formatter = new Intl.DateTimeFormat(undefined, {
+ hour: "numeric",
+ minute: "2-digit",
+ });
+
+ return withDates.map((email) => ({
+ ...email,
+ time: formatter.format(email.timestamp),
+ }));
+ }, []);
+
+ return (
+
+ {/* Outlook toolbar */}
+
+ π₯ Inbox
+ |
+ New
+ Reply
+ Forward
+ Delete
+
+ 7 Unread
+
+
+
+ {/* Column headers */}
+
+ !
+ From
+ Subject
+ Time
+
+
+ {/* Email rows */}
+
+ {/* Unread emails */}
+ {unreadEmails.map((email, i) => (
+
+ β
+
+ {email.from}
+
+
+ {email.subject}
+
+
+ {email.time}
+
+
+ ))}
+
+ {/* Divider */}
+
+ Older β Read
+
+
+ {/* Read emails */}
+ {READ_EMAILS.map((email, i) => (
+
+ β
+
+ {email.from}
+
+
+ {email.subject}
+
+ {email.time}
+
+ ))}
+
+
+ {/* Status bar */}
+
+ 12 Items, 7 Unread
+
+ Connected to Exchange Server
+
+
+ );
+};
diff --git a/src/components/game/PacmanGame.tsx b/src/components/game/PacmanGame.tsx
new file mode 100644
index 0000000..9cff583
--- /dev/null
+++ b/src/components/game/PacmanGame.tsx
@@ -0,0 +1,543 @@
+import React, { useRef, useEffect, useState, useCallback } from "react";
+
+const CELL = 24;
+const COLS = 21;
+const ROWS = 17;
+const CANVAS_W = COLS * CELL;
+const CANVAS_H = ROWS * CELL;
+const EMAIL_COUNT = 7;
+
+const MAZE: number[][] = [
+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
+ [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+ [1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1],
+ [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+ [1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1],
+ [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
+ [1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1],
+ [1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1],
+ [1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1],
+ [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
+ [1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1],
+ [1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1],
+ [1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1],
+ [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+ [1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1],
+ [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
+];
+
+interface Ghost {
+ x: number;
+ y: number;
+ targetX: number;
+ targetY: number;
+ progress: number;
+ speed: number;
+ color: string;
+ label: string;
+ dir: { dx: number; dy: number };
+}
+
+interface Email {
+ x: number;
+ y: number;
+ eaten: boolean;
+}
+
+interface GameState {
+ running: boolean;
+ px: number;
+ py: number;
+ targetX: number;
+ targetY: number;
+ progress: number;
+ nextDir: { dx: number; dy: number };
+ currentDir: { dx: number; dy: number };
+ mouth: number;
+ mouthDir: number;
+ emails: Email[];
+ ghosts: Ghost[];
+ tick: number;
+}
+
+const GHOST_CONFIGS = [
+ { color: "#e04040", label: "ED" },
+ { color: "#e07020", label: "HR" },
+ { color: "#40a0e0", label: "MD" },
+ { color: "#e040a0", label: "SE" },
+ { color: "#40c080", label: "CEO" },
+ { color: "#f7d000", label: "VP" },
+];
+
+const GHOST_SPAWNS = [
+ { x: 9, y: 9 },
+ { x: 10, y: 9 },
+ { x: 11, y: 9 },
+ { x: 9, y: 8 },
+ { x: 11, y: 8 },
+];
+
+const canMove = (x: number, y: number) =>
+ x >= 0 && x < COLS && y >= 0 && y < ROWS && MAZE[y]?.[x] === 0;
+
+interface PacmanGameProps {
+ onWin: () => void;
+ onLose: () => void;
+}
+
+export const PacmanGame: React.FC = ({ onWin, onLose }) => {
+ const isMobile = typeof window !== "undefined" && window.innerWidth < 768;
+ const isLandscape =
+ typeof window !== "undefined" && window.innerWidth > window.innerHeight;
+
+ // More aggressive scaling for landscape mobile
+ let canvasScale = 1;
+ if (isMobile && isLandscape) {
+ canvasScale = Math.min(1, (window.innerHeight - 120) / CANVAS_H);
+ } else if (isMobile) {
+ canvasScale = Math.min(1, (window.innerWidth - 48) / CANVAS_W);
+ }
+ const scaledCanvasWidth = CANVAS_W * canvasScale;
+ const scaledCanvasHeight = CANVAS_H * canvasScale;
+
+ const canvasRef = useRef(null);
+ const [emailsLeft, setEmailsLeft] = useState(EMAIL_COUNT);
+ const stateRef = useRef(null);
+
+ const setNextDir = useCallback((dx: number, dy: number) => {
+ if (stateRef.current) stateRef.current.nextDir = { dx, dy };
+ }, []);
+
+ const initState = useCallback(() => {
+ const paths: { x: number; y: number }[] = [];
+ for (let r = 0; r < ROWS; r++)
+ for (let c = 0; c < COLS; c++)
+ if (MAZE[r][c] === 0 && !(r === 1 && c === 1))
+ paths.push({ x: c, y: r });
+ for (let i = paths.length - 1; i > 0; i--) {
+ const j = Math.floor(Math.random() * (i + 1));
+ [paths[i], paths[j]] = [paths[j], paths[i]];
+ }
+ const emails = paths
+ .slice(0, EMAIL_COUNT)
+ .map((p) => ({ ...p, eaten: false }));
+
+ const ghosts: Ghost[] = GHOST_CONFIGS.map((cfg, i) => {
+ const spawn = GHOST_SPAWNS[i % GHOST_SPAWNS.length];
+ return {
+ x: spawn.x,
+ y: spawn.y,
+ targetX: spawn.x,
+ targetY: spawn.y,
+ progress: 1,
+ speed: 0.018 + Math.random() * 0.004,
+ color: cfg.color,
+ label: cfg.label,
+ dir: { dx: 0, dy: 0 },
+ };
+ });
+
+ return {
+ running: true,
+ px: 1,
+ py: 1,
+ targetX: 1,
+ targetY: 1,
+ progress: 1,
+ nextDir: { dx: 0, dy: 0 },
+ currentDir: { dx: 0, dy: 0 },
+ mouth: 0,
+ mouthDir: 0.04,
+ emails,
+ ghosts,
+ tick: 0,
+ };
+ }, []);
+
+ useEffect(() => {
+ const canvas = canvasRef.current;
+ if (!canvas) return;
+ const ctx = canvas.getContext("2d");
+ if (!ctx) return;
+
+ const state = initState();
+ stateRef.current = state;
+ setEmailsLeft(EMAIL_COUNT);
+
+ const keyHandler = (e: KeyboardEvent) => {
+ const s = stateRef.current;
+ if (!s || !s.running) return;
+ const dirs: Record = {
+ ArrowUp: { dx: 0, dy: -1 },
+ w: { dx: 0, dy: -1 },
+ ArrowDown: { dx: 0, dy: 1 },
+ s: { dx: 0, dy: 1 },
+ ArrowLeft: { dx: -1, dy: 0 },
+ a: { dx: -1, dy: 0 },
+ ArrowRight: { dx: 1, dy: 0 },
+ d: { dx: 1, dy: 0 },
+ };
+ if (dirs[e.key]) {
+ e.preventDefault();
+ s.nextDir = dirs[e.key];
+ }
+ };
+ window.addEventListener("keydown", keyHandler);
+
+ const PACMAN_SPEED = 0.06;
+
+ const chooseGhostDir = (g: Ghost) => {
+ const dirs = [
+ { dx: 1, dy: 0 },
+ { dx: -1, dy: 0 },
+ { dx: 0, dy: 1 },
+ { dx: 0, dy: -1 },
+ ].filter((d) => canMove(g.targetX + d.dx, g.targetY + d.dy));
+
+ const nonReverse = dirs.filter(
+ (d) => !(d.dx === -g.dir.dx && d.dy === -g.dir.dy),
+ );
+ const options = nonReverse.length > 0 ? nonReverse : dirs;
+
+ if (options.length === 0) return { dx: 0, dy: 0 };
+
+ const s = stateRef.current!;
+ if (Math.random() < 0.4) {
+ let best = options[0];
+ let bestDist = Infinity;
+ for (const d of options) {
+ const nx = g.targetX + d.dx;
+ const ny = g.targetY + d.dy;
+ const dist = Math.abs(nx - s.px) + Math.abs(ny - s.py);
+ if (dist < bestDist) {
+ bestDist = dist;
+ best = d;
+ }
+ }
+ return best;
+ }
+
+ return options[Math.floor(Math.random() * options.length)];
+ };
+
+ const loop = () => {
+ const s = stateRef.current;
+ if (!s || !s.running) return;
+ s.tick++;
+
+ // --- PACMAN LOGIC ---
+ if (s.progress >= 1) {
+ s.px = s.targetX;
+ s.py = s.targetY;
+ if (canMove(s.px + s.nextDir.dx, s.py + s.nextDir.dy))
+ s.currentDir = { ...s.nextDir };
+ if (canMove(s.px + s.currentDir.dx, s.py + s.currentDir.dy)) {
+ s.targetX = s.px + s.currentDir.dx;
+ s.targetY = s.py + s.currentDir.dy;
+ s.progress = 0;
+ }
+ } else s.progress = Math.min(1, s.progress + PACMAN_SPEED);
+
+ const pacScreenX =
+ (s.px + (s.targetX - s.px) * s.progress) * CELL + CELL / 2;
+ const pacScreenY =
+ (s.py + (s.targetY - s.py) * s.progress) * CELL + CELL / 2;
+
+ s.mouth += s.mouthDir;
+ if (s.mouth > 0.3 || s.mouth < 0) s.mouthDir *= -1;
+
+ const cpx = Math.round(s.px + (s.targetX - s.px) * s.progress);
+ const cpy = Math.round(s.py + (s.targetY - s.py) * s.progress);
+ for (const em of s.emails) {
+ if (!em.eaten && cpx === em.x && cpy === em.y) {
+ em.eaten = true;
+ const left = s.emails.filter((e) => !e.eaten).length;
+ setEmailsLeft(left);
+ if (left === 0) {
+ s.running = false;
+ onWin();
+ return;
+ }
+ }
+ }
+
+ // --- GHOSTS ---
+ for (const g of s.ghosts) {
+ if (g.progress >= 1) {
+ g.x = g.targetX;
+ g.y = g.targetY;
+ const newDir = chooseGhostDir(g);
+ g.dir = newDir;
+ if (canMove(g.x + newDir.dx, g.y + newDir.dy)) {
+ g.targetX = g.x + newDir.dx;
+ g.targetY = g.y + newDir.dy;
+ g.progress = 0;
+ }
+ } else g.progress = Math.min(1, g.progress + g.speed);
+
+ const gsx = (g.x + (g.targetX - g.x) * g.progress) * CELL + CELL / 2;
+ const gsy = (g.y + (g.targetY - g.y) * g.progress) * CELL + CELL / 2;
+
+ if (
+ Math.abs(pacScreenX - gsx) < CELL * 0.6 &&
+ Math.abs(pacScreenY - gsy) < CELL * 0.6
+ ) {
+ s.running = false;
+ onLose();
+ return;
+ }
+ }
+
+ // --- DRAW ---
+ ctx.fillStyle = "#1a1a2e";
+ ctx.fillRect(0, 0, COLS * CELL, ROWS * CELL);
+
+ for (let r = 0; r < ROWS; r++)
+ for (let c = 0; c < COLS; c++)
+ if (MAZE[r][c] === 1) {
+ ctx.fillStyle = "#1a3a6e";
+ ctx.fillRect(c * CELL, r * CELL, CELL, CELL);
+ ctx.strokeStyle = "#2a5aae";
+ ctx.lineWidth = 1;
+ ctx.strokeRect(c * CELL + 0.5, r * CELL + 0.5, CELL - 1, CELL - 1);
+ }
+
+ for (const em of s.emails) {
+ if (!em.eaten) {
+ const ex = em.x * CELL + CELL / 2;
+ const ey = em.y * CELL + CELL / 2;
+ ctx.fillStyle = "#fffbe6";
+ ctx.fillRect(ex - 7, ey - 4, 14, 10);
+ ctx.strokeStyle = "#c9a84c";
+ ctx.strokeRect(ex - 7, ey - 4, 14, 10);
+ ctx.beginPath();
+ ctx.moveTo(ex - 7, ey - 4);
+ ctx.lineTo(ex, ey + 2);
+ ctx.lineTo(ex + 7, ey - 4);
+ ctx.stroke();
+ }
+ }
+
+ for (const g of s.ghosts) {
+ const gx = (g.x + (g.targetX - g.x) * g.progress) * CELL + CELL / 2;
+ const gy = (g.y + (g.targetY - g.y) * g.progress) * CELL + CELL / 2;
+ const r = CELL / 2 - 2;
+ ctx.fillStyle = g.color;
+ ctx.beginPath();
+ ctx.arc(gx, gy - 2, r, Math.PI, 0);
+ ctx.lineTo(gx + r, gy + r);
+ const wave = Math.sin(s.tick * 0.15) * 2;
+ for (let i = 0; i < 4; i++) {
+ const wx = gx + r - ((r * 2) / 4) * (i + 0.5);
+ ctx.quadraticCurveTo(
+ wx + 2,
+ gy + r + wave * (i % 2 === 0 ? 1 : -1),
+ wx - 2,
+ gy + r,
+ );
+ }
+ ctx.lineTo(gx - r, gy + r);
+ ctx.closePath();
+ ctx.fill();
+
+ ctx.fillStyle = "#fff";
+ ctx.beginPath();
+ ctx.ellipse(gx - 3, gy - 3, 3, 4, 0, 0, Math.PI * 2);
+ ctx.ellipse(gx + 3, gy - 3, 3, 4, 0, 0, Math.PI * 2);
+ ctx.fill();
+ const angle = Math.atan2(pacScreenY - gy, pacScreenX - gx);
+ ctx.fillStyle = "#222";
+ ctx.beginPath();
+ ctx.arc(
+ gx - 3 + Math.cos(angle) * 1.5,
+ gy - 3 + Math.sin(angle) * 1.5,
+ 1.5,
+ 0,
+ Math.PI * 2,
+ );
+ ctx.arc(
+ gx + 3 + Math.cos(angle) * 1.5,
+ gy - 3 + Math.sin(angle) * 1.5,
+ 1.5,
+ 0,
+ Math.PI * 2,
+ );
+ ctx.fill();
+ ctx.fillStyle = "#fff";
+ ctx.font = "bold 8px monospace";
+ ctx.textAlign = "center";
+ ctx.fillText(g.label, gx, gy + r + 10);
+ }
+
+ const pacAngle = Math.atan2(s.currentDir.dy, s.currentDir.dx);
+ ctx.fillStyle = "#f7d000";
+ ctx.beginPath();
+ ctx.arc(
+ pacScreenX,
+ pacScreenY,
+ CELL / 2 - 2,
+ pacAngle + s.mouth * Math.PI,
+ pacAngle + (2 - s.mouth) * Math.PI,
+ );
+ ctx.lineTo(pacScreenX, pacScreenY);
+ ctx.closePath();
+ ctx.fill();
+ ctx.fillStyle = "#111";
+ ctx.beginPath();
+ ctx.arc(
+ pacScreenX + Math.cos(pacAngle - Math.PI / 4) * 4,
+ pacScreenY + Math.sin(pacAngle - Math.PI / 4) * 4,
+ 2,
+ 0,
+ Math.PI * 2,
+ );
+ ctx.fill();
+
+ requestAnimationFrame(loop);
+ };
+
+ requestAnimationFrame(loop);
+ return () => {
+ if (stateRef.current) stateRef.current.running = false;
+ window.removeEventListener("keydown", keyHandler);
+ };
+ }, [initState, onWin, onLose]);
+
+ return (
+
+ {/* Info / Emails */}
+
+
+ Emails: {emailsLeft}
+
+
+
+ {/* Canvas */}
+
+
+
+
+ {/* Mobile D-pad */}
+ {isMobile && (
+
+
+
+
+
+
+
+
+ )}
+
+ {/* Status Bar */}
+
+ Avoid the 6 coworkers!
+
+
+ );
+};
diff --git a/src/components/game/PingPongGame.tsx b/src/components/game/PingPongGame.tsx
new file mode 100644
index 0000000..465df5e
--- /dev/null
+++ b/src/components/game/PingPongGame.tsx
@@ -0,0 +1,360 @@
+import React, { useRef, useEffect, useState } from "react";
+
+interface PingPongGameProps {
+ onWin: () => void;
+ onLose: () => void;
+ playerAvatar?: string;
+ botAvatar?: string;
+ playerName?: string;
+}
+
+export const PingPongGame: React.FC = ({
+ onWin,
+ onLose,
+ playerAvatar,
+ botAvatar,
+}) => {
+ const isMobile = typeof window !== "undefined" && window.innerWidth < 768;
+ const CANVAS_W = 350;
+ const CANVAS_H = 240;
+ const canvasScale = isMobile
+ ? Math.min(1, (window.innerWidth - 48) / CANVAS_W)
+ : 1;
+
+ // Physics Constants for perfectly consistent speed
+ const CONSTANT_VX = 4.0;
+ const MAX_VY = 3.5;
+ const BALL_SPEED_Y_START = 2.2;
+
+ // Marty Supreme color palette
+ const COLOR_BG = "#0a0a0a";
+ const COLOR_PRIMARY = "#ff8c00";
+ const COLOR_SECONDARY = "#ff4500";
+ const COLOR_UI_TEXT = "#ffffff";
+
+ const canvasRef = useRef(null);
+ const gameRef = useRef<{
+ ballX: number;
+ ballY: number;
+ ballVX: number;
+ ballVY: number;
+ paddleY: number;
+ aiY: number;
+ playerScore: number;
+ aiScore: number;
+ running: boolean;
+ keysDown: Set;
+ framesSinceScore: number;
+ }>({
+ ballX: 175,
+ ballY: 120,
+ ballVX: CONSTANT_VX,
+ ballVY: BALL_SPEED_Y_START,
+ paddleY: 90,
+ aiY: 90,
+ playerScore: 0,
+ aiScore: 0,
+ running: true,
+ keysDown: new Set(),
+ framesSinceScore: 0,
+ });
+
+ const [scores, setScores] = useState({ player: 0, ai: 0 });
+
+ useEffect(() => {
+ const canvas = canvasRef.current;
+ if (!canvas) return;
+ const ctx = canvas.getContext("2d");
+ if (!ctx) return;
+ const g = gameRef.current;
+
+ const keyDown = (e: KeyboardEvent) => {
+ g.keysDown.add(e.key);
+ };
+ const keyUp = (e: KeyboardEvent) => {
+ g.keysDown.delete(e.key);
+ };
+ window.addEventListener("keydown", keyDown);
+ window.addEventListener("keyup", keyUp);
+
+ // Touch controls β drag anywhere on canvas to control paddle
+ const touchHandler = (e: TouchEvent) => {
+ e.preventDefault();
+ const touch = e.touches[0];
+ if (!touch) return;
+ const rect = canvas.getBoundingClientRect();
+ const relY = (touch.clientY - rect.top) * (CANVAS_H / rect.height);
+ g.paddleY = Math.max(0, Math.min(CANVAS_H - 60, relY - 30));
+ };
+ canvas.addEventListener("touchmove", touchHandler, { passive: false });
+ canvas.addEventListener("touchstart", touchHandler as EventListener, {
+ passive: true,
+ });
+
+ const PADDLE_SPEED = 5;
+ const AI_PADDLE_SPEED = 2.2; // Optimized for consistent ball speed
+ const PADDLE_H = 60;
+
+ const loop = () => {
+ if (!g.running) return;
+
+ // Increment frames counter
+ g.framesSinceScore++;
+
+ // If rally lasts too long, gradually speed up the ball (linear)
+ const RALLY_TIMEOUT_FRAMES = 300; // ~5 seconds at 60fps
+ if (g.framesSinceScore > RALLY_TIMEOUT_FRAMES) {
+ const excessFrames = g.framesSinceScore - RALLY_TIMEOUT_FRAMES;
+ const boost = excessFrames * 0.02; // linear: add 0.02 pixels/frame per excess frame
+
+ // Calculate base speed magnitude
+ const baseMagnitude = Math.sqrt(
+ CONSTANT_VX * CONSTANT_VX + BALL_SPEED_Y_START * BALL_SPEED_Y_START,
+ );
+ const currentMagnitude = Math.sqrt(
+ g.ballVX * g.ballVX + g.ballVY * g.ballVY,
+ );
+ const targetMagnitude = baseMagnitude + boost;
+
+ // Scale velocity to new magnitude while preserving direction
+ const scale = targetMagnitude / currentMagnitude;
+ g.ballVX *= scale;
+ g.ballVY *= scale;
+ }
+
+ // Keyboard paddle control (W/S or Up/Down)
+ if (
+ g.keysDown.has("w") ||
+ g.keysDown.has("W") ||
+ g.keysDown.has("ArrowUp")
+ ) {
+ g.paddleY = Math.max(0, g.paddleY - PADDLE_SPEED);
+ }
+ if (
+ g.keysDown.has("s") ||
+ g.keysDown.has("S") ||
+ g.keysDown.has("ArrowDown")
+ ) {
+ g.paddleY = Math.min(240 - PADDLE_H, g.paddleY + PADDLE_SPEED);
+ }
+
+ // Ball movement
+ g.ballX += g.ballVX;
+ g.ballY += g.ballVY;
+
+ // Top/bottom bounce
+ if (g.ballY <= 0 || g.ballY >= 240) g.ballVY *= -1;
+
+ // AI movement logic
+ const aiCenter = g.aiY + PADDLE_H / 2;
+ if (aiCenter < g.ballY - 15)
+ g.aiY = Math.min(240 - PADDLE_H, g.aiY + AI_PADDLE_SPEED);
+ else if (aiCenter > g.ballY + 15)
+ g.aiY = Math.max(0, g.aiY - AI_PADDLE_SPEED);
+
+ // --- Consistent Physics Collision ---
+
+ // Player paddle collision (left)
+ if (
+ g.ballX <= 18 &&
+ g.ballY >= g.paddleY &&
+ g.ballY <= g.paddleY + PADDLE_H
+ ) {
+ g.ballVX = Math.abs(CONSTANT_VX); // Reset to base X speed
+ const hitPoint =
+ (g.ballY - (g.paddleY + PADDLE_H / 2)) / (PADDLE_H / 2);
+ g.ballVY = hitPoint * MAX_VY; // Y speed depends on where it hit the paddle
+ }
+
+ // AI paddle collision (right)
+ if (g.ballX >= 332 && g.ballY >= g.aiY && g.ballY <= g.aiY + PADDLE_H) {
+ g.ballVX = -Math.abs(CONSTANT_VX); // Reset to base X speed
+ const hitPoint = (g.ballY - (g.aiY + PADDLE_H / 2)) / (PADDLE_H / 2);
+ g.ballVY = hitPoint * MAX_VY;
+ }
+
+ // Scoring
+ if (g.ballX < 0) {
+ g.aiScore++;
+ setScores({ player: g.playerScore, ai: g.aiScore });
+ if (g.aiScore >= 3) {
+ g.running = false;
+ onLose();
+ return;
+ }
+ g.ballX = 175;
+ g.ballY = 120;
+ g.ballVX = CONSTANT_VX;
+ g.ballVY = BALL_SPEED_Y_START;
+ g.framesSinceScore = 0;
+ }
+ if (g.ballX > 350) {
+ g.playerScore++;
+ setScores({ player: g.playerScore, ai: g.aiScore });
+ if (g.playerScore >= 3) {
+ g.running = false;
+ onWin();
+ return;
+ }
+ g.ballX = 175;
+ g.ballY = 120;
+ g.ballVX = -CONSTANT_VX;
+ g.ballVY = BALL_SPEED_Y_START;
+ g.framesSinceScore = 0;
+ }
+
+ // ββ DRAWING ββ
+
+ // Background
+ ctx.fillStyle = COLOR_BG;
+ ctx.fillRect(0, 0, 350, 240);
+
+ // Center Line
+ ctx.setLineDash([5, 5]);
+ ctx.strokeStyle = "rgba(255,140,0,0.45)";
+ ctx.lineWidth = 2;
+ ctx.beginPath();
+ ctx.moveTo(175, 0);
+ ctx.lineTo(175, 240);
+ ctx.stroke();
+ ctx.setLineDash([]);
+
+ // Left Paddle (Player)
+ ctx.save();
+ ctx.shadowColor = COLOR_PRIMARY;
+ ctx.shadowBlur = 14;
+ const leftGrad = ctx.createLinearGradient(
+ 5,
+ g.paddleY,
+ 17,
+ g.paddleY + PADDLE_H,
+ );
+ leftGrad.addColorStop(0, COLOR_SECONDARY);
+ leftGrad.addColorStop(0.5, COLOR_PRIMARY);
+ leftGrad.addColorStop(1, COLOR_SECONDARY);
+ ctx.fillStyle = leftGrad;
+ ctx.fillRect(5, g.paddleY, 12, PADDLE_H);
+ ctx.restore();
+
+ // Right Paddle (AI)
+ ctx.save();
+ ctx.shadowColor = COLOR_PRIMARY;
+ ctx.shadowBlur = 12;
+ const rightGrad = ctx.createLinearGradient(
+ 333,
+ g.aiY,
+ 345,
+ g.aiY + PADDLE_H,
+ );
+ rightGrad.addColorStop(0, COLOR_SECONDARY);
+ rightGrad.addColorStop(0.5, COLOR_PRIMARY);
+ rightGrad.addColorStop(1, COLOR_SECONDARY);
+ ctx.fillStyle = rightGrad;
+ ctx.fillRect(333, g.aiY, 12, PADDLE_H);
+ ctx.restore();
+
+ // Ball
+ ctx.save();
+ const r = 6;
+ const grad = ctx.createRadialGradient(
+ g.ballX,
+ g.ballY,
+ 1,
+ g.ballX,
+ g.ballY,
+ r + 8,
+ );
+ grad.addColorStop(0, "rgba(255, 245, 230, 1)");
+ grad.addColorStop(0.2, COLOR_PRIMARY);
+ grad.addColorStop(0.6, COLOR_SECONDARY);
+ grad.addColorStop(1, "rgba(255,69,0,0.0)");
+ ctx.fillStyle = grad;
+ ctx.shadowColor = COLOR_PRIMARY;
+ ctx.shadowBlur = 18;
+ ctx.beginPath();
+ ctx.arc(g.ballX, g.ballY, r, 0, Math.PI * 2);
+ ctx.fill();
+ ctx.restore();
+
+ // In-game Scoreboard
+ ctx.fillStyle = COLOR_UI_TEXT;
+ ctx.font = "12px monospace";
+ ctx.textAlign = "center";
+ ctx.fillText("You", 140, 18);
+ ctx.fillText("Marty", 200, 18);
+ ctx.font = "24px monospace";
+ ctx.fillText(String(g.playerScore), 140, 38);
+ ctx.fillText(String(g.aiScore), 200, 38);
+
+ requestAnimationFrame(loop);
+ };
+
+ requestAnimationFrame(loop);
+ return () => {
+ g.running = false;
+ window.removeEventListener("keydown", keyDown);
+ window.removeEventListener("keyup", keyUp);
+ canvas.removeEventListener("touchmove", touchHandler);
+ canvas.removeEventListener("touchstart", touchHandler as EventListener);
+ };
+ }, [onWin, onLose]);
+
+ return (
+
+ {/* Header: Player Avatar (Left) vs Marty Avatar (Right) */}
+
+ {playerAvatar ? (
+

+ ) : (
+
+ )}
+
+ {botAvatar && (
+

+ )}
+
+
+
+ {isMobile
+ ? "Touch the canvas to move your paddle."
+ : "W/S or β/β to move."}{" "}
+ First to 3 wins!
+
+
+
+
+
+
+
+ YOU: {scores.player} | MARTY SUPREME: {scores.ai}
+
+
+ );
+};
diff --git a/src/components/game/ProcrastinationDesktop.tsx b/src/components/game/ProcrastinationDesktop.tsx
new file mode 100644
index 0000000..97e2fab
--- /dev/null
+++ b/src/components/game/ProcrastinationDesktop.tsx
@@ -0,0 +1,480 @@
+import React, { useState, useCallback, useEffect } from "react";
+import { Globe } from "lucide-react";
+
+const MATCH_OVERS = 20;
+const MAX_BALLS_PER_INNINGS = MATCH_OVERS * 6;
+
+type BattingTeam = "INDIA" | "AUSTRALIA" | "DONE";
+
+interface InningsState {
+ runs: number;
+ wickets: number;
+ balls: number;
+}
+
+interface MatchState {
+ battingTeam: BattingTeam;
+ india: InningsState;
+ australia: InningsState;
+ recentBalls: string[];
+ lastBallCommentary: string;
+}
+
+function formatOvers(ballsFaced: number) {
+ return `${Math.floor(ballsFaced / 6)}.${ballsFaced % 6}`;
+}
+
+function isInningsComplete(innings: InningsState) {
+ return innings.wickets >= 10 || innings.balls >= MAX_BALLS_PER_INNINGS;
+}
+
+function createInitialMatchState(): MatchState {
+ return {
+ battingTeam: "INDIA",
+ india: { runs: 0, wickets: 0, balls: 0 },
+ australia: { runs: 0, wickets: 0, balls: 0 },
+ recentBalls: [],
+ lastBallCommentary: "Toss: India bat first.",
+ };
+}
+
+function formatRunRate(runs: number, balls: number) {
+ if (balls === 0) return "0.00";
+ return ((runs * 6) / balls).toFixed(2);
+}
+
+interface ProcrastinationDesktopProps {
+ hidden?: boolean;
+ disabled?: boolean;
+}
+
+export const ProcrastinationDesktop: React.FC = ({
+ hidden = false,
+ disabled = false,
+}) => {
+ const isMobile = typeof window !== "undefined" && window.innerWidth < 768;
+ const [pos, setPos] = useState({
+ x: isMobile ? 8 : 96,
+ y: isMobile ? 155 : 40,
+ });
+ const [activeTab, setActiveTab] = useState<"cricket" | "cat" | "youtube">(
+ "cricket",
+ );
+ const [match, setMatch] = useState(createInitialMatchState);
+
+ const resetMatch = useCallback(() => {
+ setMatch(createInitialMatchState());
+ }, []);
+
+ useEffect(() => {
+ const timer = setInterval(() => {
+ setMatch((prev) => {
+ if (prev.battingTeam === "DONE") return prev;
+
+ const teamKey = prev.battingTeam === "INDIA" ? "india" : "australia";
+ const currentInnings = prev[teamKey];
+
+ const australiaChasedTarget =
+ prev.battingTeam === "AUSTRALIA" &&
+ prev.australia.runs > prev.india.runs;
+
+ if (australiaChasedTarget) {
+ return { ...prev, battingTeam: "DONE" };
+ }
+
+ if (isInningsComplete(currentInnings)) {
+ if (prev.battingTeam === "INDIA") {
+ return {
+ ...prev,
+ battingTeam: "AUSTRALIA",
+ recentBalls: [],
+ lastBallCommentary: `Target: ${prev.india.runs + 1} from ${MATCH_OVERS} overs.`,
+ };
+ }
+ return {
+ ...prev,
+ battingTeam: "DONE",
+ lastBallCommentary: "Australia innings complete.",
+ };
+ }
+
+ const outcomeRoll = Math.random();
+ let runDelta = 0;
+ let wicketDelta = 0;
+ let ballSymbol = ".";
+ let ballCommentary = "Dot ball.";
+
+ if (outcomeRoll < 0.04) {
+ wicketDelta = 1;
+ ballSymbol = "W";
+ ballCommentary = "WICKET! Batter dismissed.";
+ } else if (outcomeRoll < 0.44) {
+ runDelta = 0;
+ } else if (outcomeRoll < 0.79) {
+ runDelta = 1;
+ ballSymbol = "1";
+ ballCommentary = "Single taken.";
+ } else if (outcomeRoll < 0.91) {
+ runDelta = 2;
+ ballSymbol = "2";
+ ballCommentary = "Driven for two.";
+ } else if (outcomeRoll < 0.94) {
+ runDelta = 3;
+ ballSymbol = "3";
+ ballCommentary = "Excellent running, three runs.";
+ } else if (outcomeRoll < 0.995) {
+ runDelta = 4;
+ ballSymbol = "4";
+ ballCommentary = "FOUR! Finds the gap.";
+ } else {
+ runDelta = 6;
+ ballSymbol = "6";
+ ballCommentary = "SIX! Huge hit into the stands.";
+ }
+
+ const nextInnings: InningsState = {
+ runs: currentInnings.runs + runDelta,
+ wickets: Math.min(10, currentInnings.wickets + wicketDelta),
+ balls: currentInnings.balls + 1,
+ };
+
+ const nextState: MatchState =
+ teamKey === "india"
+ ? {
+ ...prev,
+ india: nextInnings,
+ }
+ : {
+ ...prev,
+ australia: nextInnings,
+ };
+
+ const ballPrefix =
+ prev.battingTeam === "INDIA"
+ ? `IND ${formatOvers(nextInnings.balls)}`
+ : `AUS ${formatOvers(nextInnings.balls)}`;
+
+ nextState.recentBalls = [...prev.recentBalls.slice(-11), ballSymbol];
+ nextState.lastBallCommentary = `${ballPrefix}: ${ballCommentary}`;
+
+ const chaseCompleted =
+ prev.battingTeam === "AUSTRALIA" &&
+ nextState.australia.runs > nextState.india.runs;
+
+ if (chaseCompleted) {
+ return {
+ ...nextState,
+ battingTeam: "DONE",
+ lastBallCommentary: `${ballPrefix}: ${ballCommentary} Australia complete the chase.`,
+ };
+ }
+
+ if (isInningsComplete(nextInnings)) {
+ if (prev.battingTeam === "INDIA") {
+ return {
+ ...nextState,
+ battingTeam: "AUSTRALIA",
+ recentBalls: [],
+ lastBallCommentary: `India finish on ${nextState.india.runs}/${nextState.india.wickets}. Target: ${nextState.india.runs + 1}`,
+ };
+ }
+ return {
+ ...nextState,
+ battingTeam: "DONE",
+ lastBallCommentary: `${ballPrefix}: Innings over.`,
+ };
+ }
+
+ return nextState;
+ });
+ }, 1500);
+
+ return () => clearInterval(timer);
+ }, []);
+
+ const indiaRuns = match.india.runs;
+ const australiaRuns = match.australia.runs;
+ const target = indiaRuns + 1;
+ const runsNeeded = Math.max(0, target - australiaRuns);
+ const ballsRemaining = Math.max(
+ 0,
+ MAX_BALLS_PER_INNINGS - match.australia.balls,
+ );
+ const requiredRate =
+ match.battingTeam === "AUSTRALIA" && ballsRemaining > 0 && runsNeeded > 0
+ ? ((runsNeeded * 6) / ballsRemaining).toFixed(2)
+ : "0.00";
+ const currentRate =
+ match.battingTeam === "INDIA"
+ ? formatRunRate(match.india.runs, match.india.balls)
+ : formatRunRate(match.australia.runs, match.australia.balls);
+
+ const liveLine =
+ match.battingTeam === "INDIA"
+ ? `β LIVE - India batting first (${MATCH_OVERS}-over match)`
+ : match.battingTeam === "AUSTRALIA"
+ ? australiaRuns >= target
+ ? `β LIVE - Australia have chased ${target}`
+ : `β LIVE - Australia need ${runsNeeded} from ${ballsRemaining} balls`
+ : australiaRuns >= target
+ ? `β RESULT - Australia won by ${10 - match.australia.wickets} wickets`
+ : indiaRuns === australiaRuns
+ ? "β RESULT - Match tied"
+ : `β RESULT - India won by ${indiaRuns - australiaRuns} runs`;
+
+ const statusColorClass =
+ match.battingTeam !== "DONE"
+ ? "text-green-700"
+ : australiaRuns >= target
+ ? "text-red-700"
+ : indiaRuns > australiaRuns
+ ? "text-blue-700"
+ : "text-gray-700";
+
+ const browserTitle =
+ activeTab === "cricket"
+ ? "CricketLiveScore.tv"
+ : activeTab === "cat"
+ ? "CatVideosNow.tv"
+ : "YouTube";
+
+ const browserFavicon =
+ activeTab === "cricket" ? "π" : activeTab === "cat" ? "π±" : "βΆοΈ";
+
+ const browserUrl =
+ activeTab === "cricket"
+ ? "https://www.cricketlive.tv/match/ind-vs-aus-2026"
+ : activeTab === "cat"
+ ? "https://www.catvideosnow.tv/watch/funniest-cats"
+ : "https://www.youtube.com/watch?v=minecraft-live";
+
+ const onMouseDown = useCallback(
+ (e: React.MouseEvent) => {
+ e.preventDefault();
+ const startX = e.clientX - pos.x;
+ const startY = e.clientY - pos.y;
+
+ const onMove = (ev: MouseEvent) => {
+ setPos({ x: ev.clientX - startX, y: ev.clientY - startY });
+ };
+ const onUp = () => {
+ window.removeEventListener("mousemove", onMove);
+ window.removeEventListener("mouseup", onUp);
+ };
+ window.addEventListener("mousemove", onMove);
+ window.addEventListener("mouseup", onUp);
+ },
+ [pos],
+ );
+
+ return (
+
+
+ {/* Title Bar β drag handle */}
+
+
+
+
+ Google Chrome - {browserFavicon} {browserTitle}
+
+
+
+
+ _
+
+
+ β‘
+
+
+ β
+
+
+
+
+ {/* Browser Toolbar */}
+
+
β
+
β
+
β³
+
+ {browserUrl}
+
+
+
+ {/* Tabs */}
+
+
+
+
+
+
+ {/* Content */}
+
+ {activeTab === "cricket" && (
+ <>
+
+ π IND vs AUS - LIVE
+
+
+
+
+
INDIA
+
+ {match.india.runs}/{match.india.wickets}
+
+
+ ({formatOvers(match.india.balls)} ov)
+
+
+
vs
+
+
AUSTRALIA
+
+ {match.australia.runs}/{match.australia.wickets}
+
+
+ ({formatOvers(match.australia.balls)} ov)
+
+
+
+
+
+
Current RR
+
{currentRate}
+
+
+
+
Req RR
+
{requiredRate}
+
+
+
Balls Left
+
{ballsRemaining}
+
+
+
+
Last Over Feed
+
+ {match.recentBalls.length > 0
+ ? match.recentBalls.join(" ")
+ : "No balls yet"}
+
+
+
+
+ {liveLine}
+
+
+ {match.lastBallCommentary}
+
+
+
+
+
+ Live Chat (2.4k)
+
+ Scorecard
+ Commentary
+
+
+ >
+ )}
+
+ {activeTab === "cat" && (
+
+
+ π± Cat Videos - LIVE
+
+

+
+ )}
+
+ {activeTab === "youtube" && (
+
+
βΆ YouTube
+
+

+
+
+
+ probably your office Wi-Fi.
+
+
+ )}
+
+
+
+ );
+};
diff --git a/src/components/game/PunishmentScreen.tsx b/src/components/game/PunishmentScreen.tsx
new file mode 100644
index 0000000..65cee57
--- /dev/null
+++ b/src/components/game/PunishmentScreen.tsx
@@ -0,0 +1,149 @@
+import React, { useEffect, useState } from "react";
+import { Video, MessageCircle, LayoutList } from "lucide-react";
+import { TeamsMockup } from "./TeamsMockup";
+import { OutlookMockup } from "./OutlookMockup";
+import { ZoomMockup } from "./ZoomMockup";
+
+interface PunishmentScreenProps {
+ onComplete: () => void;
+ gameStage: string;
+ isPunishment: boolean;
+}
+
+const PUNISHMENT_TIME_SECONDS = 5;
+
+const PUNISHMENTS = {
+ zoom: {
+ title: "Zoom - All Hands Meeting",
+ icon: ,
+ content: ,
+ },
+ teams: {
+ title: "Microsoft Teams - Sprint Chat",
+ icon: ,
+ content: ,
+ },
+ jira: {
+ title: "Jira - Sprint Board",
+ icon: ,
+ content: (
+
+ {/* Toolbar */}
+
+ Project Dashboard
+
+
+ {/* Board */}
+
+ {[
+ { title: "TO DO", items: ["Fix mobile", "Docs", "Dark mode"] },
+ { title: "IN PROGRESS", items: ["Auth flow", "Refactor API"] },
+ { title: "DONE", items: ["Update README"] },
+ ].map((col) => (
+
+
+ {col.title}
+
+
+
+ {col.items.map((i) => (
+
+ {i}
+
+ ))}
+
+
+ ))}
+
+
+ {/* Status */}
+
+ 47 issues remaining
+
+
+ ),
+ },
+ email: {
+ title: "Outlook",
+ icon: ,
+ content: null,
+ },
+};
+
+const GAME_STAGE_PUNISHMENT_MAP: Record = {
+ pingpong: "teams",
+ wordle: "zoom",
+ tetris: "jira",
+ pacman: "email",
+};
+
+export const PunishmentScreen: React.FC = ({
+ onComplete,
+ gameStage,
+ isPunishment,
+}) => {
+ const [timer, setTimer] = useState(PUNISHMENT_TIME_SECONDS);
+ const punishmentType =
+ GAME_STAGE_PUNISHMENT_MAP[gameStage.toLowerCase()] ?? "zoom";
+ const punishment = PUNISHMENTS[punishmentType];
+
+ // Unique heights for each punishment type
+ const windowHeightMap: Record = {
+ zoom: "h-[600px]",
+ teams: "h-[400px]",
+ jira: "h-[500px]",
+ email: "h-[520px]",
+ };
+ const windowWidthMap: Record = {
+ zoom: "w-[800px]",
+ teams: "w-[700px]",
+ jira: "w-[720px]",
+ email: "w-[720px]",
+ };
+ const windowHeight = windowHeightMap[punishmentType] || "h-[520px]";
+ const windowWidth = windowWidthMap[punishmentType] || "w-[700px]";
+
+ useEffect(() => {
+ setTimer(PUNISHMENT_TIME_SECONDS);
+ const interval = setInterval(() => {
+ setTimer((prev) => {
+ if (prev <= 1) {
+ clearInterval(interval);
+ onComplete();
+ return 0;
+ }
+ return prev - 1;
+ });
+ }, 1000);
+ return () => clearInterval(interval);
+ }, [onComplete, gameStage, punishmentType]);
+
+ return (
+
+
+
+
+ {punishment.icon}
+ {punishment.title}
+
+
+
+ {punishmentType === "email" ? (
+
+ ) : (
+ <>{punishment.content}>
+ )}
+
+
+
+ );
+};
diff --git a/src/components/game/Taskbar.tsx b/src/components/game/Taskbar.tsx
new file mode 100644
index 0000000..6d03e35
--- /dev/null
+++ b/src/components/game/Taskbar.tsx
@@ -0,0 +1,99 @@
+import React, { useState, useEffect } from "react";
+import {
+ Monitor,
+ Globe,
+ MessageCircle,
+ FolderOpen,
+ Volume2,
+} from "lucide-react";
+
+interface TaskbarProps {
+ volume: number;
+ setVolume: (value: number) => void;
+}
+
+export const Taskbar: React.FC = ({ volume, setVolume }) => {
+ const [time, setTime] = useState(new Date());
+ const [showVolumeControl, setShowVolumeControl] = useState(false);
+
+ useEffect(() => {
+ const interval = setInterval(() => setTime(new Date()), 60000);
+ return () => clearInterval(interval);
+ }, []);
+
+ const timeStr = time.toLocaleTimeString([], {
+ hour: "2-digit",
+ minute: "2-digit",
+ });
+ const dateStr = time.toLocaleDateString([], {
+ month: "short",
+ day: "numeric",
+ });
+
+ return (
+
+
+
+
+ {/* Quick launch icons (Win7 style) */}
+
+ {[
+ { icon: , label: "Chrome" },
+ { icon: , label: "Teams" },
+ { icon: , label: "Explorer" },
+ ].map((item) => (
+
+ ))}
+
+
+
+ {showVolumeControl && (
+
+
+ VOL
+
+ setVolume(Number(event.target.value) / 100)
+ }
+ className="w-24 accent-primary"
+ />
+
+ {Math.round(volume * 100)}%
+
+
+
+ )}
+
+
+
+
+ {timeStr}
+
+
+ {dateStr}
+
+
+
+
+ );
+};
diff --git a/src/components/game/TeamsMockup.tsx b/src/components/game/TeamsMockup.tsx
new file mode 100644
index 0000000..fffb1d6
--- /dev/null
+++ b/src/components/game/TeamsMockup.tsx
@@ -0,0 +1,39 @@
+import React from "react";
+
+export const TeamsMockup: React.FC = () => (
+
+ {/* Sidebar */}
+
+
Channels
+
# General
+
# Engineering
+
# Incidents
+
+
+ {/* Chat */}
+
+
+ Engineering Chat
+
+
+
+
+ Sarah: Prod DB connections high.
+
+
+ Michael: API latency increasing.
+
+
+ You: Scaling pool?
+
+
+ Sarah: Rolling back deployment.
+
+
+
+
+ Type a message...
+
+
+
+);
diff --git a/src/components/game/TeamsNotif.tsx b/src/components/game/TeamsNotif.tsx
new file mode 100644
index 0000000..63c19bc
--- /dev/null
+++ b/src/components/game/TeamsNotif.tsx
@@ -0,0 +1,60 @@
+interface TeamsNotifProps {
+ onDismiss?: () => void;
+ onJoin?: () => void;
+}
+
+export function TeamsNotif({ onDismiss, onJoin }: TeamsNotifProps) {
+ const time = new Date().toLocaleTimeString([], {
+ hour: "2-digit",
+ minute: "2-digit",
+ });
+
+ return (
+
+
+ {/* XP Title Bar */}
+
+ π¬ Microsoft Teams
+
+
+
+ {/* Body */}
+
+
+

{
+ (e.target as HTMLImageElement).style.display = "none";
+ }}
+ />
+
+ Boss Baby
+
+ JOIN MY TEAMS. We need to discuss cross-functional alignment
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/game/TetrisGame.tsx b/src/components/game/TetrisGame.tsx
new file mode 100644
index 0000000..1b36a98
--- /dev/null
+++ b/src/components/game/TetrisGame.tsx
@@ -0,0 +1,397 @@
+import React, { useRef, useEffect, useState } from "react";
+
+const COLS = 20;
+const ROWS = 15;
+const CELL = 22;
+const TIMER_SECONDS = 60;
+
+// Row index from the top (0 = very top, ROWS-1 = bottom).
+// Overlay fires when any block reaches this row β i.e. stack is (ROWS - DANGER_ROW) tall.
+const DANGER_ROW = 5; // triggers when 10 of 15 rows are stacked
+
+const SHAPES = [
+ [
+ [1, 1, 1, 1],
+ [1, 1, 1, 1],
+ ], // I: 2Γ4 slab
+ [
+ [1, 1, 1],
+ [1, 1, 1],
+ [1, 1, 1],
+ ], // O: 3Γ3 square
+ [
+ [0, 1, 0],
+ [1, 1, 1],
+ [0, 1, 0],
+ ], // T: 3Γ3 cross
+ [
+ [1, 1, 0],
+ [1, 1, 1],
+ [1, 1, 1],
+ ], // L: 3Γ3 chunky L
+ [
+ [0, 1, 1],
+ [0, 1, 1],
+ [1, 1, 1],
+ ], // J: 3Γ3 chunky J
+ [[1, 1, 1, 1]], // I: 1Γ4 bar
+];
+
+const CANVAS_W = COLS * CELL;
+const CANVAS_H = ROWS * CELL;
+
+const PRIORITIES = ["CRIT", "HIGH", "MED", "LOW"];
+const COLORS = ["#ff3333", "#fb5607", "#ffbe0b", "#22c55e"];
+const HIGHLIGHT_COLORS = ["#ff9999", "#fdb080", "#ffe580", "#86efac"];
+const SHADOW_COLORS = ["#7a0000", "#7d2b03", "#806000", "#14532d"];
+
+interface TetrisGameProps {
+ onTopReached: () => void;
+ onCleared: () => void;
+}
+
+export const TetrisGame: React.FC = ({
+ onTopReached,
+ onCleared,
+}) => {
+ const isMobile = typeof window !== "undefined" && window.innerWidth < 768;
+ const canvasScale = isMobile
+ ? Math.min(1, (window.innerWidth - 48) / CANVAS_W)
+ : 1;
+
+ const canvasRef = useRef(null);
+ const [timeLeft, setTimeLeft] = useState(TIMER_SECONDS);
+ const [flashMsg, setFlashMsg] = useState(null);
+ const flashTimeout = useRef | null>(null);
+ const ctrlRef = useRef<{
+ move: (dir: number) => void;
+ rotate: () => void;
+ drop: () => void;
+ } | null>(null);
+
+ useEffect(() => {
+ const canvas = canvasRef.current;
+ if (!canvas) return;
+ const ctx = canvas.getContext("2d");
+ if (!ctx) return;
+
+ const grid: (number | null)[][] = Array.from({ length: ROWS }, () =>
+ Array(COLS).fill(null),
+ );
+ let currentPiece: {
+ shape: number[][];
+ colorIdx: number;
+ label: string;
+ x: number;
+ y: number;
+ } | null = null;
+ let running = true;
+ let dropCounter = 0;
+ let lastTime = 0;
+ let startTime = performance.now();
+ let piecesPlaced = 0;
+
+ function flash(msg: string) {
+ if (flashTimeout.current) clearTimeout(flashTimeout.current);
+ setFlashMsg(msg);
+ flashTimeout.current = setTimeout(() => setFlashMsg(null), 1300);
+ }
+
+ function newPiece() {
+ const shapeIdx = Math.floor(Math.random() * SHAPES.length);
+ const priorityIdx = Math.floor(Math.random() * PRIORITIES.length);
+ currentPiece = {
+ shape: SHAPES[shapeIdx],
+ colorIdx: priorityIdx,
+ label: PRIORITIES[priorityIdx],
+ x: Math.floor(COLS / 2) - 1,
+ y: 0,
+ };
+ if (collides(currentPiece)) {
+ running = false;
+ onTopReached();
+ }
+ }
+
+ function collides(piece: typeof currentPiece) {
+ if (!piece) return false;
+ for (let r = 0; r < piece.shape.length; r++) {
+ for (let c = 0; c < piece.shape[r].length; c++) {
+ if (piece.shape[r][c]) {
+ const nx = piece.x + c;
+ const ny = piece.y + r;
+ if (nx < 0 || nx >= COLS || ny >= ROWS) return true;
+ if (ny >= 0 && grid[ny][nx] !== null) return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ function merge() {
+ if (!currentPiece) return;
+ for (let r = 0; r < currentPiece.shape.length; r++) {
+ for (let c = 0; c < currentPiece.shape[r].length; c++) {
+ if (currentPiece.shape[r][c]) {
+ const ny = currentPiece.y + r;
+ const nx = currentPiece.x + c;
+ if (ny >= 0 && ny < ROWS && nx >= 0 && nx < COLS) {
+ grid[ny][nx] = currentPiece.colorIdx;
+ }
+ }
+ }
+ }
+ piecesPlaced++;
+ let linesCleared = 0;
+ for (let r = ROWS - 1; r >= 0; r--) {
+ if (grid[r].every((c) => c !== null)) {
+ grid.splice(r, 1);
+ grid.unshift(Array(COLS).fill(null));
+ linesCleared++;
+ r++;
+ }
+ }
+ if (linesCleared > 1) {
+ flash("Reassigned to the whole team!");
+ } else if (linesCleared === 1) {
+ flash("Pawned off!");
+ }
+ }
+
+ function drop() {
+ if (!currentPiece) return;
+ currentPiece.y++;
+ if (collides(currentPiece)) {
+ currentPiece.y--;
+ merge();
+ newPiece();
+ }
+ }
+
+ function move(dir: number) {
+ if (!currentPiece) return;
+ currentPiece.x += dir;
+ if (collides(currentPiece)) currentPiece.x -= dir;
+ }
+
+ function rotate() {
+ if (!currentPiece) return;
+ const rotated = currentPiece.shape[0].map((_, i) =>
+ currentPiece!.shape.map((row) => row[i]).reverse(),
+ );
+ const old = currentPiece.shape;
+ currentPiece.shape = rotated;
+ if (collides(currentPiece)) currentPiece.shape = old;
+ }
+
+ function drawBlock(px: number, py: number, colorIdx: number) {
+ const s = CELL - 1;
+ ctx.fillStyle = COLORS[colorIdx];
+ ctx.fillRect(px, py, s, s);
+ ctx.fillStyle = HIGHLIGHT_COLORS[colorIdx];
+ ctx.fillRect(px, py, s, 3);
+ ctx.fillRect(px, py, 3, s);
+ ctx.fillStyle = SHADOW_COLORS[colorIdx];
+ ctx.fillRect(px, py + s - 3, s, 3);
+ ctx.fillRect(px + s - 3, py, 3, s);
+ }
+
+ function draw() {
+ ctx.fillStyle = "#0a0a1a";
+ ctx.fillRect(0, 0, COLS * CELL, ROWS * CELL);
+
+ for (let r = 0; r < ROWS; r++) {
+ for (let c = 0; c < COLS; c++) {
+ if (grid[r][c] !== null) {
+ drawBlock(c * CELL, r * CELL, grid[r][c]!);
+ }
+ }
+ }
+
+ if (currentPiece) {
+ for (let r = 0; r < currentPiece.shape.length; r++) {
+ for (let c = 0; c < currentPiece.shape[r].length; c++) {
+ if (currentPiece.shape[r][c]) {
+ drawBlock(
+ (currentPiece.x + c) * CELL,
+ (currentPiece.y + r) * CELL,
+ currentPiece.colorIdx,
+ );
+ }
+ }
+ }
+ ctx.fillStyle = "#fff";
+ ctx.font = "bold 9px monospace";
+ ctx.fillText(
+ currentPiece.label,
+ (currentPiece.x + 0.15) * CELL,
+ (currentPiece.y + 1) * CELL - 3,
+ );
+ }
+
+ // Danger overlay: blocks are stacking into the top zone
+ let isDanger = false;
+ for (let c = 0; c < COLS; c++) {
+ if (grid[DANGER_ROW][c] !== null) {
+ isDanger = true;
+ break;
+ }
+ }
+ if (isDanger) {
+ ctx.fillStyle = "rgba(255, 51, 51, 0.12)";
+ ctx.fillRect(0, 0, COLS * CELL, DANGER_ROW * CELL);
+ ctx.fillStyle = "rgba(255, 51, 51, 0.85)";
+ ctx.font = "bold 11px monospace";
+ ctx.textAlign = "center";
+ ctx.fillText(
+ "all yours now...",
+ (COLS * CELL) / 2,
+ DANGER_ROW * CELL - 6,
+ );
+ ctx.textAlign = "left";
+ }
+
+ ctx.strokeStyle = "#1a1a3e";
+ for (let r = 0; r <= ROWS; r++) {
+ ctx.beginPath();
+ ctx.moveTo(0, r * CELL);
+ ctx.lineTo(COLS * CELL, r * CELL);
+ ctx.stroke();
+ }
+ for (let c = 0; c <= COLS; c++) {
+ ctx.beginPath();
+ ctx.moveTo(c * CELL, 0);
+ ctx.lineTo(c * CELL, ROWS * CELL);
+ ctx.stroke();
+ }
+ }
+
+ function gameLoop(time: number) {
+ if (!running) return;
+ const delta = time - lastTime;
+ lastTime = time;
+ dropCounter += delta;
+
+ const elapsed = (time - startTime) / 1000;
+ const remaining = Math.max(0, TIMER_SECONDS - elapsed);
+ setTimeLeft(Math.ceil(remaining));
+ if (remaining <= 0) {
+ running = false;
+ onCleared();
+ return;
+ }
+
+ const dropInterval = Math.max(160, 420 - piecesPlaced * 12);
+ if (dropCounter > dropInterval) {
+ drop();
+ dropCounter = 0;
+ }
+ draw();
+ requestAnimationFrame(gameLoop);
+ }
+
+ const keyHandler = (e: KeyboardEvent) => {
+ if (!running) return;
+ if (e.key === "ArrowLeft" || e.key.toLowerCase() === "a") move(-1);
+ if (e.key === "ArrowRight" || e.key.toLowerCase() === "d") move(1);
+ if (e.key === "ArrowDown" || e.key.toLowerCase() === "s") drop();
+ if (e.key === "ArrowUp" || e.key.toLowerCase() === "w") rotate();
+ };
+
+ window.addEventListener("keydown", keyHandler);
+ ctrlRef.current = { move, rotate, drop };
+ newPiece();
+ startTime = performance.now();
+ requestAnimationFrame(gameLoop);
+
+ return () => {
+ running = false;
+ ctrlRef.current = null;
+ window.removeEventListener("keydown", keyHandler);
+ if (flashTimeout.current) clearTimeout(flashTimeout.current);
+ };
+ }, [onTopReached, onCleared]);
+
+ return (
+
+
+ Clear rows to reassign Jiras — let them stack and{" "}
+
+ they're all yours
+
+
+
+
+ β Crit
+ β High
+ β Med
+ β Low
+
+
+ {timeLeft}s
+
+
+
+
+ {flashMsg && (
+
+
+ {flashMsg}
+
+
+ )}
+
+ {isMobile ? (
+
+
+
+
+
+
+ ) : (
+
+ β rotate Β· β β move Β· β drop
+
+ )}
+
+ );
+};
diff --git a/src/components/game/WordleGame.tsx b/src/components/game/WordleGame.tsx
new file mode 100644
index 0000000..4ca0acd
--- /dev/null
+++ b/src/components/game/WordleGame.tsx
@@ -0,0 +1,376 @@
+import React, { useState, useCallback, useEffect } from "react";
+
+const MAX_GUESSES = 6;
+
+const FALLBACK_VALID_WORDS = [
+ "SYNCS",
+ "AGILE",
+ "PIVOT",
+ "SCRUM",
+ "EPICS",
+ "FLEET",
+ "RAPID",
+ "SLACK",
+ "STAND",
+ "FOCUS",
+ "ALIGN",
+ "SCOPE",
+ "PATCH",
+ "BRICK",
+ "CRANE",
+ "GLOBE",
+ "HOUSE",
+ "LIGHT",
+ "MONEY",
+ "POWER",
+ "QUEST",
+ "RAISE",
+ "SMART",
+ "THINK",
+ "ULTRA",
+ "VALVE",
+ "WATER",
+ "YIELD",
+ "BLAST",
+ "CHARM",
+ "DRAFT",
+ "EIGHT",
+ "FLAME",
+ "GRAPE",
+ "HASTE",
+ "INPUT",
+ "JUDGE",
+ "KNEEL",
+ "LEAPS",
+ "MANGO",
+ "NOBLE",
+ "OCEAN",
+ "PLUMB",
+ "QUITE",
+ "ROUND",
+ "SHARP",
+ "TOWER",
+ "UNITE",
+ "WATCH",
+ "WORLD",
+ "BRAIN",
+ "CLOUD",
+ "DAILY",
+ "EXTRA",
+ "FRESH",
+ "GRAIN",
+ "TREND",
+ "TRACK",
+ "TRADE",
+ "TRAIN",
+ "TRAIL",
+ "TRIAL",
+ "TWEAK",
+ "SWARM",
+ "SPARK",
+ "SPACE",
+ "SOLVE",
+ "SOLID",
+ "SHIFT",
+ "SHARE",
+ "SHAPE",
+ "SERVE",
+ "JIRAS",
+ "CLOUD",
+ "CACHE",
+ "BYTES",
+ "DEBUG",
+ "PIXEL",
+ "PROXY",
+ "ARRAY",
+ "QUERY",
+ "PROPS",
+ "GATES",
+ "MODES",
+ "NODES",
+ "AZURE",
+ "REDUX",
+ "LINUX",
+ "TOKEN",
+ "STACK",
+ "LINKS",
+ "MONGO",
+ "KAFKA",
+ "GRAPH",
+ "SWIFT",
+];
+
+const TARGET_WORDS = [
+ "AGILE",
+ "PIVOT",
+ "SCRUM",
+ "EPICS",
+ "SLACK",
+ "STAND",
+ "ALIGN",
+ "SCOPE",
+ "TREND",
+ "JIRAS",
+ "CLOUD",
+ "CACHE",
+ "BYTES",
+ "DEBUG",
+ "PIXEL",
+ "PROXY",
+ "ARRAY",
+ "QUERY",
+ "PROPS",
+ "GATES",
+ "MODES",
+ "NODES",
+ "AZURE",
+ "REDUX",
+ "LINUX",
+ "TOKEN",
+ "STACK",
+ "LINKS",
+ "MONGO",
+ "KAFKA",
+ "GRAPH",
+ "SWIFT",
+];
+
+interface WordleGameProps {
+ onComplete: (guesses: number) => void;
+}
+
+const KEYBOARD_ROWS = [
+ ["Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P"],
+ ["A", "S", "D", "F", "G", "H", "J", "K", "L"],
+ ["ENTER", "Z", "X", "C", "V", "B", "N", "M", "β«"],
+];
+
+export const WordleGame: React.FC = ({ onComplete }) => {
+ const [target] = useState(
+ () => TARGET_WORDS[Math.floor(Math.random() * TARGET_WORDS.length)],
+ );
+ const [guesses, setGuesses] = useState([]);
+ const [current, setCurrent] = useState("");
+ const [done, setDone] = useState(false);
+ const [error, setError] = useState("");
+ const [validWords, setValidWords] = useState>(
+ new Set(FALLBACK_VALID_WORDS),
+ );
+ const [letterStates, setLetterStates] = useState<
+ Record
+ >({});
+
+ // Load words from dictionary if available
+ useEffect(() => {
+ let active = true;
+ const loadWords = async () => {
+ try {
+ const response = await fetch("/words.txt");
+ if (!response.ok) return;
+ const text = await response.text();
+ const words = text
+ .split(/\r?\n/)
+ .map((w) => w.trim().toUpperCase())
+ .filter((w) => /^[A-Z]{5}$/.test(w));
+ if (!active || words.length === 0) return;
+ setValidWords(new Set([...FALLBACK_VALID_WORDS, ...words]));
+ } catch {
+ return;
+ }
+ };
+ loadWords();
+ return () => {
+ active = false;
+ };
+ }, []);
+
+ // Update letter states (for keyboard coloring)
+ const updateLetterStates = useCallback((word: string, targetWord: string) => {
+ setLetterStates((prev) => {
+ const next = { ...prev };
+ for (let i = 0; i < word.length; i++) {
+ const l = word[i];
+ if (l === targetWord[i]) {
+ next[l] = "correct";
+ } else if (targetWord.includes(l)) {
+ if (next[l] !== "correct") next[l] = "present";
+ } else {
+ if (!next[l]) next[l] = "absent";
+ }
+ }
+ return next;
+ });
+ }, []);
+
+ const submit = useCallback(() => {
+ if (done || current.length !== 5) return;
+ const upper = current.toUpperCase();
+ if (!validWords.has(upper)) {
+ setError("Not a valid word!");
+ setTimeout(() => setError(""), 1500);
+ return;
+ }
+ const newGuesses = [...guesses, upper];
+ setGuesses(newGuesses);
+ setCurrent("");
+ updateLetterStates(upper, target);
+
+ if (upper === target) {
+ setDone(true);
+ onComplete(newGuesses.length);
+ } else if (newGuesses.length >= MAX_GUESSES) {
+ setDone(true);
+ onComplete(7);
+ }
+ }, [
+ current,
+ guesses,
+ done,
+ target,
+ validWords,
+ updateLetterStates,
+ onComplete,
+ ]);
+
+ const handleKey = useCallback(
+ (key: string) => {
+ if (done) return;
+ if (key === "ENTER") {
+ submit();
+ return;
+ }
+ if (key === "β«") {
+ setCurrent((prev) => prev.slice(0, -1));
+ return;
+ }
+ if (/^[A-Z]$/.test(key) && current.length < 5) {
+ setCurrent((prev) => prev + key);
+ }
+ },
+ [current, done, submit],
+ );
+
+ useEffect(() => {
+ const handler = (e: KeyboardEvent) => {
+ if (done) return;
+ if (e.key === "Enter") {
+ submit();
+ return;
+ }
+ if (e.key === "Backspace") {
+ setCurrent((prev) => prev.slice(0, -1));
+ return;
+ }
+ if (/^[a-zA-Z]$/.test(e.key) && current.length < 5) {
+ setCurrent((prev) => prev + e.key.toUpperCase());
+ }
+ };
+ window.addEventListener("keydown", handler);
+ return () => window.removeEventListener("keydown", handler);
+ }, [current, done, submit]);
+
+ // Determine coloring of letters in boxes
+ const getColor = (letter: string, index: number, row: string) => {
+ if (!row) return "bg-card border border-border";
+ const targetLetters = target.split("");
+ const rowLetters = row.split("");
+ const counts: Record = {};
+ targetLetters.forEach((l) => (counts[l] = (counts[l] || 0) + 1));
+
+ const result: Array<"correct" | "present" | "absent"> =
+ Array(5).fill("absent");
+ // First pass: correct letters
+ for (let i = 0; i < 5; i++) {
+ if (rowLetters[i] === targetLetters[i]) {
+ result[i] = "correct";
+ counts[rowLetters[i]]--;
+ }
+ }
+ // Second pass: present letters
+ for (let i = 0; i < 5; i++) {
+ if (result[i] === "correct") continue;
+ if (counts[rowLetters[i]] > 0) {
+ result[i] = "present";
+ counts[rowLetters[i]]--;
+ }
+ }
+ if (result[index] === "correct")
+ return "bg-success text-success-foreground";
+ if (result[index] === "present")
+ return "bg-warning text-warning-foreground";
+ return "bg-muted text-muted-foreground";
+ };
+
+ const getKeyColor = (letter: string) => {
+ const state = letterStates[letter];
+ if (state === "correct") return "bg-success text-success-foreground";
+ if (state === "present") return "bg-warning text-warning-foreground";
+ if (state === "absent") return "bg-foreground/30 text-muted-foreground";
+ return "bg-muted text-card-foreground";
+ };
+
+ const rows = [...guesses];
+ while (rows.length < MAX_GUESSES) rows.push("");
+
+ return (
+
+
+ Decode the corporate buzzword!
+
+ {error && (
+
+ {error}
+
+ )}
+
+ {/* Word rows */}
+
+ {rows.map((row, ri) => (
+
+ {[0, 1, 2, 3, 4].map((ci) => {
+ const isCurrentRow = ri === guesses.length && !done;
+ const letter = isCurrentRow ? current[ci] || "" : row[ci] || "";
+ const colorClass = isCurrentRow
+ ? "bg-card border border-border"
+ : getColor(letter, ci, row);
+ return (
+
+ {letter}
+
+ );
+ })}
+
+ ))}
+
+
+ {/* On-screen keyboard */}
+ {!done && (
+
+ {KEYBOARD_ROWS.map((row, ri) => (
+
+ {row.map((key) => (
+
+ ))}
+
+ ))}
+
+ )}
+
+ {/* Show target if failed */}
+ {done && guesses[guesses.length - 1] !== target && (
+
+ The word was: {target}
+
+ )}
+
+ );
+};
diff --git a/src/components/game/ZoomMockup.tsx b/src/components/game/ZoomMockup.tsx
new file mode 100644
index 0000000..b255834
--- /dev/null
+++ b/src/components/game/ZoomMockup.tsx
@@ -0,0 +1,57 @@
+import React from "react";
+
+const PARTICIPANTS = [
+ { initials: "JD", name: "John D.", color: "#4a7c9b" },
+ { initials: "SK", name: "Sarah K.", color: "#7c4a9b" },
+ { initials: "MR", name: "Mike R.", color: "#9b6b4a" },
+ { initials: "AL", name: "Amy L.", color: "#4a9b6b" },
+];
+
+export const ZoomMockup: React.FC = () => {
+ return (
+
+ {/* Menu */}
+
+ Call
+ View
+ Tools
+ Help
+
+
+ {/* Main video */}
+
+
+

+
+
+ PM β Screen Sharing (Poor Connection)
+
+
+
+
+ {/* Participant strip */}
+
+ {PARTICIPANTS.map((p) => (
+
+
+ {p.initials}
+
+
{p.name}
+
+ ))}
+
+
+ {/* Status */}
+
+ Connected β’ 12 participants
+
+
+ );
+};
diff --git a/src/components/ui/accordion.tsx b/src/components/ui/accordion.tsx
new file mode 100644
index 0000000..83ff017
--- /dev/null
+++ b/src/components/ui/accordion.tsx
@@ -0,0 +1,56 @@
+import * as React from "react";
+import * as AccordionPrimitive from "@radix-ui/react-accordion";
+import { ChevronDown } from "lucide-react";
+
+import { cn } from "@/lib/utils";
+
+const Accordion = AccordionPrimitive.Root;
+
+const AccordionItem = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+AccordionItem.displayName = "AccordionItem";
+
+const AccordionTrigger = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+ svg]:rotate-180",
+ className,
+ )}
+ {...props}
+ >
+ {children}
+
+
+
+));
+AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName;
+
+const AccordionContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+ {children}
+
+));
+
+AccordionContent.displayName = AccordionPrimitive.Content.displayName;
+
+export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };
diff --git a/src/components/ui/alert-dialog.tsx b/src/components/ui/alert-dialog.tsx
new file mode 100644
index 0000000..72b0afe
--- /dev/null
+++ b/src/components/ui/alert-dialog.tsx
@@ -0,0 +1,139 @@
+import * as React from "react";
+import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
+
+import { cn } from "@/lib/utils";
+import { buttonVariants } from "@/components/ui/button";
+
+const AlertDialog = AlertDialogPrimitive.Root;
+
+const AlertDialogTrigger = AlertDialogPrimitive.Trigger;
+
+const AlertDialogPortal = AlertDialogPrimitive.Portal;
+
+const AlertDialogOverlay = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;
+
+const AlertDialogContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+
+
+
+));
+AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;
+
+const AlertDialogHeader = ({
+ className,
+ ...props
+}: React.HTMLAttributes) => (
+
+);
+AlertDialogHeader.displayName = "AlertDialogHeader";
+
+const AlertDialogFooter = ({
+ className,
+ ...props
+}: React.HTMLAttributes) => (
+
+);
+AlertDialogFooter.displayName = "AlertDialogFooter";
+
+const AlertDialogTitle = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
+
+const AlertDialogDescription = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+AlertDialogDescription.displayName =
+ AlertDialogPrimitive.Description.displayName;
+
+const AlertDialogAction = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;
+
+const AlertDialogCancel = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;
+
+export {
+ AlertDialog,
+ AlertDialogPortal,
+ AlertDialogOverlay,
+ AlertDialogTrigger,
+ AlertDialogContent,
+ AlertDialogHeader,
+ AlertDialogFooter,
+ AlertDialogTitle,
+ AlertDialogDescription,
+ AlertDialogAction,
+ AlertDialogCancel,
+};
diff --git a/src/components/ui/alert.tsx b/src/components/ui/alert.tsx
new file mode 100644
index 0000000..13219e7
--- /dev/null
+++ b/src/components/ui/alert.tsx
@@ -0,0 +1,59 @@
+import * as React from "react";
+import { cva, type VariantProps } from "class-variance-authority";
+
+import { cn } from "@/lib/utils";
+
+const alertVariants = cva(
+ "relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",
+ {
+ variants: {
+ variant: {
+ default: "bg-background text-foreground",
+ destructive:
+ "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ },
+ },
+);
+
+const Alert = React.forwardRef<
+ HTMLDivElement,
+ React.HTMLAttributes & VariantProps
+>(({ className, variant, ...props }, ref) => (
+
+));
+Alert.displayName = "Alert";
+
+const AlertTitle = React.forwardRef<
+ HTMLParagraphElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+AlertTitle.displayName = "AlertTitle";
+
+const AlertDescription = React.forwardRef<
+ HTMLParagraphElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+AlertDescription.displayName = "AlertDescription";
+
+export { Alert, AlertTitle, AlertDescription };
diff --git a/src/components/ui/aspect-ratio.tsx b/src/components/ui/aspect-ratio.tsx
new file mode 100644
index 0000000..c9e6f4b
--- /dev/null
+++ b/src/components/ui/aspect-ratio.tsx
@@ -0,0 +1,5 @@
+import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio";
+
+const AspectRatio = AspectRatioPrimitive.Root;
+
+export { AspectRatio };
diff --git a/src/components/ui/avatar.tsx b/src/components/ui/avatar.tsx
new file mode 100644
index 0000000..444b1db
--- /dev/null
+++ b/src/components/ui/avatar.tsx
@@ -0,0 +1,48 @@
+import * as React from "react";
+import * as AvatarPrimitive from "@radix-ui/react-avatar";
+
+import { cn } from "@/lib/utils";
+
+const Avatar = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+Avatar.displayName = AvatarPrimitive.Root.displayName;
+
+const AvatarImage = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+AvatarImage.displayName = AvatarPrimitive.Image.displayName;
+
+const AvatarFallback = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
+
+export { Avatar, AvatarImage, AvatarFallback };
diff --git a/src/components/ui/badge.tsx b/src/components/ui/badge.tsx
new file mode 100644
index 0000000..d3d5d60
--- /dev/null
+++ b/src/components/ui/badge.tsx
@@ -0,0 +1,36 @@
+import * as React from "react";
+import { cva, type VariantProps } from "class-variance-authority";
+
+import { cn } from "@/lib/utils";
+
+const badgeVariants = cva(
+ "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
+ {
+ variants: {
+ variant: {
+ default:
+ "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
+ secondary:
+ "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
+ destructive:
+ "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
+ outline: "text-foreground",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ },
+ },
+);
+
+export interface BadgeProps
+ extends React.HTMLAttributes,
+ VariantProps {}
+
+function Badge({ className, variant, ...props }: BadgeProps) {
+ return (
+
+ );
+}
+
+export { Badge, badgeVariants };
diff --git a/src/components/ui/breadcrumb.tsx b/src/components/ui/breadcrumb.tsx
new file mode 100644
index 0000000..6934f83
--- /dev/null
+++ b/src/components/ui/breadcrumb.tsx
@@ -0,0 +1,115 @@
+import * as React from "react";
+import { Slot } from "@radix-ui/react-slot";
+import { ChevronRight, MoreHorizontal } from "lucide-react";
+
+import { cn } from "@/lib/utils";
+
+const Breadcrumb = React.forwardRef<
+ HTMLElement,
+ React.ComponentPropsWithoutRef<"nav"> & {
+ separator?: React.ReactNode;
+ }
+>(({ ...props }, ref) => );
+Breadcrumb.displayName = "Breadcrumb";
+
+const BreadcrumbList = React.forwardRef<
+ HTMLOListElement,
+ React.ComponentPropsWithoutRef<"ol">
+>(({ className, ...props }, ref) => (
+
+));
+BreadcrumbList.displayName = "BreadcrumbList";
+
+const BreadcrumbItem = React.forwardRef<
+ HTMLLIElement,
+ React.ComponentPropsWithoutRef<"li">
+>(({ className, ...props }, ref) => (
+
+));
+BreadcrumbItem.displayName = "BreadcrumbItem";
+
+const BreadcrumbLink = React.forwardRef<
+ HTMLAnchorElement,
+ React.ComponentPropsWithoutRef<"a"> & {
+ asChild?: boolean;
+ }
+>(({ asChild, className, ...props }, ref) => {
+ const Comp = asChild ? Slot : "a";
+
+ return (
+
+ );
+});
+BreadcrumbLink.displayName = "BreadcrumbLink";
+
+const BreadcrumbPage = React.forwardRef<
+ HTMLSpanElement,
+ React.ComponentPropsWithoutRef<"span">
+>(({ className, ...props }, ref) => (
+
+));
+BreadcrumbPage.displayName = "BreadcrumbPage";
+
+const BreadcrumbSeparator = ({
+ children,
+ className,
+ ...props
+}: React.ComponentProps<"li">) => (
+ svg]:size-3.5", className)}
+ {...props}
+ >
+ {children ?? }
+
+);
+BreadcrumbSeparator.displayName = "BreadcrumbSeparator";
+
+const BreadcrumbEllipsis = ({
+ className,
+ ...props
+}: React.ComponentProps<"span">) => (
+
+
+ More
+
+);
+BreadcrumbEllipsis.displayName = "BreadcrumbElipssis";
+
+export {
+ Breadcrumb,
+ BreadcrumbList,
+ BreadcrumbItem,
+ BreadcrumbLink,
+ BreadcrumbPage,
+ BreadcrumbSeparator,
+ BreadcrumbEllipsis,
+};
diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx
new file mode 100644
index 0000000..d6c7bcb
--- /dev/null
+++ b/src/components/ui/button.tsx
@@ -0,0 +1,56 @@
+import * as React from "react";
+import { Slot } from "@radix-ui/react-slot";
+import { cva, type VariantProps } from "class-variance-authority";
+
+import { cn } from "@/lib/utils";
+
+const buttonVariants = cva(
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
+ {
+ variants: {
+ variant: {
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
+ destructive:
+ "bg-destructive text-destructive-foreground hover:bg-destructive/90",
+ outline:
+ "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
+ secondary:
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80",
+ ghost: "hover:bg-accent hover:text-accent-foreground",
+ link: "text-primary underline-offset-4 hover:underline",
+ },
+ size: {
+ default: "h-10 px-4 py-2",
+ sm: "h-9 rounded-md px-3",
+ lg: "h-11 rounded-md px-8",
+ icon: "h-10 w-10",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ size: "default",
+ },
+ },
+);
+
+export interface ButtonProps
+ extends React.ButtonHTMLAttributes,
+ VariantProps {
+ asChild?: boolean;
+}
+
+const Button = React.forwardRef(
+ ({ className, variant, size, asChild = false, ...props }, ref) => {
+ const Comp = asChild ? Slot : "button";
+ return (
+
+ );
+ },
+);
+Button.displayName = "Button";
+
+export { Button, buttonVariants };
diff --git a/src/components/ui/calendar.tsx b/src/components/ui/calendar.tsx
new file mode 100644
index 0000000..d6c7bcb
--- /dev/null
+++ b/src/components/ui/calendar.tsx
@@ -0,0 +1,56 @@
+import * as React from "react";
+import { Slot } from "@radix-ui/react-slot";
+import { cva, type VariantProps } from "class-variance-authority";
+
+import { cn } from "@/lib/utils";
+
+const buttonVariants = cva(
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
+ {
+ variants: {
+ variant: {
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
+ destructive:
+ "bg-destructive text-destructive-foreground hover:bg-destructive/90",
+ outline:
+ "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
+ secondary:
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80",
+ ghost: "hover:bg-accent hover:text-accent-foreground",
+ link: "text-primary underline-offset-4 hover:underline",
+ },
+ size: {
+ default: "h-10 px-4 py-2",
+ sm: "h-9 rounded-md px-3",
+ lg: "h-11 rounded-md px-8",
+ icon: "h-10 w-10",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ size: "default",
+ },
+ },
+);
+
+export interface ButtonProps
+ extends React.ButtonHTMLAttributes,
+ VariantProps {
+ asChild?: boolean;
+}
+
+const Button = React.forwardRef(
+ ({ className, variant, size, asChild = false, ...props }, ref) => {
+ const Comp = asChild ? Slot : "button";
+ return (
+
+ );
+ },
+);
+Button.displayName = "Button";
+
+export { Button, buttonVariants };
diff --git a/src/components/ui/card.tsx b/src/components/ui/card.tsx
new file mode 100644
index 0000000..dc3b01d
--- /dev/null
+++ b/src/components/ui/card.tsx
@@ -0,0 +1,86 @@
+import * as React from "react";
+
+import { cn } from "@/lib/utils";
+
+const Card = React.forwardRef<
+ HTMLDivElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+Card.displayName = "Card";
+
+const CardHeader = React.forwardRef<
+ HTMLDivElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+CardHeader.displayName = "CardHeader";
+
+const CardTitle = React.forwardRef<
+ HTMLParagraphElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+CardTitle.displayName = "CardTitle";
+
+const CardDescription = React.forwardRef<
+ HTMLParagraphElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+CardDescription.displayName = "CardDescription";
+
+const CardContent = React.forwardRef<
+ HTMLDivElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+CardContent.displayName = "CardContent";
+
+const CardFooter = React.forwardRef<
+ HTMLDivElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => (
+
+));
+CardFooter.displayName = "CardFooter";
+
+export {
+ Card,
+ CardHeader,
+ CardFooter,
+ CardTitle,
+ CardDescription,
+ CardContent,
+};
diff --git a/src/components/ui/carousel.tsx b/src/components/ui/carousel.tsx
new file mode 100644
index 0000000..c4111e3
--- /dev/null
+++ b/src/components/ui/carousel.tsx
@@ -0,0 +1,260 @@
+import * as React from "react";
+import useEmblaCarousel, {
+ type UseEmblaCarouselType,
+} from "embla-carousel-react";
+import { ArrowLeft, ArrowRight } from "lucide-react";
+
+import { cn } from "@/lib/utils";
+import { Button } from "@/components/ui/button";
+
+type CarouselApi = UseEmblaCarouselType[1];
+type UseCarouselParameters = Parameters;
+type CarouselOptions = UseCarouselParameters[0];
+type CarouselPlugin = UseCarouselParameters[1];
+
+type CarouselProps = {
+ opts?: CarouselOptions;
+ plugins?: CarouselPlugin;
+ orientation?: "horizontal" | "vertical";
+ setApi?: (api: CarouselApi) => void;
+};
+
+type CarouselContextProps = {
+ carouselRef: ReturnType[0];
+ api: ReturnType[1];
+ scrollPrev: () => void;
+ scrollNext: () => void;
+ canScrollPrev: boolean;
+ canScrollNext: boolean;
+} & CarouselProps;
+
+const CarouselContext = React.createContext(null);
+
+function useCarousel() {
+ const context = React.useContext(CarouselContext);
+
+ if (!context) {
+ throw new Error("useCarousel must be used within a ");
+ }
+
+ return context;
+}
+
+const Carousel = React.forwardRef<
+ HTMLDivElement,
+ React.HTMLAttributes & CarouselProps
+>(
+ (
+ {
+ orientation = "horizontal",
+ opts,
+ setApi,
+ plugins,
+ className,
+ children,
+ ...props
+ },
+ ref,
+ ) => {
+ const [carouselRef, api] = useEmblaCarousel(
+ {
+ ...opts,
+ axis: orientation === "horizontal" ? "x" : "y",
+ },
+ plugins,
+ );
+ const [canScrollPrev, setCanScrollPrev] = React.useState(false);
+ const [canScrollNext, setCanScrollNext] = React.useState(false);
+
+ const onSelect = React.useCallback((api: CarouselApi) => {
+ if (!api) {
+ return;
+ }
+
+ setCanScrollPrev(api.canScrollPrev());
+ setCanScrollNext(api.canScrollNext());
+ }, []);
+
+ const scrollPrev = React.useCallback(() => {
+ api?.scrollPrev();
+ }, [api]);
+
+ const scrollNext = React.useCallback(() => {
+ api?.scrollNext();
+ }, [api]);
+
+ const handleKeyDown = React.useCallback(
+ (event: React.KeyboardEvent) => {
+ if (event.key === "ArrowLeft") {
+ event.preventDefault();
+ scrollPrev();
+ } else if (event.key === "ArrowRight") {
+ event.preventDefault();
+ scrollNext();
+ }
+ },
+ [scrollPrev, scrollNext],
+ );
+
+ React.useEffect(() => {
+ if (!api || !setApi) {
+ return;
+ }
+
+ setApi(api);
+ }, [api, setApi]);
+
+ React.useEffect(() => {
+ if (!api) {
+ return;
+ }
+
+ onSelect(api);
+ api.on("reInit", onSelect);
+ api.on("select", onSelect);
+
+ return () => {
+ api?.off("select", onSelect);
+ };
+ }, [api, onSelect]);
+
+ return (
+
+
+ {children}
+
+
+ );
+ },
+);
+Carousel.displayName = "Carousel";
+
+const CarouselContent = React.forwardRef<
+ HTMLDivElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => {
+ const { carouselRef, orientation } = useCarousel();
+
+ return (
+
+ );
+});
+CarouselContent.displayName = "CarouselContent";
+
+const CarouselItem = React.forwardRef<
+ HTMLDivElement,
+ React.HTMLAttributes
+>(({ className, ...props }, ref) => {
+ const { orientation } = useCarousel();
+
+ return (
+
+ );
+});
+CarouselItem.displayName = "CarouselItem";
+
+const CarouselPrevious = React.forwardRef<
+ HTMLButtonElement,
+ React.ComponentProps
+>(({ className, variant = "outline", size = "icon", ...props }, ref) => {
+ const { orientation, scrollPrev, canScrollPrev } = useCarousel();
+
+ return (
+
+ );
+});
+CarouselPrevious.displayName = "CarouselPrevious";
+
+const CarouselNext = React.forwardRef<
+ HTMLButtonElement,
+ React.ComponentProps
+>(({ className, variant = "outline", size = "icon", ...props }, ref) => {
+ const { orientation, scrollNext, canScrollNext } = useCarousel();
+
+ return (
+
+ );
+});
+CarouselNext.displayName = "CarouselNext";
+
+export {
+ type CarouselApi,
+ Carousel,
+ CarouselContent,
+ CarouselItem,
+ CarouselPrevious,
+ CarouselNext,
+};
diff --git a/src/components/ui/chart.tsx b/src/components/ui/chart.tsx
new file mode 100644
index 0000000..ba084ed
--- /dev/null
+++ b/src/components/ui/chart.tsx
@@ -0,0 +1,363 @@
+import * as React from "react";
+import * as RechartsPrimitive from "recharts";
+
+import { cn } from "@/lib/utils";
+
+// Format: { THEME_NAME: CSS_SELECTOR }
+const THEMES = { light: "", dark: ".dark" } as const;
+
+export type ChartConfig = {
+ [k in string]: {
+ label?: React.ReactNode;
+ icon?: React.ComponentType;
+ } & (
+ | { color?: string; theme?: never }
+ | { color?: never; theme: Record }
+ );
+};
+
+type ChartContextProps = {
+ config: ChartConfig;
+};
+
+const ChartContext = React.createContext(null);
+
+function useChart() {
+ const context = React.useContext(ChartContext);
+
+ if (!context) {
+ throw new Error("useChart must be used within a ");
+ }
+
+ return context;
+}
+
+const ChartContainer = React.forwardRef<
+ HTMLDivElement,
+ React.ComponentProps<"div"> & {
+ config: ChartConfig;
+ children: React.ComponentProps<
+ typeof RechartsPrimitive.ResponsiveContainer
+ >["children"];
+ }
+>(({ id, className, children, config, ...props }, ref) => {
+ const uniqueId = React.useId();
+ const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`;
+
+ return (
+
+
+
+
+ {children}
+
+
+
+ );
+});
+ChartContainer.displayName = "Chart";
+
+const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {
+ const colorConfig = Object.entries(config).filter(
+ ([_, config]) => config.theme || config.color,
+ );
+
+ if (!colorConfig.length) {
+ return null;
+ }
+
+ return (
+