Initial commit from template vite_react_shadcn_ts_20250728_minor

gpt-engineer-app[bot] committed Nov 27, 2025 at 11:11 UTC 67818513bb8a84fda278c9e868faedb0ac9f64cf
77 files changed +11625
.gitignore new
+24
@@ -0,0 +1,24 @@
1 +# Logs
2 +logs
3 +*.log
4 +npm-debug.log*
5 +yarn-debug.log*
6 +yarn-error.log*
7 +pnpm-debug.log*
8 +lerna-debug.log*
9 +
10 +node_modules
11 +dist
12 +dist-ssr
13 +*.local
14 +
15 +# Editor directories and files
16 +.vscode/*
17 +!.vscode/extensions.json
18 +.idea
19 +.DS_Store
20 +*.suo
21 +*.ntvs*
22 +*.njsproj
23 +*.sln
24 +*.sw?
README.md new
+73
@@ -0,0 +1,73 @@
1 +# Welcome to your Lovable project
2 +
3 +## Project info
4 +
5 +**URL**: https://lovable.dev/projects/b956142d-8f42-4ed5-97c8-8198e2b51da7
6 +
7 +## How can I edit this code?
8 +
9 +There are several ways of editing your application.
10 +
11 +**Use Lovable**
12 +
13 +Simply visit the [Lovable Project](https://lovable.dev/projects/b956142d-8f42-4ed5-97c8-8198e2b51da7) and start prompting.
14 +
15 +Changes made via Lovable will be committed automatically to this repo.
16 +
17 +**Use your preferred IDE**
18 +
19 +If you want to work locally using your own IDE, you can clone this repo and push changes. Pushed changes will also be reflected in Lovable.
20 +
21 +The only requirement is having Node.js & npm installed - [install with nvm](https://github.com/nvm-sh/nvm#installing-and-updating)
22 +
23 +Follow these steps:
24 +
25 +```sh
26 +# Step 1: Clone the repository using the project's Git URL.
27 +git clone <YOUR_GIT_URL>
28 +
29 +# Step 2: Navigate to the project directory.
30 +cd <YOUR_PROJECT_NAME>
31 +
32 +# Step 3: Install the necessary dependencies.
33 +npm i
34 +
35 +# Step 4: Start the development server with auto-reloading and an instant preview.
36 +npm run dev
37 +```
38 +
39 +**Edit a file directly in GitHub**
40 +
41 +- Navigate to the desired file(s).
42 +- Click the "Edit" button (pencil icon) at the top right of the file view.
43 +- Make your changes and commit the changes.
44 +
45 +**Use GitHub Codespaces**
46 +
47 +- Navigate to the main page of your repository.
48 +- Click on the "Code" button (green button) near the top right.
49 +- Select the "Codespaces" tab.
50 +- Click on "New codespace" to launch a new Codespace environment.
51 +- Edit files directly within the Codespace and commit and push your changes once you're done.
52 +
53 +## What technologies are used for this project?
54 +
55 +This project is built with:
56 +
57 +- Vite
58 +- TypeScript
59 +- React
60 +- shadcn-ui
61 +- Tailwind CSS
62 +
63 +## How can I deploy this project?
64 +
65 +Simply open [Lovable](https://lovable.dev/projects/b956142d-8f42-4ed5-97c8-8198e2b51da7) and click on Share -> Publish.
66 +
67 +## Can I connect a custom domain to my Lovable project?
68 +
69 +Yes, you can!
70 +
71 +To connect a domain, navigate to Project > Settings > Domains and click Connect Domain.
72 +
73 +Read more here: [Setting up a custom domain](https://docs.lovable.dev/features/custom-domain#custom-domain)
bun.lockb
Binary files /dev/null and b/bun.lockb differ
components.json new
+20
@@ -0,0 +1,20 @@
1 +{
2 + "$schema": "https://ui.shadcn.com/schema.json",
3 + "style": "default",
4 + "rsc": false,
5 + "tsx": true,
6 + "tailwind": {
7 + "config": "tailwind.config.ts",
8 + "css": "src/index.css",
9 + "baseColor": "slate",
10 + "cssVariables": true,
11 + "prefix": ""
12 + },
13 + "aliases": {
14 + "components": "@/components",
15 + "utils": "@/lib/utils",
16 + "ui": "@/components/ui",
17 + "lib": "@/lib",
18 + "hooks": "@/hooks"
19 + }
20 +}
eslint.config.js new
+26
@@ -0,0 +1,26 @@
1 +import js from "@eslint/js";
2 +import globals from "globals";
3 +import reactHooks from "eslint-plugin-react-hooks";
4 +import reactRefresh from "eslint-plugin-react-refresh";
5 +import tseslint from "typescript-eslint";
6 +
7 +export default tseslint.config(
8 + { ignores: ["dist"] },
9 + {
10 + extends: [js.configs.recommended, ...tseslint.configs.recommended],
11 + files: ["**/*.{ts,tsx}"],
12 + languageOptions: {
13 + ecmaVersion: 2020,
14 + globals: globals.browser,
15 + },
16 + plugins: {
17 + "react-hooks": reactHooks,
18 + "react-refresh": reactRefresh,
19 + },
20 + rules: {
21 + ...reactHooks.configs.recommended.rules,
22 + "react-refresh/only-export-components": ["warn", { allowConstantExport: true }],
23 + "@typescript-eslint/no-unused-vars": "off",
24 + },
25 + },
26 +);
index.html new
+24
@@ -0,0 +1,24 @@
1 +<!doctype html>
2 +<html lang="en">
3 + <head>
4 + <meta charset="UTF-8" />
5 + <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6 + <title>b956142d-8f42-4ed5-97c8-8198e2b51da7</title>
7 + <meta name="description" content="Lovable Generated Project" />
8 + <meta name="author" content="Lovable" />
9 +
10 + <meta property="og:title" content="b956142d-8f42-4ed5-97c8-8198e2b51da7" />
11 + <meta property="og:description" content="Lovable Generated Project" />
12 + <meta property="og:type" content="website" />
13 + <meta property="og:image" content="https://lovable.dev/opengraph-image-p98pqg.png" />
14 +
15 + <meta name="twitter:card" content="summary_large_image" />
16 + <meta name="twitter:site" content="@Lovable" />
17 + <meta name="twitter:image" content="https://lovable.dev/opengraph-image-p98pqg.png" />
18 + </head>
19 +
20 + <body>
21 + <div id="root"></div>
22 + <script type="module" src="/src/main.tsx"></script>
23 + </body>
24 +</html>
package-lock.json new
+6766
@@ -0,0 +1,6766 @@
1 +{
2 + "name": "vite_react_shadcn_ts",
3 + "version": "0.0.0",
4 + "lockfileVersion": 3,
5 + "requires": true,
6 + "packages": {
7 + "": {
8 + "name": "vite_react_shadcn_ts",
9 + "version": "0.0.0",
10 + "dependencies": {
11 + "@hookform/resolvers": "^3.10.0",
12 + "@radix-ui/react-accordion": "^1.2.11",
13 + "@radix-ui/react-alert-dialog": "^1.1.14",
14 + "@radix-ui/react-aspect-ratio": "^1.1.7",
15 + "@radix-ui/react-avatar": "^1.1.10",
16 + "@radix-ui/react-checkbox": "^1.3.2",
17 + "@radix-ui/react-collapsible": "^1.1.11",
18 + "@radix-ui/react-context-menu": "^2.2.15",
19 + "@radix-ui/react-dialog": "^1.1.14",
20 + "@radix-ui/react-dropdown-menu": "^2.1.15",
21 + "@radix-ui/react-hover-card": "^1.1.14",
22 + "@radix-ui/react-label": "^2.1.7",
23 + "@radix-ui/react-menubar": "^1.1.15",
24 + "@radix-ui/react-navigation-menu": "^1.2.13",
25 + "@radix-ui/react-popover": "^1.1.14",
26 + "@radix-ui/react-progress": "^1.1.7",
27 + "@radix-ui/react-radio-group": "^1.3.7",
28 + "@radix-ui/react-scroll-area": "^1.2.9",
29 + "@radix-ui/react-select": "^2.2.5",
30 + "@radix-ui/react-separator": "^1.1.7",
31 + "@radix-ui/react-slider": "^1.3.5",
32 + "@radix-ui/react-slot": "^1.2.3",
33 + "@radix-ui/react-switch": "^1.2.5",
34 + "@radix-ui/react-tabs": "^1.1.12",
35 + "@radix-ui/react-toast": "^1.2.14",
36 + "@radix-ui/react-toggle": "^1.1.9",
37 + "@radix-ui/react-toggle-group": "^1.1.10",
38 + "@radix-ui/react-tooltip": "^1.2.7",
39 + "@tanstack/react-query": "^5.83.0",
40 + "class-variance-authority": "^0.7.1",
41 + "clsx": "^2.1.1",
42 + "cmdk": "^1.1.1",
43 + "date-fns": "^3.6.0",
44 + "embla-carousel-react": "^8.6.0",
45 + "input-otp": "^1.4.2",
46 + "lucide-react": "^0.462.0",
47 + "next-themes": "^0.3.0",
48 + "react": "^18.3.1",
49 + "react-day-picker": "^8.10.1",
50 + "react-dom": "^18.3.1",
51 + "react-hook-form": "^7.61.1",
52 + "react-resizable-panels": "^2.1.9",
53 + "react-router-dom": "^6.30.1",
54 + "recharts": "^2.15.4",
55 + "sonner": "^1.7.4",
56 + "tailwind-merge": "^2.6.0",
57 + "tailwindcss-animate": "^1.0.7",
58 + "vaul": "^0.9.9",
59 + "zod": "^3.25.76"
60 + },
61 + "devDependencies": {
62 + "@eslint/js": "^9.32.0",
63 + "@tailwindcss/typography": "^0.5.16",
64 + "@types/node": "^22.16.5",
65 + "@types/react": "^18.3.23",
66 + "@types/react-dom": "^18.3.7",
67 + "@vitejs/plugin-react-swc": "^3.11.0",
68 + "autoprefixer": "^10.4.21",
69 + "eslint": "^9.32.0",
70 + "eslint-plugin-react-hooks": "^5.2.0",
71 + "eslint-plugin-react-refresh": "^0.4.20",
72 + "globals": "^15.15.0",
73 + "lovable-tagger": "^1.1.11",
74 + "postcss": "^8.5.6",
75 + "tailwindcss": "^3.4.17",
76 + "typescript": "^5.8.3",
77 + "typescript-eslint": "^8.38.0",
78 + "vite": "^5.4.19"
79 + }
80 + },
81 + "node_modules/@alloc/quick-lru": {
82 + "version": "5.2.0",
83 + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
84 + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
85 + "license": "MIT",
86 + "engines": {
87 + "node": ">=10"
88 + },
89 + "funding": {
90 + "url": "https://github.com/sponsors/sindresorhus"
91 + }
92 + },
93 + "node_modules/@babel/helper-string-parser": {
94 + "version": "7.25.9",
95 + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
96 + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
97 + "dev": true,
98 + "license": "MIT",
99 + "engines": {
100 + "node": ">=6.9.0"
101 + }
102 + },
103 + "node_modules/@babel/helper-validator-identifier": {
104 + "version": "7.25.9",
105 + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
106 + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
107 + "dev": true,
108 + "license": "MIT",
109 + "engines": {
110 + "node": ">=6.9.0"
111 + }
112 + },
113 + "node_modules/@babel/parser": {
114 + "version": "7.25.9",
115 + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.9.tgz",
116 + "integrity": "sha512-aI3jjAAO1fh7vY/pBGsn1i9LDbRP43+asrRlkPuTXW5yHXtd1NgTEMudbBoDDxrf1daEEfPJqR+JBMakzrR4Dg==",
117 + "dev": true,
118 + "license": "MIT",
119 + "dependencies": {
120 + "@babel/types": "^7.25.9"
121 + },
122 + "bin": {
123 + "parser": "bin/babel-parser.js"
124 + },
125 + "engines": {
126 + "node": ">=6.0.0"
127 + }
128 + },
129 + "node_modules/@babel/runtime": {
130 + "version": "7.28.2",
131 + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.2.tgz",
132 + "integrity": "sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==",
133 + "license": "MIT",
134 + "engines": {
135 + "node": ">=6.9.0"
136 + }
137 + },
138 + "node_modules/@babel/types": {
139 + "version": "7.25.9",
140 + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.9.tgz",
141 + "integrity": "sha512-OwS2CM5KocvQ/k7dFJa8i5bNGJP0hXWfVCfDkqRFP1IreH1JDC7wG6eCYCi0+McbfT8OR/kNqsI0UU0xP9H6PQ==",
142 + "dev": true,
143 + "license": "MIT",
144 + "dependencies": {
145 + "@babel/helper-string-parser": "^7.25.9",
146 + "@babel/helper-validator-identifier": "^7.25.9"
147 + },
148 + "engines": {
149 + "node": ">=6.9.0"
150 + }
151 + },
152 + "node_modules/@esbuild/aix-ppc64": {
153 + "version": "0.21.5",
154 + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
155 + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
156 + "cpu": [
157 + "ppc64"
158 + ],
159 + "dev": true,
160 + "license": "MIT",
161 + "optional": true,
162 + "os": [
163 + "aix"
164 + ],
165 + "engines": {
166 + "node": ">=12"
167 + }
168 + },
169 + "node_modules/@esbuild/android-arm": {
170 + "version": "0.21.5",
171 + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
172 + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
173 + "cpu": [
174 + "arm"
175 + ],
176 + "dev": true,
177 + "license": "MIT",
178 + "optional": true,
179 + "os": [
180 + "android"
181 + ],
182 + "engines": {
183 + "node": ">=12"
184 + }
185 + },
186 + "node_modules/@esbuild/android-arm64": {
187 + "version": "0.21.5",
188 + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
189 + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
190 + "cpu": [
191 + "arm64"
192 + ],
193 + "dev": true,
194 + "license": "MIT",
195 + "optional": true,
196 + "os": [
197 + "android"
198 + ],
199 + "engines": {
200 + "node": ">=12"
201 + }
202 + },
203 + "node_modules/@esbuild/android-x64": {
204 + "version": "0.21.5",
205 + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
206 + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
207 + "cpu": [
208 + "x64"
209 + ],
210 + "dev": true,
211 + "license": "MIT",
212 + "optional": true,
213 + "os": [
214 + "android"
215 + ],
216 + "engines": {
217 + "node": ">=12"
218 + }
219 + },
220 + "node_modules/@esbuild/darwin-arm64": {
221 + "version": "0.21.5",
222 + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
223 + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
224 + "cpu": [
225 + "arm64"
226 + ],
227 + "dev": true,
228 + "license": "MIT",
229 + "optional": true,
230 + "os": [
231 + "darwin"
232 + ],
233 + "engines": {
234 + "node": ">=12"
235 + }
236 + },
237 + "node_modules/@esbuild/darwin-x64": {
238 + "version": "0.21.5",
239 + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
240 + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
241 + "cpu": [
242 + "x64"
243 + ],
244 + "dev": true,
245 + "license": "MIT",
246 + "optional": true,
247 + "os": [
248 + "darwin"
249 + ],
250 + "engines": {
251 + "node": ">=12"
252 + }
253 + },
254 + "node_modules/@esbuild/freebsd-arm64": {
255 + "version": "0.21.5",
256 + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
257 + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
258 + "cpu": [
259 + "arm64"
260 + ],
261 + "dev": true,
262 + "license": "MIT",
263 + "optional": true,
264 + "os": [
265 + "freebsd"
266 + ],
267 + "engines": {
268 + "node": ">=12"
269 + }
270 + },
271 + "node_modules/@esbuild/freebsd-x64": {
272 + "version": "0.21.5",
273 + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
274 + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
275 + "cpu": [
276 + "x64"
277 + ],
278 + "dev": true,
279 + "license": "MIT",
280 + "optional": true,
281 + "os": [
282 + "freebsd"
283 + ],
284 + "engines": {
285 + "node": ">=12"
286 + }
287 + },
288 + "node_modules/@esbuild/linux-arm": {
289 + "version": "0.21.5",
290 + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
291 + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
292 + "cpu": [
293 + "arm"
294 + ],
295 + "dev": true,
296 + "license": "MIT",
297 + "optional": true,
298 + "os": [
299 + "linux"
300 + ],
301 + "engines": {
302 + "node": ">=12"
303 + }
304 + },
305 + "node_modules/@esbuild/linux-arm64": {
306 + "version": "0.21.5",
307 + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
308 + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
309 + "cpu": [
310 + "arm64"
311 + ],
312 + "dev": true,
313 + "license": "MIT",
314 + "optional": true,
315 + "os": [
316 + "linux"
317 + ],
318 + "engines": {
319 + "node": ">=12"
320 + }
321 + },
322 + "node_modules/@esbuild/linux-ia32": {
323 + "version": "0.21.5",
324 + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
325 + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
326 + "cpu": [
327 + "ia32"
328 + ],
329 + "dev": true,
330 + "license": "MIT",
331 + "optional": true,
332 + "os": [
333 + "linux"
334 + ],
335 + "engines": {
336 + "node": ">=12"
337 + }
338 + },
339 + "node_modules/@esbuild/linux-loong64": {
340 + "version": "0.21.5",
341 + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
342 + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
343 + "cpu": [
344 + "loong64"
345 + ],
346 + "dev": true,
347 + "license": "MIT",
348 + "optional": true,
349 + "os": [
350 + "linux"
351 + ],
352 + "engines": {
353 + "node": ">=12"
354 + }
355 + },
356 + "node_modules/@esbuild/linux-mips64el": {
357 + "version": "0.21.5",
358 + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
359 + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
360 + "cpu": [
361 + "mips64el"
362 + ],
363 + "dev": true,
364 + "license": "MIT",
365 + "optional": true,
366 + "os": [
367 + "linux"
368 + ],
369 + "engines": {
370 + "node": ">=12"
371 + }
372 + },
373 + "node_modules/@esbuild/linux-ppc64": {
374 + "version": "0.21.5",
375 + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
376 + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
377 + "cpu": [
378 + "ppc64"
379 + ],
380 + "dev": true,
381 + "license": "MIT",
382 + "optional": true,
383 + "os": [
384 + "linux"
385 + ],
386 + "engines": {
387 + "node": ">=12"
388 + }
389 + },
390 + "node_modules/@esbuild/linux-riscv64": {
391 + "version": "0.21.5",
392 + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
393 + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
394 + "cpu": [
395 + "riscv64"
396 + ],
397 + "dev": true,
398 + "license": "MIT",
399 + "optional": true,
400 + "os": [
401 + "linux"
402 + ],
403 + "engines": {
404 + "node": ">=12"
405 + }
406 + },
407 + "node_modules/@esbuild/linux-s390x": {
408 + "version": "0.21.5",
409 + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
410 + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
411 + "cpu": [
412 + "s390x"
413 + ],
414 + "dev": true,
415 + "license": "MIT",
416 + "optional": true,
417 + "os": [
418 + "linux"
419 + ],
420 + "engines": {
421 + "node": ">=12"
422 + }
423 + },
424 + "node_modules/@esbuild/linux-x64": {
425 + "version": "0.21.5",
426 + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
427 + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
428 + "cpu": [
429 + "x64"
430 + ],
431 + "dev": true,
432 + "license": "MIT",
433 + "optional": true,
434 + "os": [
435 + "linux"
436 + ],
437 + "engines": {
438 + "node": ">=12"
439 + }
440 + },
441 + "node_modules/@esbuild/netbsd-arm64": {
442 + "version": "0.25.0",
443 + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.0.tgz",
444 + "integrity": "sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==",
445 + "cpu": [
446 + "arm64"
447 + ],
448 + "dev": true,
449 + "license": "MIT",
450 + "optional": true,
451 + "os": [
452 + "netbsd"
453 + ],
454 + "engines": {
455 + "node": ">=18"
456 + }
457 + },
458 + "node_modules/@esbuild/netbsd-x64": {
459 + "version": "0.21.5",
460 + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
461 + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
462 + "cpu": [
463 + "x64"
464 + ],
465 + "dev": true,
466 + "license": "MIT",
467 + "optional": true,
468 + "os": [
469 + "netbsd"
470 + ],
471 + "engines": {
472 + "node": ">=12"
473 + }
474 + },
475 + "node_modules/@esbuild/openbsd-arm64": {
476 + "version": "0.25.0",
477 + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.0.tgz",
478 + "integrity": "sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==",
479 + "cpu": [
480 + "arm64"
481 + ],
482 + "dev": true,
483 + "license": "MIT",
484 + "optional": true,
485 + "os": [
486 + "openbsd"
487 + ],
488 + "engines": {
489 + "node": ">=18"
490 + }
491 + },
492 + "node_modules/@esbuild/openbsd-x64": {
493 + "version": "0.21.5",
494 + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
495 + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
496 + "cpu": [
497 + "x64"
498 + ],
499 + "dev": true,
500 + "license": "MIT",
501 + "optional": true,
502 + "os": [
503 + "openbsd"
504 + ],
505 + "engines": {
506 + "node": ">=12"
507 + }
508 + },
509 + "node_modules/@esbuild/sunos-x64": {
510 + "version": "0.21.5",
511 + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
512 + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
513 + "cpu": [
514 + "x64"
515 + ],
516 + "dev": true,
517 + "license": "MIT",
518 + "optional": true,
519 + "os": [
520 + "sunos"
521 + ],
522 + "engines": {
523 + "node": ">=12"
524 + }
525 + },
526 + "node_modules/@esbuild/win32-arm64": {
527 + "version": "0.21.5",
528 + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
529 + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
530 + "cpu": [
531 + "arm64"
532 + ],
533 + "dev": true,
534 + "license": "MIT",
535 + "optional": true,
536 + "os": [
537 + "win32"
538 + ],
539 + "engines": {
540 + "node": ">=12"
541 + }
542 + },
543 + "node_modules/@esbuild/win32-ia32": {
544 + "version": "0.21.5",
545 + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
546 + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
547 + "cpu": [
548 + "ia32"
549 + ],
550 + "dev": true,
551 + "license": "MIT",
552 + "optional": true,
553 + "os": [
554 + "win32"
555 + ],
556 + "engines": {
557 + "node": ">=12"
558 + }
559 + },
560 + "node_modules/@esbuild/win32-x64": {
561 + "version": "0.21.5",
562 + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
563 + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
564 + "cpu": [
565 + "x64"
566 + ],
567 + "dev": true,
568 + "license": "MIT",
569 + "optional": true,
570 + "os": [
571 + "win32"
572 + ],
573 + "engines": {
574 + "node": ">=12"
575 + }
576 + },
577 + "node_modules/@eslint-community/eslint-utils": {
578 + "version": "4.7.0",
579 + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz",
580 + "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==",
581 + "dev": true,
582 + "license": "MIT",
583 + "dependencies": {
584 + "eslint-visitor-keys": "^3.4.3"
585 + },
586 + "engines": {
587 + "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
588 + },
589 + "funding": {
590 + "url": "https://opencollective.com/eslint"
591 + },
592 + "peerDependencies": {
593 + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
594 + }
595 + },
596 + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
597 + "version": "3.4.3",
598 + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
599 + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
600 + "dev": true,
601 + "license": "Apache-2.0",
602 + "engines": {
603 + "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
604 + },
605 + "funding": {
606 + "url": "https://opencollective.com/eslint"
607 + }
608 + },
609 + "node_modules/@eslint-community/regexpp": {
610 + "version": "4.12.1",
611 + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
612 + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
613 + "dev": true,
614 + "license": "MIT",
615 + "engines": {
616 + "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
617 + }
618 + },
619 + "node_modules/@eslint/config-array": {
620 + "version": "0.21.0",
621 + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz",
622 + "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==",
623 + "dev": true,
624 + "license": "Apache-2.0",
625 + "dependencies": {
626 + "@eslint/object-schema": "^2.1.6",
627 + "debug": "^4.3.1",
628 + "minimatch": "^3.1.2"
629 + },
630 + "engines": {
631 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
632 + }
633 + },
634 + "node_modules/@eslint/config-helpers": {
635 + "version": "0.3.0",
636 + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.0.tgz",
637 + "integrity": "sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==",
638 + "dev": true,
639 + "license": "Apache-2.0",
640 + "engines": {
641 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
642 + }
643 + },
644 + "node_modules/@eslint/core": {
645 + "version": "0.15.1",
646 + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.1.tgz",
647 + "integrity": "sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==",
648 + "dev": true,
649 + "license": "Apache-2.0",
650 + "dependencies": {
651 + "@types/json-schema": "^7.0.15"
652 + },
653 + "engines": {
654 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
655 + }
656 + },
657 + "node_modules/@eslint/eslintrc": {
658 + "version": "3.3.1",
659 + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz",
660 + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==",
661 + "dev": true,
662 + "license": "MIT",
663 + "dependencies": {
664 + "ajv": "^6.12.4",
665 + "debug": "^4.3.2",
666 + "espree": "^10.0.1",
667 + "globals": "^14.0.0",
668 + "ignore": "^5.2.0",
669 + "import-fresh": "^3.2.1",
670 + "js-yaml": "^4.1.0",
671 + "minimatch": "^3.1.2",
672 + "strip-json-comments": "^3.1.1"
673 + },
674 + "engines": {
675 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
676 + },
677 + "funding": {
678 + "url": "https://opencollective.com/eslint"
679 + }
680 + },
681 + "node_modules/@eslint/eslintrc/node_modules/globals": {
682 + "version": "14.0.0",
683 + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
684 + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
685 + "dev": true,
686 + "license": "MIT",
687 + "engines": {
688 + "node": ">=18"
689 + },
690 + "funding": {
691 + "url": "https://github.com/sponsors/sindresorhus"
692 + }
693 + },
694 + "node_modules/@eslint/js": {
695 + "version": "9.32.0",
696 + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.32.0.tgz",
697 + "integrity": "sha512-BBpRFZK3eX6uMLKz8WxFOBIFFcGFJ/g8XuwjTHCqHROSIsopI+ddn/d5Cfh36+7+e5edVS8dbSHnBNhrLEX0zg==",
698 + "dev": true,
699 + "license": "MIT",
700 + "engines": {
701 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
702 + },
703 + "funding": {
704 + "url": "https://eslint.org/donate"
705 + }
706 + },
707 + "node_modules/@eslint/object-schema": {
708 + "version": "2.1.6",
709 + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz",
710 + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==",
711 + "dev": true,
712 + "license": "Apache-2.0",
713 + "engines": {
714 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
715 + }
716 + },
717 + "node_modules/@eslint/plugin-kit": {
718 + "version": "0.3.4",
719 + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.4.tgz",
720 + "integrity": "sha512-Ul5l+lHEcw3L5+k8POx6r74mxEYKG5kOb6Xpy2gCRW6zweT6TEhAf8vhxGgjhqrd/VO/Dirhsb+1hNpD1ue9hw==",
721 + "dev": true,
722 + "license": "Apache-2.0",
723 + "dependencies": {
724 + "@eslint/core": "^0.15.1",
725 + "levn": "^0.4.1"
726 + },
727 + "engines": {
728 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
729 + }
730 + },
731 + "node_modules/@floating-ui/core": {
732 + "version": "1.7.2",
733 + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.2.tgz",
734 + "integrity": "sha512-wNB5ooIKHQc+Kui96jE/n69rHFWAVoxn5CAzL1Xdd8FG03cgY3MLO+GF9U3W737fYDSgPWA6MReKhBQBop6Pcw==",
735 + "license": "MIT",
736 + "dependencies": {
737 + "@floating-ui/utils": "^0.2.10"
738 + }
739 + },
740 + "node_modules/@floating-ui/dom": {
741 + "version": "1.7.2",
742 + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.2.tgz",
743 + "integrity": "sha512-7cfaOQuCS27HD7DX+6ib2OrnW+b4ZBwDNnCcT0uTyidcmyWb03FnQqJybDBoCnpdxwBSfA94UAYlRCt7mV+TbA==",
744 + "license": "MIT",
745 + "dependencies": {
746 + "@floating-ui/core": "^1.7.2",
747 + "@floating-ui/utils": "^0.2.10"
748 + }
749 + },
750 + "node_modules/@floating-ui/react-dom": {
751 + "version": "2.1.4",
752 + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.4.tgz",
753 + "integrity": "sha512-JbbpPhp38UmXDDAu60RJmbeme37Jbgsm7NrHGgzYYFKmblzRUh6Pa641dII6LsjwF4XlScDrde2UAzDo/b9KPw==",
754 + "license": "MIT",
755 + "dependencies": {
756 + "@floating-ui/dom": "^1.7.2"
757 + },
758 + "peerDependencies": {
759 + "react": ">=16.8.0",
760 + "react-dom": ">=16.8.0"
761 + }
762 + },
763 + "node_modules/@floating-ui/utils": {
764 + "version": "0.2.10",
765 + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz",
766 + "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==",
767 + "license": "MIT"
768 + },
769 + "node_modules/@hookform/resolvers": {
770 + "version": "3.10.0",
771 + "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.10.0.tgz",
772 + "integrity": "sha512-79Dv+3mDF7i+2ajj7SkypSKHhl1cbln1OGavqrsF7p6mbUv11xpqpacPsGDCTRvCSjEEIez2ef1NveSVL3b0Ag==",
773 + "license": "MIT",
774 + "peerDependencies": {
775 + "react-hook-form": "^7.0.0"
776 + }
777 + },
778 + "node_modules/@humanfs/core": {
779 + "version": "0.19.1",
780 + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
781 + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
782 + "dev": true,
783 + "license": "Apache-2.0",
784 + "engines": {
785 + "node": ">=18.18.0"
786 + }
787 + },
788 + "node_modules/@humanfs/node": {
789 + "version": "0.16.6",
790 + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz",
791 + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==",
792 + "dev": true,
793 + "license": "Apache-2.0",
794 + "dependencies": {
795 + "@humanfs/core": "^0.19.1",
796 + "@humanwhocodes/retry": "^0.3.0"
797 + },
798 + "engines": {
799 + "node": ">=18.18.0"
800 + }
801 + },
802 + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": {
803 + "version": "0.3.1",
804 + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz",
805 + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==",
806 + "dev": true,
807 + "license": "Apache-2.0",
808 + "engines": {
809 + "node": ">=18.18"
810 + },
811 + "funding": {
812 + "type": "github",
813 + "url": "https://github.com/sponsors/nzakas"
814 + }
815 + },
816 + "node_modules/@humanwhocodes/module-importer": {
817 + "version": "1.0.1",
818 + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
819 + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
820 + "dev": true,
821 + "license": "Apache-2.0",
822 + "engines": {
823 + "node": ">=12.22"
824 + },
825 + "funding": {
826 + "type": "github",
827 + "url": "https://github.com/sponsors/nzakas"
828 + }
829 + },
830 + "node_modules/@humanwhocodes/retry": {
831 + "version": "0.4.3",
832 + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
833 + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
834 + "dev": true,
835 + "license": "Apache-2.0",
836 + "engines": {
837 + "node": ">=18.18"
838 + },
839 + "funding": {
840 + "type": "github",
841 + "url": "https://github.com/sponsors/nzakas"
842 + }
843 + },
844 + "node_modules/@isaacs/cliui": {
845 + "version": "8.0.2",
846 + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
847 + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
848 + "license": "ISC",
849 + "dependencies": {
850 + "string-width": "^5.1.2",
851 + "string-width-cjs": "npm:string-width@^4.2.0",
852 + "strip-ansi": "^7.0.1",
853 + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
854 + "wrap-ansi": "^8.1.0",
855 + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
856 + },
857 + "engines": {
858 + "node": ">=12"
859 + }
860 + },
861 + "node_modules/@jridgewell/gen-mapping": {
862 + "version": "0.3.5",
863 + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
864 + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
865 + "license": "MIT",
866 + "dependencies": {
867 + "@jridgewell/set-array": "^1.2.1",
868 + "@jridgewell/sourcemap-codec": "^1.4.10",
869 + "@jridgewell/trace-mapping": "^0.3.24"
870 + },
871 + "engines": {
872 + "node": ">=6.0.0"
873 + }
874 + },
875 + "node_modules/@jridgewell/resolve-uri": {
876 + "version": "3.1.2",
877 + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
878 + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
879 + "license": "MIT",
880 + "engines": {
881 + "node": ">=6.0.0"
882 + }
883 + },
884 + "node_modules/@jridgewell/set-array": {
885 + "version": "1.2.1",
886 + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
887 + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
888 + "license": "MIT",
889 + "engines": {
890 + "node": ">=6.0.0"
891 + }
892 + },
893 + "node_modules/@jridgewell/sourcemap-codec": {
894 + "version": "1.5.0",
895 + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
896 + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
897 + "license": "MIT"
898 + },
899 + "node_modules/@jridgewell/trace-mapping": {
900 + "version": "0.3.25",
901 + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
902 + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
903 + "license": "MIT",
904 + "dependencies": {
905 + "@jridgewell/resolve-uri": "^3.1.0",
906 + "@jridgewell/sourcemap-codec": "^1.4.14"
907 + }
908 + },
909 + "node_modules/@nodelib/fs.scandir": {
910 + "version": "2.1.5",
911 + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
912 + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
913 + "license": "MIT",
914 + "dependencies": {
915 + "@nodelib/fs.stat": "2.0.5",
916 + "run-parallel": "^1.1.9"
917 + },
918 + "engines": {
919 + "node": ">= 8"
920 + }
921 + },
922 + "node_modules/@nodelib/fs.stat": {
923 + "version": "2.0.5",
924 + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
925 + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
926 + "license": "MIT",
927 + "engines": {
928 + "node": ">= 8"
929 + }
930 + },
931 + "node_modules/@nodelib/fs.walk": {
932 + "version": "1.2.8",
933 + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
934 + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
935 + "license": "MIT",
936 + "dependencies": {
937 + "@nodelib/fs.scandir": "2.1.5",
938 + "fastq": "^1.6.0"
939 + },
940 + "engines": {
941 + "node": ">= 8"
942 + }
943 + },
944 + "node_modules/@pkgjs/parseargs": {
945 + "version": "0.11.0",
946 + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
947 + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
948 + "license": "MIT",
949 + "optional": true,
950 + "engines": {
951 + "node": ">=14"
952 + }
953 + },
954 + "node_modules/@radix-ui/number": {
955 + "version": "1.1.1",
956 + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz",
957 + "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==",
958 + "license": "MIT"
959 + },
960 + "node_modules/@radix-ui/primitive": {
961 + "version": "1.1.2",
962 + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.2.tgz",
963 + "integrity": "sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==",
964 + "license": "MIT"
965 + },
966 + "node_modules/@radix-ui/react-accordion": {
967 + "version": "1.2.11",
968 + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.11.tgz",
969 + "integrity": "sha512-l3W5D54emV2ues7jjeG1xcyN7S3jnK3zE2zHqgn0CmMsy9lNJwmgcrmaxS+7ipw15FAivzKNzH3d5EcGoFKw0A==",
970 + "license": "MIT",
971 + "dependencies": {
972 + "@radix-ui/primitive": "1.1.2",
973 + "@radix-ui/react-collapsible": "1.1.11",
974 + "@radix-ui/react-collection": "1.1.7",
975 + "@radix-ui/react-compose-refs": "1.1.2",
976 + "@radix-ui/react-context": "1.1.2",
977 + "@radix-ui/react-direction": "1.1.1",
978 + "@radix-ui/react-id": "1.1.1",
979 + "@radix-ui/react-primitive": "2.1.3",
980 + "@radix-ui/react-use-controllable-state": "1.2.2"
981 + },
982 + "peerDependencies": {
983 + "@types/react": "*",
984 + "@types/react-dom": "*",
985 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
986 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
987 + },
988 + "peerDependenciesMeta": {
989 + "@types/react": {
990 + "optional": true
991 + },
992 + "@types/react-dom": {
993 + "optional": true
994 + }
995 + }
996 + },
997 + "node_modules/@radix-ui/react-alert-dialog": {
998 + "version": "1.1.14",
999 + "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.14.tgz",
1000 + "integrity": "sha512-IOZfZ3nPvN6lXpJTBCunFQPRSvK8MDgSc1FB85xnIpUKOw9en0dJj8JmCAxV7BiZdtYlUpmrQjoTFkVYtdoWzQ==",
1001 + "license": "MIT",
1002 + "dependencies": {
1003 + "@radix-ui/primitive": "1.1.2",
1004 + "@radix-ui/react-compose-refs": "1.1.2",
1005 + "@radix-ui/react-context": "1.1.2",
1006 + "@radix-ui/react-dialog": "1.1.14",
1007 + "@radix-ui/react-primitive": "2.1.3",
1008 + "@radix-ui/react-slot": "1.2.3"
1009 + },
1010 + "peerDependencies": {
1011 + "@types/react": "*",
1012 + "@types/react-dom": "*",
1013 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1014 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1015 + },
1016 + "peerDependenciesMeta": {
1017 + "@types/react": {
1018 + "optional": true
1019 + },
1020 + "@types/react-dom": {
1021 + "optional": true
1022 + }
1023 + }
1024 + },
1025 + "node_modules/@radix-ui/react-arrow": {
1026 + "version": "1.1.7",
1027 + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz",
1028 + "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==",
1029 + "license": "MIT",
1030 + "dependencies": {
1031 + "@radix-ui/react-primitive": "2.1.3"
1032 + },
1033 + "peerDependencies": {
1034 + "@types/react": "*",
1035 + "@types/react-dom": "*",
1036 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1037 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1038 + },
1039 + "peerDependenciesMeta": {
1040 + "@types/react": {
1041 + "optional": true
1042 + },
1043 + "@types/react-dom": {
1044 + "optional": true
1045 + }
1046 + }
1047 + },
1048 + "node_modules/@radix-ui/react-aspect-ratio": {
1049 + "version": "1.1.7",
1050 + "resolved": "https://registry.npmjs.org/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.1.7.tgz",
1051 + "integrity": "sha512-Yq6lvO9HQyPwev1onK1daHCHqXVLzPhSVjmsNjCa2Zcxy2f7uJD2itDtxknv6FzAKCwD1qQkeVDmX/cev13n/g==",
1052 + "license": "MIT",
1053 + "dependencies": {
1054 + "@radix-ui/react-primitive": "2.1.3"
1055 + },
1056 + "peerDependencies": {
1057 + "@types/react": "*",
1058 + "@types/react-dom": "*",
1059 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1060 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1061 + },
1062 + "peerDependenciesMeta": {
1063 + "@types/react": {
1064 + "optional": true
1065 + },
1066 + "@types/react-dom": {
1067 + "optional": true
1068 + }
1069 + }
1070 + },
1071 + "node_modules/@radix-ui/react-avatar": {
1072 + "version": "1.1.10",
1073 + "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.10.tgz",
1074 + "integrity": "sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==",
1075 + "license": "MIT",
1076 + "dependencies": {
1077 + "@radix-ui/react-context": "1.1.2",
1078 + "@radix-ui/react-primitive": "2.1.3",
1079 + "@radix-ui/react-use-callback-ref": "1.1.1",
1080 + "@radix-ui/react-use-is-hydrated": "0.1.0",
1081 + "@radix-ui/react-use-layout-effect": "1.1.1"
1082 + },
1083 + "peerDependencies": {
1084 + "@types/react": "*",
1085 + "@types/react-dom": "*",
1086 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1087 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1088 + },
1089 + "peerDependenciesMeta": {
1090 + "@types/react": {
1091 + "optional": true
1092 + },
1093 + "@types/react-dom": {
1094 + "optional": true
1095 + }
1096 + }
1097 + },
1098 + "node_modules/@radix-ui/react-checkbox": {
1099 + "version": "1.3.2",
1100 + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.2.tgz",
1101 + "integrity": "sha512-yd+dI56KZqawxKZrJ31eENUwqc1QSqg4OZ15rybGjF2ZNwMO+wCyHzAVLRp9qoYJf7kYy0YpZ2b0JCzJ42HZpA==",
1102 + "license": "MIT",
1103 + "dependencies": {
1104 + "@radix-ui/primitive": "1.1.2",
1105 + "@radix-ui/react-compose-refs": "1.1.2",
1106 + "@radix-ui/react-context": "1.1.2",
1107 + "@radix-ui/react-presence": "1.1.4",
1108 + "@radix-ui/react-primitive": "2.1.3",
1109 + "@radix-ui/react-use-controllable-state": "1.2.2",
1110 + "@radix-ui/react-use-previous": "1.1.1",
1111 + "@radix-ui/react-use-size": "1.1.1"
1112 + },
1113 + "peerDependencies": {
1114 + "@types/react": "*",
1115 + "@types/react-dom": "*",
1116 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1117 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1118 + },
1119 + "peerDependenciesMeta": {
1120 + "@types/react": {
1121 + "optional": true
1122 + },
1123 + "@types/react-dom": {
1124 + "optional": true
1125 + }
1126 + }
1127 + },
1128 + "node_modules/@radix-ui/react-collapsible": {
1129 + "version": "1.1.11",
1130 + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.11.tgz",
1131 + "integrity": "sha512-2qrRsVGSCYasSz1RFOorXwl0H7g7J1frQtgpQgYrt+MOidtPAINHn9CPovQXb83r8ahapdx3Tu0fa/pdFFSdPg==",
1132 + "license": "MIT",
1133 + "dependencies": {
1134 + "@radix-ui/primitive": "1.1.2",
1135 + "@radix-ui/react-compose-refs": "1.1.2",
1136 + "@radix-ui/react-context": "1.1.2",
1137 + "@radix-ui/react-id": "1.1.1",
1138 + "@radix-ui/react-presence": "1.1.4",
1139 + "@radix-ui/react-primitive": "2.1.3",
1140 + "@radix-ui/react-use-controllable-state": "1.2.2",
1141 + "@radix-ui/react-use-layout-effect": "1.1.1"
1142 + },
1143 + "peerDependencies": {
1144 + "@types/react": "*",
1145 + "@types/react-dom": "*",
1146 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1147 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1148 + },
1149 + "peerDependenciesMeta": {
1150 + "@types/react": {
1151 + "optional": true
1152 + },
1153 + "@types/react-dom": {
1154 + "optional": true
1155 + }
1156 + }
1157 + },
1158 + "node_modules/@radix-ui/react-collection": {
1159 + "version": "1.1.7",
1160 + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz",
1161 + "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==",
1162 + "license": "MIT",
1163 + "dependencies": {
1164 + "@radix-ui/react-compose-refs": "1.1.2",
1165 + "@radix-ui/react-context": "1.1.2",
1166 + "@radix-ui/react-primitive": "2.1.3",
1167 + "@radix-ui/react-slot": "1.2.3"
1168 + },
1169 + "peerDependencies": {
1170 + "@types/react": "*",
1171 + "@types/react-dom": "*",
1172 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1173 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1174 + },
1175 + "peerDependenciesMeta": {
1176 + "@types/react": {
1177 + "optional": true
1178 + },
1179 + "@types/react-dom": {
1180 + "optional": true
1181 + }
1182 + }
1183 + },
1184 + "node_modules/@radix-ui/react-compose-refs": {
1185 + "version": "1.1.2",
1186 + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
1187 + "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
1188 + "license": "MIT",
1189 + "peerDependencies": {
1190 + "@types/react": "*",
1191 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1192 + },
1193 + "peerDependenciesMeta": {
1194 + "@types/react": {
1195 + "optional": true
1196 + }
1197 + }
1198 + },
1199 + "node_modules/@radix-ui/react-context": {
1200 + "version": "1.1.2",
1201 + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz",
1202 + "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==",
1203 + "license": "MIT",
1204 + "peerDependencies": {
1205 + "@types/react": "*",
1206 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1207 + },
1208 + "peerDependenciesMeta": {
1209 + "@types/react": {
1210 + "optional": true
1211 + }
1212 + }
1213 + },
1214 + "node_modules/@radix-ui/react-context-menu": {
1215 + "version": "2.2.15",
1216 + "resolved": "https://registry.npmjs.org/@radix-ui/react-context-menu/-/react-context-menu-2.2.15.tgz",
1217 + "integrity": "sha512-UsQUMjcYTsBjTSXw0P3GO0werEQvUY2plgRQuKoCTtkNr45q1DiL51j4m7gxhABzZ0BadoXNsIbg7F3KwiUBbw==",
1218 + "license": "MIT",
1219 + "dependencies": {
1220 + "@radix-ui/primitive": "1.1.2",
1221 + "@radix-ui/react-context": "1.1.2",
1222 + "@radix-ui/react-menu": "2.1.15",
1223 + "@radix-ui/react-primitive": "2.1.3",
1224 + "@radix-ui/react-use-callback-ref": "1.1.1",
1225 + "@radix-ui/react-use-controllable-state": "1.2.2"
1226 + },
1227 + "peerDependencies": {
1228 + "@types/react": "*",
1229 + "@types/react-dom": "*",
1230 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1231 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1232 + },
1233 + "peerDependenciesMeta": {
1234 + "@types/react": {
1235 + "optional": true
1236 + },
1237 + "@types/react-dom": {
1238 + "optional": true
1239 + }
1240 + }
1241 + },
1242 + "node_modules/@radix-ui/react-dialog": {
1243 + "version": "1.1.14",
1244 + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.14.tgz",
1245 + "integrity": "sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw==",
1246 + "license": "MIT",
1247 + "dependencies": {
1248 + "@radix-ui/primitive": "1.1.2",
1249 + "@radix-ui/react-compose-refs": "1.1.2",
1250 + "@radix-ui/react-context": "1.1.2",
1251 + "@radix-ui/react-dismissable-layer": "1.1.10",
1252 + "@radix-ui/react-focus-guards": "1.1.2",
1253 + "@radix-ui/react-focus-scope": "1.1.7",
1254 + "@radix-ui/react-id": "1.1.1",
1255 + "@radix-ui/react-portal": "1.1.9",
1256 + "@radix-ui/react-presence": "1.1.4",
1257 + "@radix-ui/react-primitive": "2.1.3",
1258 + "@radix-ui/react-slot": "1.2.3",
1259 + "@radix-ui/react-use-controllable-state": "1.2.2",
1260 + "aria-hidden": "^1.2.4",
1261 + "react-remove-scroll": "^2.6.3"
1262 + },
1263 + "peerDependencies": {
1264 + "@types/react": "*",
1265 + "@types/react-dom": "*",
1266 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1267 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1268 + },
1269 + "peerDependenciesMeta": {
1270 + "@types/react": {
1271 + "optional": true
1272 + },
1273 + "@types/react-dom": {
1274 + "optional": true
1275 + }
1276 + }
1277 + },
1278 + "node_modules/@radix-ui/react-direction": {
1279 + "version": "1.1.1",
1280 + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz",
1281 + "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==",
1282 + "license": "MIT",
1283 + "peerDependencies": {
1284 + "@types/react": "*",
1285 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1286 + },
1287 + "peerDependenciesMeta": {
1288 + "@types/react": {
1289 + "optional": true
1290 + }
1291 + }
1292 + },
1293 + "node_modules/@radix-ui/react-dismissable-layer": {
1294 + "version": "1.1.10",
1295 + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.10.tgz",
1296 + "integrity": "sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==",
1297 + "license": "MIT",
1298 + "dependencies": {
1299 + "@radix-ui/primitive": "1.1.2",
1300 + "@radix-ui/react-compose-refs": "1.1.2",
1301 + "@radix-ui/react-primitive": "2.1.3",
1302 + "@radix-ui/react-use-callback-ref": "1.1.1",
1303 + "@radix-ui/react-use-escape-keydown": "1.1.1"
1304 + },
1305 + "peerDependencies": {
1306 + "@types/react": "*",
1307 + "@types/react-dom": "*",
1308 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1309 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1310 + },
1311 + "peerDependenciesMeta": {
1312 + "@types/react": {
1313 + "optional": true
1314 + },
1315 + "@types/react-dom": {
1316 + "optional": true
1317 + }
1318 + }
1319 + },
1320 + "node_modules/@radix-ui/react-dropdown-menu": {
1321 + "version": "2.1.15",
1322 + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.15.tgz",
1323 + "integrity": "sha512-mIBnOjgwo9AH3FyKaSWoSu/dYj6VdhJ7frEPiGTeXCdUFHjl9h3mFh2wwhEtINOmYXWhdpf1rY2minFsmaNgVQ==",
1324 + "license": "MIT",
1325 + "dependencies": {
1326 + "@radix-ui/primitive": "1.1.2",
1327 + "@radix-ui/react-compose-refs": "1.1.2",
1328 + "@radix-ui/react-context": "1.1.2",
1329 + "@radix-ui/react-id": "1.1.1",
1330 + "@radix-ui/react-menu": "2.1.15",
1331 + "@radix-ui/react-primitive": "2.1.3",
1332 + "@radix-ui/react-use-controllable-state": "1.2.2"
1333 + },
1334 + "peerDependencies": {
1335 + "@types/react": "*",
1336 + "@types/react-dom": "*",
1337 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1338 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1339 + },
1340 + "peerDependenciesMeta": {
1341 + "@types/react": {
1342 + "optional": true
1343 + },
1344 + "@types/react-dom": {
1345 + "optional": true
1346 + }
1347 + }
1348 + },
1349 + "node_modules/@radix-ui/react-focus-guards": {
1350 + "version": "1.1.2",
1351 + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.2.tgz",
1352 + "integrity": "sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==",
1353 + "license": "MIT",
1354 + "peerDependencies": {
1355 + "@types/react": "*",
1356 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1357 + },
1358 + "peerDependenciesMeta": {
1359 + "@types/react": {
1360 + "optional": true
1361 + }
1362 + }
1363 + },
1364 + "node_modules/@radix-ui/react-focus-scope": {
1365 + "version": "1.1.7",
1366 + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz",
1367 + "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==",
1368 + "license": "MIT",
1369 + "dependencies": {
1370 + "@radix-ui/react-compose-refs": "1.1.2",
1371 + "@radix-ui/react-primitive": "2.1.3",
1372 + "@radix-ui/react-use-callback-ref": "1.1.1"
1373 + },
1374 + "peerDependencies": {
1375 + "@types/react": "*",
1376 + "@types/react-dom": "*",
1377 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1378 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1379 + },
1380 + "peerDependenciesMeta": {
1381 + "@types/react": {
1382 + "optional": true
1383 + },
1384 + "@types/react-dom": {
1385 + "optional": true
1386 + }
1387 + }
1388 + },
1389 + "node_modules/@radix-ui/react-hover-card": {
1390 + "version": "1.1.14",
1391 + "resolved": "https://registry.npmjs.org/@radix-ui/react-hover-card/-/react-hover-card-1.1.14.tgz",
1392 + "integrity": "sha512-CPYZ24Mhirm+g6D8jArmLzjYu4Eyg3TTUHswR26QgzXBHBe64BO/RHOJKzmF/Dxb4y4f9PKyJdwm/O/AhNkb+Q==",
1393 + "license": "MIT",
1394 + "dependencies": {
1395 + "@radix-ui/primitive": "1.1.2",
1396 + "@radix-ui/react-compose-refs": "1.1.2",
1397 + "@radix-ui/react-context": "1.1.2",
1398 + "@radix-ui/react-dismissable-layer": "1.1.10",
1399 + "@radix-ui/react-popper": "1.2.7",
1400 + "@radix-ui/react-portal": "1.1.9",
1401 + "@radix-ui/react-presence": "1.1.4",
1402 + "@radix-ui/react-primitive": "2.1.3",
1403 + "@radix-ui/react-use-controllable-state": "1.2.2"
1404 + },
1405 + "peerDependencies": {
1406 + "@types/react": "*",
1407 + "@types/react-dom": "*",
1408 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1409 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1410 + },
1411 + "peerDependenciesMeta": {
1412 + "@types/react": {
1413 + "optional": true
1414 + },
1415 + "@types/react-dom": {
1416 + "optional": true
1417 + }
1418 + }
1419 + },
1420 + "node_modules/@radix-ui/react-id": {
1421 + "version": "1.1.1",
1422 + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz",
1423 + "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==",
1424 + "license": "MIT",
1425 + "dependencies": {
1426 + "@radix-ui/react-use-layout-effect": "1.1.1"
1427 + },
1428 + "peerDependencies": {
1429 + "@types/react": "*",
1430 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1431 + },
1432 + "peerDependenciesMeta": {
1433 + "@types/react": {
1434 + "optional": true
1435 + }
1436 + }
1437 + },
1438 + "node_modules/@radix-ui/react-label": {
1439 + "version": "2.1.7",
1440 + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.7.tgz",
1441 + "integrity": "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==",
1442 + "license": "MIT",
1443 + "dependencies": {
1444 + "@radix-ui/react-primitive": "2.1.3"
1445 + },
1446 + "peerDependencies": {
1447 + "@types/react": "*",
1448 + "@types/react-dom": "*",
1449 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1450 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1451 + },
1452 + "peerDependenciesMeta": {
1453 + "@types/react": {
1454 + "optional": true
1455 + },
1456 + "@types/react-dom": {
1457 + "optional": true
1458 + }
1459 + }
1460 + },
1461 + "node_modules/@radix-ui/react-menu": {
1462 + "version": "2.1.15",
1463 + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.15.tgz",
1464 + "integrity": "sha512-tVlmA3Vb9n8SZSd+YSbuFR66l87Wiy4du+YE+0hzKQEANA+7cWKH1WgqcEX4pXqxUFQKrWQGHdvEfw00TjFiew==",
1465 + "license": "MIT",
1466 + "dependencies": {
1467 + "@radix-ui/primitive": "1.1.2",
1468 + "@radix-ui/react-collection": "1.1.7",
1469 + "@radix-ui/react-compose-refs": "1.1.2",
1470 + "@radix-ui/react-context": "1.1.2",
1471 + "@radix-ui/react-direction": "1.1.1",
1472 + "@radix-ui/react-dismissable-layer": "1.1.10",
1473 + "@radix-ui/react-focus-guards": "1.1.2",
1474 + "@radix-ui/react-focus-scope": "1.1.7",
1475 + "@radix-ui/react-id": "1.1.1",
1476 + "@radix-ui/react-popper": "1.2.7",
1477 + "@radix-ui/react-portal": "1.1.9",
1478 + "@radix-ui/react-presence": "1.1.4",
1479 + "@radix-ui/react-primitive": "2.1.3",
1480 + "@radix-ui/react-roving-focus": "1.1.10",
1481 + "@radix-ui/react-slot": "1.2.3",
1482 + "@radix-ui/react-use-callback-ref": "1.1.1",
1483 + "aria-hidden": "^1.2.4",
1484 + "react-remove-scroll": "^2.6.3"
1485 + },
1486 + "peerDependencies": {
1487 + "@types/react": "*",
1488 + "@types/react-dom": "*",
1489 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1490 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1491 + },
1492 + "peerDependenciesMeta": {
1493 + "@types/react": {
1494 + "optional": true
1495 + },
1496 + "@types/react-dom": {
1497 + "optional": true
1498 + }
1499 + }
1500 + },
1501 + "node_modules/@radix-ui/react-menubar": {
1502 + "version": "1.1.15",
1503 + "resolved": "https://registry.npmjs.org/@radix-ui/react-menubar/-/react-menubar-1.1.15.tgz",
1504 + "integrity": "sha512-Z71C7LGD+YDYo3TV81paUs8f3Zbmkvg6VLRQpKYfzioOE6n7fOhA3ApK/V/2Odolxjoc4ENk8AYCjohCNayd5A==",
1505 + "license": "MIT",
1506 + "dependencies": {
1507 + "@radix-ui/primitive": "1.1.2",
1508 + "@radix-ui/react-collection": "1.1.7",
1509 + "@radix-ui/react-compose-refs": "1.1.2",
1510 + "@radix-ui/react-context": "1.1.2",
1511 + "@radix-ui/react-direction": "1.1.1",
1512 + "@radix-ui/react-id": "1.1.1",
1513 + "@radix-ui/react-menu": "2.1.15",
1514 + "@radix-ui/react-primitive": "2.1.3",
1515 + "@radix-ui/react-roving-focus": "1.1.10",
1516 + "@radix-ui/react-use-controllable-state": "1.2.2"
1517 + },
1518 + "peerDependencies": {
1519 + "@types/react": "*",
1520 + "@types/react-dom": "*",
1521 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1522 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1523 + },
1524 + "peerDependenciesMeta": {
1525 + "@types/react": {
1526 + "optional": true
1527 + },
1528 + "@types/react-dom": {
1529 + "optional": true
1530 + }
1531 + }
1532 + },
1533 + "node_modules/@radix-ui/react-navigation-menu": {
1534 + "version": "1.2.13",
1535 + "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.13.tgz",
1536 + "integrity": "sha512-WG8wWfDiJlSF5hELjwfjSGOXcBR/ZMhBFCGYe8vERpC39CQYZeq1PQ2kaYHdye3V95d06H89KGMsVCIE4LWo3g==",
1537 + "license": "MIT",
1538 + "dependencies": {
1539 + "@radix-ui/primitive": "1.1.2",
1540 + "@radix-ui/react-collection": "1.1.7",
1541 + "@radix-ui/react-compose-refs": "1.1.2",
1542 + "@radix-ui/react-context": "1.1.2",
1543 + "@radix-ui/react-direction": "1.1.1",
1544 + "@radix-ui/react-dismissable-layer": "1.1.10",
1545 + "@radix-ui/react-id": "1.1.1",
1546 + "@radix-ui/react-presence": "1.1.4",
1547 + "@radix-ui/react-primitive": "2.1.3",
1548 + "@radix-ui/react-use-callback-ref": "1.1.1",
1549 + "@radix-ui/react-use-controllable-state": "1.2.2",
1550 + "@radix-ui/react-use-layout-effect": "1.1.1",
1551 + "@radix-ui/react-use-previous": "1.1.1",
1552 + "@radix-ui/react-visually-hidden": "1.2.3"
1553 + },
1554 + "peerDependencies": {
1555 + "@types/react": "*",
1556 + "@types/react-dom": "*",
1557 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1558 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1559 + },
1560 + "peerDependenciesMeta": {
1561 + "@types/react": {
1562 + "optional": true
1563 + },
1564 + "@types/react-dom": {
1565 + "optional": true
1566 + }
1567 + }
1568 + },
1569 + "node_modules/@radix-ui/react-popover": {
1570 + "version": "1.1.14",
1571 + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.14.tgz",
1572 + "integrity": "sha512-ODz16+1iIbGUfFEfKx2HTPKizg2MN39uIOV8MXeHnmdd3i/N9Wt7vU46wbHsqA0xoaQyXVcs0KIlBdOA2Y95bw==",
1573 + "license": "MIT",
1574 + "dependencies": {
1575 + "@radix-ui/primitive": "1.1.2",
1576 + "@radix-ui/react-compose-refs": "1.1.2",
1577 + "@radix-ui/react-context": "1.1.2",
1578 + "@radix-ui/react-dismissable-layer": "1.1.10",
1579 + "@radix-ui/react-focus-guards": "1.1.2",
1580 + "@radix-ui/react-focus-scope": "1.1.7",
1581 + "@radix-ui/react-id": "1.1.1",
1582 + "@radix-ui/react-popper": "1.2.7",
1583 + "@radix-ui/react-portal": "1.1.9",
1584 + "@radix-ui/react-presence": "1.1.4",
1585 + "@radix-ui/react-primitive": "2.1.3",
1586 + "@radix-ui/react-slot": "1.2.3",
1587 + "@radix-ui/react-use-controllable-state": "1.2.2",
1588 + "aria-hidden": "^1.2.4",
1589 + "react-remove-scroll": "^2.6.3"
1590 + },
1591 + "peerDependencies": {
1592 + "@types/react": "*",
1593 + "@types/react-dom": "*",
1594 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1595 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1596 + },
1597 + "peerDependenciesMeta": {
1598 + "@types/react": {
1599 + "optional": true
1600 + },
1601 + "@types/react-dom": {
1602 + "optional": true
1603 + }
1604 + }
1605 + },
1606 + "node_modules/@radix-ui/react-popper": {
1607 + "version": "1.2.7",
1608 + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.7.tgz",
1609 + "integrity": "sha512-IUFAccz1JyKcf/RjB552PlWwxjeCJB8/4KxT7EhBHOJM+mN7LdW+B3kacJXILm32xawcMMjb2i0cIZpo+f9kiQ==",
1610 + "license": "MIT",
1611 + "dependencies": {
1612 + "@floating-ui/react-dom": "^2.0.0",
1613 + "@radix-ui/react-arrow": "1.1.7",
1614 + "@radix-ui/react-compose-refs": "1.1.2",
1615 + "@radix-ui/react-context": "1.1.2",
1616 + "@radix-ui/react-primitive": "2.1.3",
1617 + "@radix-ui/react-use-callback-ref": "1.1.1",
1618 + "@radix-ui/react-use-layout-effect": "1.1.1",
1619 + "@radix-ui/react-use-rect": "1.1.1",
1620 + "@radix-ui/react-use-size": "1.1.1",
1621 + "@radix-ui/rect": "1.1.1"
1622 + },
1623 + "peerDependencies": {
1624 + "@types/react": "*",
1625 + "@types/react-dom": "*",
1626 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1627 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1628 + },
1629 + "peerDependenciesMeta": {
1630 + "@types/react": {
1631 + "optional": true
1632 + },
1633 + "@types/react-dom": {
1634 + "optional": true
1635 + }
1636 + }
1637 + },
1638 + "node_modules/@radix-ui/react-portal": {
1639 + "version": "1.1.9",
1640 + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz",
1641 + "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==",
1642 + "license": "MIT",
1643 + "dependencies": {
1644 + "@radix-ui/react-primitive": "2.1.3",
1645 + "@radix-ui/react-use-layout-effect": "1.1.1"
1646 + },
1647 + "peerDependencies": {
1648 + "@types/react": "*",
1649 + "@types/react-dom": "*",
1650 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1651 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1652 + },
1653 + "peerDependenciesMeta": {
1654 + "@types/react": {
1655 + "optional": true
1656 + },
1657 + "@types/react-dom": {
1658 + "optional": true
1659 + }
1660 + }
1661 + },
1662 + "node_modules/@radix-ui/react-presence": {
1663 + "version": "1.1.4",
1664 + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.4.tgz",
1665 + "integrity": "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==",
1666 + "license": "MIT",
1667 + "dependencies": {
1668 + "@radix-ui/react-compose-refs": "1.1.2",
1669 + "@radix-ui/react-use-layout-effect": "1.1.1"
1670 + },
1671 + "peerDependencies": {
1672 + "@types/react": "*",
1673 + "@types/react-dom": "*",
1674 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1675 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1676 + },
1677 + "peerDependenciesMeta": {
1678 + "@types/react": {
1679 + "optional": true
1680 + },
1681 + "@types/react-dom": {
1682 + "optional": true
1683 + }
1684 + }
1685 + },
1686 + "node_modules/@radix-ui/react-primitive": {
1687 + "version": "2.1.3",
1688 + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
1689 + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
1690 + "license": "MIT",
1691 + "dependencies": {
1692 + "@radix-ui/react-slot": "1.2.3"
1693 + },
1694 + "peerDependencies": {
1695 + "@types/react": "*",
1696 + "@types/react-dom": "*",
1697 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1698 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1699 + },
1700 + "peerDependenciesMeta": {
1701 + "@types/react": {
1702 + "optional": true
1703 + },
1704 + "@types/react-dom": {
1705 + "optional": true
1706 + }
1707 + }
1708 + },
1709 + "node_modules/@radix-ui/react-progress": {
1710 + "version": "1.1.7",
1711 + "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.7.tgz",
1712 + "integrity": "sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg==",
1713 + "license": "MIT",
1714 + "dependencies": {
1715 + "@radix-ui/react-context": "1.1.2",
1716 + "@radix-ui/react-primitive": "2.1.3"
1717 + },
1718 + "peerDependencies": {
1719 + "@types/react": "*",
1720 + "@types/react-dom": "*",
1721 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1722 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1723 + },
1724 + "peerDependenciesMeta": {
1725 + "@types/react": {
1726 + "optional": true
1727 + },
1728 + "@types/react-dom": {
1729 + "optional": true
1730 + }
1731 + }
1732 + },
1733 + "node_modules/@radix-ui/react-radio-group": {
1734 + "version": "1.3.7",
1735 + "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.3.7.tgz",
1736 + "integrity": "sha512-9w5XhD0KPOrm92OTTE0SysH3sYzHsSTHNvZgUBo/VZ80VdYyB5RneDbc0dKpURS24IxkoFRu/hI0i4XyfFwY6g==",
1737 + "license": "MIT",
1738 + "dependencies": {
1739 + "@radix-ui/primitive": "1.1.2",
1740 + "@radix-ui/react-compose-refs": "1.1.2",
1741 + "@radix-ui/react-context": "1.1.2",
1742 + "@radix-ui/react-direction": "1.1.1",
1743 + "@radix-ui/react-presence": "1.1.4",
1744 + "@radix-ui/react-primitive": "2.1.3",
1745 + "@radix-ui/react-roving-focus": "1.1.10",
1746 + "@radix-ui/react-use-controllable-state": "1.2.2",
1747 + "@radix-ui/react-use-previous": "1.1.1",
1748 + "@radix-ui/react-use-size": "1.1.1"
1749 + },
1750 + "peerDependencies": {
1751 + "@types/react": "*",
1752 + "@types/react-dom": "*",
1753 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1754 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1755 + },
1756 + "peerDependenciesMeta": {
1757 + "@types/react": {
1758 + "optional": true
1759 + },
1760 + "@types/react-dom": {
1761 + "optional": true
1762 + }
1763 + }
1764 + },
1765 + "node_modules/@radix-ui/react-roving-focus": {
1766 + "version": "1.1.10",
1767 + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.10.tgz",
1768 + "integrity": "sha512-dT9aOXUen9JSsxnMPv/0VqySQf5eDQ6LCk5Sw28kamz8wSOW2bJdlX2Bg5VUIIcV+6XlHpWTIuTPCf/UNIyq8Q==",
1769 + "license": "MIT",
1770 + "dependencies": {
1771 + "@radix-ui/primitive": "1.1.2",
1772 + "@radix-ui/react-collection": "1.1.7",
1773 + "@radix-ui/react-compose-refs": "1.1.2",
1774 + "@radix-ui/react-context": "1.1.2",
1775 + "@radix-ui/react-direction": "1.1.1",
1776 + "@radix-ui/react-id": "1.1.1",
1777 + "@radix-ui/react-primitive": "2.1.3",
1778 + "@radix-ui/react-use-callback-ref": "1.1.1",
1779 + "@radix-ui/react-use-controllable-state": "1.2.2"
1780 + },
1781 + "peerDependencies": {
1782 + "@types/react": "*",
1783 + "@types/react-dom": "*",
1784 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1785 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1786 + },
1787 + "peerDependenciesMeta": {
1788 + "@types/react": {
1789 + "optional": true
1790 + },
1791 + "@types/react-dom": {
1792 + "optional": true
1793 + }
1794 + }
1795 + },
1796 + "node_modules/@radix-ui/react-scroll-area": {
1797 + "version": "1.2.9",
1798 + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.9.tgz",
1799 + "integrity": "sha512-YSjEfBXnhUELsO2VzjdtYYD4CfQjvao+lhhrX5XsHD7/cyUNzljF1FHEbgTPN7LH2MClfwRMIsYlqTYpKTTe2A==",
1800 + "license": "MIT",
1801 + "dependencies": {
1802 + "@radix-ui/number": "1.1.1",
1803 + "@radix-ui/primitive": "1.1.2",
1804 + "@radix-ui/react-compose-refs": "1.1.2",
1805 + "@radix-ui/react-context": "1.1.2",
1806 + "@radix-ui/react-direction": "1.1.1",
1807 + "@radix-ui/react-presence": "1.1.4",
1808 + "@radix-ui/react-primitive": "2.1.3",
1809 + "@radix-ui/react-use-callback-ref": "1.1.1",
1810 + "@radix-ui/react-use-layout-effect": "1.1.1"
1811 + },
1812 + "peerDependencies": {
1813 + "@types/react": "*",
1814 + "@types/react-dom": "*",
1815 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1816 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1817 + },
1818 + "peerDependenciesMeta": {
1819 + "@types/react": {
1820 + "optional": true
1821 + },
1822 + "@types/react-dom": {
1823 + "optional": true
1824 + }
1825 + }
1826 + },
1827 + "node_modules/@radix-ui/react-select": {
1828 + "version": "2.2.5",
1829 + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.5.tgz",
1830 + "integrity": "sha512-HnMTdXEVuuyzx63ME0ut4+sEMYW6oouHWNGUZc7ddvUWIcfCva/AMoqEW/3wnEllriMWBa0RHspCYnfCWJQYmA==",
1831 + "license": "MIT",
1832 + "dependencies": {
1833 + "@radix-ui/number": "1.1.1",
1834 + "@radix-ui/primitive": "1.1.2",
1835 + "@radix-ui/react-collection": "1.1.7",
1836 + "@radix-ui/react-compose-refs": "1.1.2",
1837 + "@radix-ui/react-context": "1.1.2",
1838 + "@radix-ui/react-direction": "1.1.1",
1839 + "@radix-ui/react-dismissable-layer": "1.1.10",
1840 + "@radix-ui/react-focus-guards": "1.1.2",
1841 + "@radix-ui/react-focus-scope": "1.1.7",
1842 + "@radix-ui/react-id": "1.1.1",
1843 + "@radix-ui/react-popper": "1.2.7",
1844 + "@radix-ui/react-portal": "1.1.9",
1845 + "@radix-ui/react-primitive": "2.1.3",
1846 + "@radix-ui/react-slot": "1.2.3",
1847 + "@radix-ui/react-use-callback-ref": "1.1.1",
1848 + "@radix-ui/react-use-controllable-state": "1.2.2",
1849 + "@radix-ui/react-use-layout-effect": "1.1.1",
1850 + "@radix-ui/react-use-previous": "1.1.1",
1851 + "@radix-ui/react-visually-hidden": "1.2.3",
1852 + "aria-hidden": "^1.2.4",
1853 + "react-remove-scroll": "^2.6.3"
1854 + },
1855 + "peerDependencies": {
1856 + "@types/react": "*",
1857 + "@types/react-dom": "*",
1858 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1859 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1860 + },
1861 + "peerDependenciesMeta": {
1862 + "@types/react": {
1863 + "optional": true
1864 + },
1865 + "@types/react-dom": {
1866 + "optional": true
1867 + }
1868 + }
1869 + },
1870 + "node_modules/@radix-ui/react-separator": {
1871 + "version": "1.1.7",
1872 + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.7.tgz",
1873 + "integrity": "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==",
1874 + "license": "MIT",
1875 + "dependencies": {
1876 + "@radix-ui/react-primitive": "2.1.3"
1877 + },
1878 + "peerDependencies": {
1879 + "@types/react": "*",
1880 + "@types/react-dom": "*",
1881 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1882 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1883 + },
1884 + "peerDependenciesMeta": {
1885 + "@types/react": {
1886 + "optional": true
1887 + },
1888 + "@types/react-dom": {
1889 + "optional": true
1890 + }
1891 + }
1892 + },
1893 + "node_modules/@radix-ui/react-slider": {
1894 + "version": "1.3.5",
1895 + "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.3.5.tgz",
1896 + "integrity": "sha512-rkfe2pU2NBAYfGaxa3Mqosi7VZEWX5CxKaanRv0vZd4Zhl9fvQrg0VM93dv3xGLGfrHuoTRF3JXH8nb9g+B3fw==",
1897 + "license": "MIT",
1898 + "dependencies": {
1899 + "@radix-ui/number": "1.1.1",
1900 + "@radix-ui/primitive": "1.1.2",
1901 + "@radix-ui/react-collection": "1.1.7",
1902 + "@radix-ui/react-compose-refs": "1.1.2",
1903 + "@radix-ui/react-context": "1.1.2",
1904 + "@radix-ui/react-direction": "1.1.1",
1905 + "@radix-ui/react-primitive": "2.1.3",
1906 + "@radix-ui/react-use-controllable-state": "1.2.2",
1907 + "@radix-ui/react-use-layout-effect": "1.1.1",
1908 + "@radix-ui/react-use-previous": "1.1.1",
1909 + "@radix-ui/react-use-size": "1.1.1"
1910 + },
1911 + "peerDependencies": {
1912 + "@types/react": "*",
1913 + "@types/react-dom": "*",
1914 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1915 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1916 + },
1917 + "peerDependenciesMeta": {
1918 + "@types/react": {
1919 + "optional": true
1920 + },
1921 + "@types/react-dom": {
1922 + "optional": true
1923 + }
1924 + }
1925 + },
1926 + "node_modules/@radix-ui/react-slot": {
1927 + "version": "1.2.3",
1928 + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
1929 + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
1930 + "license": "MIT",
1931 + "dependencies": {
1932 + "@radix-ui/react-compose-refs": "1.1.2"
1933 + },
1934 + "peerDependencies": {
1935 + "@types/react": "*",
1936 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1937 + },
1938 + "peerDependenciesMeta": {
1939 + "@types/react": {
1940 + "optional": true
1941 + }
1942 + }
1943 + },
1944 + "node_modules/@radix-ui/react-switch": {
1945 + "version": "1.2.5",
1946 + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.2.5.tgz",
1947 + "integrity": "sha512-5ijLkak6ZMylXsaImpZ8u4Rlf5grRmoc0p0QeX9VJtlrM4f5m3nCTX8tWga/zOA8PZYIR/t0p2Mnvd7InrJ6yQ==",
1948 + "license": "MIT",
1949 + "dependencies": {
1950 + "@radix-ui/primitive": "1.1.2",
1951 + "@radix-ui/react-compose-refs": "1.1.2",
1952 + "@radix-ui/react-context": "1.1.2",
1953 + "@radix-ui/react-primitive": "2.1.3",
1954 + "@radix-ui/react-use-controllable-state": "1.2.2",
1955 + "@radix-ui/react-use-previous": "1.1.1",
1956 + "@radix-ui/react-use-size": "1.1.1"
1957 + },
1958 + "peerDependencies": {
1959 + "@types/react": "*",
1960 + "@types/react-dom": "*",
1961 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1962 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1963 + },
1964 + "peerDependenciesMeta": {
1965 + "@types/react": {
1966 + "optional": true
1967 + },
1968 + "@types/react-dom": {
1969 + "optional": true
1970 + }
1971 + }
1972 + },
1973 + "node_modules/@radix-ui/react-tabs": {
1974 + "version": "1.1.12",
1975 + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.12.tgz",
1976 + "integrity": "sha512-GTVAlRVrQrSw3cEARM0nAx73ixrWDPNZAruETn3oHCNP6SbZ/hNxdxp+u7VkIEv3/sFoLq1PfcHrl7Pnp0CDpw==",
1977 + "license": "MIT",
1978 + "dependencies": {
1979 + "@radix-ui/primitive": "1.1.2",
1980 + "@radix-ui/react-context": "1.1.2",
1981 + "@radix-ui/react-direction": "1.1.1",
1982 + "@radix-ui/react-id": "1.1.1",
1983 + "@radix-ui/react-presence": "1.1.4",
1984 + "@radix-ui/react-primitive": "2.1.3",
1985 + "@radix-ui/react-roving-focus": "1.1.10",
1986 + "@radix-ui/react-use-controllable-state": "1.2.2"
1987 + },
1988 + "peerDependencies": {
1989 + "@types/react": "*",
1990 + "@types/react-dom": "*",
1991 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
1992 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
1993 + },
1994 + "peerDependenciesMeta": {
1995 + "@types/react": {
1996 + "optional": true
1997 + },
1998 + "@types/react-dom": {
1999 + "optional": true
2000 + }
2001 + }
2002 + },
2003 + "node_modules/@radix-ui/react-toast": {
2004 + "version": "1.2.14",
2005 + "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.14.tgz",
2006 + "integrity": "sha512-nAP5FBxBJGQ/YfUB+r+O6USFVkWq3gAInkxyEnmvEV5jtSbfDhfa4hwX8CraCnbjMLsE7XSf/K75l9xXY7joWg==",
2007 + "license": "MIT",
2008 + "dependencies": {
2009 + "@radix-ui/primitive": "1.1.2",
2010 + "@radix-ui/react-collection": "1.1.7",
2011 + "@radix-ui/react-compose-refs": "1.1.2",
2012 + "@radix-ui/react-context": "1.1.2",
2013 + "@radix-ui/react-dismissable-layer": "1.1.10",
2014 + "@radix-ui/react-portal": "1.1.9",
2015 + "@radix-ui/react-presence": "1.1.4",
2016 + "@radix-ui/react-primitive": "2.1.3",
2017 + "@radix-ui/react-use-callback-ref": "1.1.1",
2018 + "@radix-ui/react-use-controllable-state": "1.2.2",
2019 + "@radix-ui/react-use-layout-effect": "1.1.1",
2020 + "@radix-ui/react-visually-hidden": "1.2.3"
2021 + },
2022 + "peerDependencies": {
2023 + "@types/react": "*",
2024 + "@types/react-dom": "*",
2025 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
2026 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2027 + },
2028 + "peerDependenciesMeta": {
2029 + "@types/react": {
2030 + "optional": true
2031 + },
2032 + "@types/react-dom": {
2033 + "optional": true
2034 + }
2035 + }
2036 + },
2037 + "node_modules/@radix-ui/react-toggle": {
2038 + "version": "1.1.9",
2039 + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.9.tgz",
2040 + "integrity": "sha512-ZoFkBBz9zv9GWer7wIjvdRxmh2wyc2oKWw6C6CseWd6/yq1DK/l5lJ+wnsmFwJZbBYqr02mrf8A2q/CVCuM3ZA==",
2041 + "license": "MIT",
2042 + "dependencies": {
2043 + "@radix-ui/primitive": "1.1.2",
2044 + "@radix-ui/react-primitive": "2.1.3",
2045 + "@radix-ui/react-use-controllable-state": "1.2.2"
2046 + },
2047 + "peerDependencies": {
2048 + "@types/react": "*",
2049 + "@types/react-dom": "*",
2050 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
2051 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2052 + },
2053 + "peerDependenciesMeta": {
2054 + "@types/react": {
2055 + "optional": true
2056 + },
2057 + "@types/react-dom": {
2058 + "optional": true
2059 + }
2060 + }
2061 + },
2062 + "node_modules/@radix-ui/react-toggle-group": {
2063 + "version": "1.1.10",
2064 + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.10.tgz",
2065 + "integrity": "sha512-kiU694Km3WFLTC75DdqgM/3Jauf3rD9wxeS9XtyWFKsBUeZA337lC+6uUazT7I1DhanZ5gyD5Stf8uf2dbQxOQ==",
2066 + "license": "MIT",
2067 + "dependencies": {
2068 + "@radix-ui/primitive": "1.1.2",
2069 + "@radix-ui/react-context": "1.1.2",
2070 + "@radix-ui/react-direction": "1.1.1",
2071 + "@radix-ui/react-primitive": "2.1.3",
2072 + "@radix-ui/react-roving-focus": "1.1.10",
2073 + "@radix-ui/react-toggle": "1.1.9",
2074 + "@radix-ui/react-use-controllable-state": "1.2.2"
2075 + },
2076 + "peerDependencies": {
2077 + "@types/react": "*",
2078 + "@types/react-dom": "*",
2079 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
2080 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2081 + },
2082 + "peerDependenciesMeta": {
2083 + "@types/react": {
2084 + "optional": true
2085 + },
2086 + "@types/react-dom": {
2087 + "optional": true
2088 + }
2089 + }
2090 + },
2091 + "node_modules/@radix-ui/react-tooltip": {
2092 + "version": "1.2.7",
2093 + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.7.tgz",
2094 + "integrity": "sha512-Ap+fNYwKTYJ9pzqW+Xe2HtMRbQ/EeWkj2qykZ6SuEV4iS/o1bZI5ssJbk4D2r8XuDuOBVz/tIx2JObtuqU+5Zw==",
2095 + "license": "MIT",
2096 + "dependencies": {
2097 + "@radix-ui/primitive": "1.1.2",
2098 + "@radix-ui/react-compose-refs": "1.1.2",
2099 + "@radix-ui/react-context": "1.1.2",
2100 + "@radix-ui/react-dismissable-layer": "1.1.10",
2101 + "@radix-ui/react-id": "1.1.1",
2102 + "@radix-ui/react-popper": "1.2.7",
2103 + "@radix-ui/react-portal": "1.1.9",
2104 + "@radix-ui/react-presence": "1.1.4",
2105 + "@radix-ui/react-primitive": "2.1.3",
2106 + "@radix-ui/react-slot": "1.2.3",
2107 + "@radix-ui/react-use-controllable-state": "1.2.2",
2108 + "@radix-ui/react-visually-hidden": "1.2.3"
2109 + },
2110 + "peerDependencies": {
2111 + "@types/react": "*",
2112 + "@types/react-dom": "*",
2113 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
2114 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2115 + },
2116 + "peerDependenciesMeta": {
2117 + "@types/react": {
2118 + "optional": true
2119 + },
2120 + "@types/react-dom": {
2121 + "optional": true
2122 + }
2123 + }
2124 + },
2125 + "node_modules/@radix-ui/react-use-callback-ref": {
2126 + "version": "1.1.1",
2127 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz",
2128 + "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==",
2129 + "license": "MIT",
2130 + "peerDependencies": {
2131 + "@types/react": "*",
2132 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2133 + },
2134 + "peerDependenciesMeta": {
2135 + "@types/react": {
2136 + "optional": true
2137 + }
2138 + }
2139 + },
2140 + "node_modules/@radix-ui/react-use-controllable-state": {
2141 + "version": "1.2.2",
2142 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz",
2143 + "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==",
2144 + "license": "MIT",
2145 + "dependencies": {
2146 + "@radix-ui/react-use-effect-event": "0.0.2",
2147 + "@radix-ui/react-use-layout-effect": "1.1.1"
2148 + },
2149 + "peerDependencies": {
2150 + "@types/react": "*",
2151 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2152 + },
2153 + "peerDependenciesMeta": {
2154 + "@types/react": {
2155 + "optional": true
2156 + }
2157 + }
2158 + },
2159 + "node_modules/@radix-ui/react-use-effect-event": {
2160 + "version": "0.0.2",
2161 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz",
2162 + "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==",
2163 + "license": "MIT",
2164 + "dependencies": {
2165 + "@radix-ui/react-use-layout-effect": "1.1.1"
2166 + },
2167 + "peerDependencies": {
2168 + "@types/react": "*",
2169 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2170 + },
2171 + "peerDependenciesMeta": {
2172 + "@types/react": {
2173 + "optional": true
2174 + }
2175 + }
2176 + },
2177 + "node_modules/@radix-ui/react-use-escape-keydown": {
2178 + "version": "1.1.1",
2179 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz",
2180 + "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==",
2181 + "license": "MIT",
2182 + "dependencies": {
2183 + "@radix-ui/react-use-callback-ref": "1.1.1"
2184 + },
2185 + "peerDependencies": {
2186 + "@types/react": "*",
2187 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2188 + },
2189 + "peerDependenciesMeta": {
2190 + "@types/react": {
2191 + "optional": true
2192 + }
2193 + }
2194 + },
2195 + "node_modules/@radix-ui/react-use-is-hydrated": {
2196 + "version": "0.1.0",
2197 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.0.tgz",
2198 + "integrity": "sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==",
2199 + "license": "MIT",
2200 + "dependencies": {
2201 + "use-sync-external-store": "^1.5.0"
2202 + },
2203 + "peerDependencies": {
2204 + "@types/react": "*",
2205 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2206 + },
2207 + "peerDependenciesMeta": {
2208 + "@types/react": {
2209 + "optional": true
2210 + }
2211 + }
2212 + },
2213 + "node_modules/@radix-ui/react-use-layout-effect": {
2214 + "version": "1.1.1",
2215 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz",
2216 + "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==",
2217 + "license": "MIT",
2218 + "peerDependencies": {
2219 + "@types/react": "*",
2220 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2221 + },
2222 + "peerDependenciesMeta": {
2223 + "@types/react": {
2224 + "optional": true
2225 + }
2226 + }
2227 + },
2228 + "node_modules/@radix-ui/react-use-previous": {
2229 + "version": "1.1.1",
2230 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz",
2231 + "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==",
2232 + "license": "MIT",
2233 + "peerDependencies": {
2234 + "@types/react": "*",
2235 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2236 + },
2237 + "peerDependenciesMeta": {
2238 + "@types/react": {
2239 + "optional": true
2240 + }
2241 + }
2242 + },
2243 + "node_modules/@radix-ui/react-use-rect": {
2244 + "version": "1.1.1",
2245 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz",
2246 + "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==",
2247 + "license": "MIT",
2248 + "dependencies": {
2249 + "@radix-ui/rect": "1.1.1"
2250 + },
2251 + "peerDependencies": {
2252 + "@types/react": "*",
2253 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2254 + },
2255 + "peerDependenciesMeta": {
2256 + "@types/react": {
2257 + "optional": true
2258 + }
2259 + }
2260 + },
2261 + "node_modules/@radix-ui/react-use-size": {
2262 + "version": "1.1.1",
2263 + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz",
2264 + "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==",
2265 + "license": "MIT",
2266 + "dependencies": {
2267 + "@radix-ui/react-use-layout-effect": "1.1.1"
2268 + },
2269 + "peerDependencies": {
2270 + "@types/react": "*",
2271 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2272 + },
2273 + "peerDependenciesMeta": {
2274 + "@types/react": {
2275 + "optional": true
2276 + }
2277 + }
2278 + },
2279 + "node_modules/@radix-ui/react-visually-hidden": {
2280 + "version": "1.2.3",
2281 + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz",
2282 + "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==",
2283 + "license": "MIT",
2284 + "dependencies": {
2285 + "@radix-ui/react-primitive": "2.1.3"
2286 + },
2287 + "peerDependencies": {
2288 + "@types/react": "*",
2289 + "@types/react-dom": "*",
2290 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
2291 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
2292 + },
2293 + "peerDependenciesMeta": {
2294 + "@types/react": {
2295 + "optional": true
2296 + },
2297 + "@types/react-dom": {
2298 + "optional": true
2299 + }
2300 + }
2301 + },
2302 + "node_modules/@radix-ui/rect": {
2303 + "version": "1.1.1",
2304 + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz",
2305 + "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==",
2306 + "license": "MIT"
2307 + },
2308 + "node_modules/@remix-run/router": {
2309 + "version": "1.23.0",
2310 + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.0.tgz",
2311 + "integrity": "sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==",
2312 + "license": "MIT",
2313 + "engines": {
2314 + "node": ">=14.0.0"
2315 + }
2316 + },
2317 + "node_modules/@rolldown/pluginutils": {
2318 + "version": "1.0.0-beta.27",
2319 + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz",
2320 + "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==",
2321 + "dev": true,
2322 + "license": "MIT"
2323 + },
2324 + "node_modules/@rollup/rollup-android-arm-eabi": {
2325 + "version": "4.24.0",
2326 + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz",
2327 + "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==",
2328 + "cpu": [
2329 + "arm"
2330 + ],
2331 + "dev": true,
2332 + "license": "MIT",
2333 + "optional": true,
2334 + "os": [
2335 + "android"
2336 + ]
2337 + },
2338 + "node_modules/@rollup/rollup-android-arm64": {
2339 + "version": "4.24.0",
2340 + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz",
2341 + "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==",
2342 + "cpu": [
2343 + "arm64"
2344 + ],
2345 + "dev": true,
2346 + "license": "MIT",
2347 + "optional": true,
2348 + "os": [
2349 + "android"
2350 + ]
2351 + },
2352 + "node_modules/@rollup/rollup-darwin-arm64": {
2353 + "version": "4.24.0",
2354 + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz",
2355 + "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==",
2356 + "cpu": [
2357 + "arm64"
2358 + ],
2359 + "dev": true,
2360 + "license": "MIT",
2361 + "optional": true,
2362 + "os": [
2363 + "darwin"
2364 + ]
2365 + },
2366 + "node_modules/@rollup/rollup-darwin-x64": {
2367 + "version": "4.24.0",
2368 + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz",
2369 + "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==",
2370 + "cpu": [
2371 + "x64"
2372 + ],
2373 + "dev": true,
2374 + "license": "MIT",
2375 + "optional": true,
2376 + "os": [
2377 + "darwin"
2378 + ]
2379 + },
2380 + "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
2381 + "version": "4.24.0",
2382 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz",
2383 + "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==",
2384 + "cpu": [
2385 + "arm"
2386 + ],
2387 + "dev": true,
2388 + "license": "MIT",
2389 + "optional": true,
2390 + "os": [
2391 + "linux"
2392 + ]
2393 + },
2394 + "node_modules/@rollup/rollup-linux-arm-musleabihf": {
2395 + "version": "4.24.0",
2396 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz",
2397 + "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==",
2398 + "cpu": [
2399 + "arm"
2400 + ],
2401 + "dev": true,
2402 + "license": "MIT",
2403 + "optional": true,
2404 + "os": [
2405 + "linux"
2406 + ]
2407 + },
2408 + "node_modules/@rollup/rollup-linux-arm64-gnu": {
2409 + "version": "4.24.0",
2410 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz",
2411 + "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==",
2412 + "cpu": [
2413 + "arm64"
2414 + ],
2415 + "dev": true,
2416 + "license": "MIT",
2417 + "optional": true,
2418 + "os": [
2419 + "linux"
2420 + ]
2421 + },
2422 + "node_modules/@rollup/rollup-linux-arm64-musl": {
2423 + "version": "4.24.0",
2424 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz",
2425 + "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==",
2426 + "cpu": [
2427 + "arm64"
2428 + ],
2429 + "dev": true,
2430 + "license": "MIT",
2431 + "optional": true,
2432 + "os": [
2433 + "linux"
2434 + ]
2435 + },
2436 + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
2437 + "version": "4.24.0",
2438 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz",
2439 + "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==",
2440 + "cpu": [
2441 + "ppc64"
2442 + ],
2443 + "dev": true,
2444 + "license": "MIT",
2445 + "optional": true,
2446 + "os": [
2447 + "linux"
2448 + ]
2449 + },
2450 + "node_modules/@rollup/rollup-linux-riscv64-gnu": {
2451 + "version": "4.24.0",
2452 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz",
2453 + "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==",
2454 + "cpu": [
2455 + "riscv64"
2456 + ],
2457 + "dev": true,
2458 + "license": "MIT",
2459 + "optional": true,
2460 + "os": [
2461 + "linux"
2462 + ]
2463 + },
2464 + "node_modules/@rollup/rollup-linux-s390x-gnu": {
2465 + "version": "4.24.0",
2466 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz",
2467 + "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==",
2468 + "cpu": [
2469 + "s390x"
2470 + ],
2471 + "dev": true,
2472 + "license": "MIT",
2473 + "optional": true,
2474 + "os": [
2475 + "linux"
2476 + ]
2477 + },
2478 + "node_modules/@rollup/rollup-linux-x64-gnu": {
2479 + "version": "4.24.0",
2480 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz",
2481 + "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==",
2482 + "cpu": [
2483 + "x64"
2484 + ],
2485 + "dev": true,
2486 + "license": "MIT",
2487 + "optional": true,
2488 + "os": [
2489 + "linux"
2490 + ]
2491 + },
2492 + "node_modules/@rollup/rollup-linux-x64-musl": {
2493 + "version": "4.24.0",
2494 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz",
2495 + "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==",
2496 + "cpu": [
2497 + "x64"
2498 + ],
2499 + "dev": true,
2500 + "license": "MIT",
2501 + "optional": true,
2502 + "os": [
2503 + "linux"
2504 + ]
2505 + },
2506 + "node_modules/@rollup/rollup-win32-arm64-msvc": {
2507 + "version": "4.24.0",
2508 + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz",
2509 + "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==",
2510 + "cpu": [
2511 + "arm64"
2512 + ],
2513 + "dev": true,
2514 + "license": "MIT",
2515 + "optional": true,
2516 + "os": [
2517 + "win32"
2518 + ]
2519 + },
2520 + "node_modules/@rollup/rollup-win32-ia32-msvc": {
2521 + "version": "4.24.0",
2522 + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz",
2523 + "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==",
2524 + "cpu": [
2525 + "ia32"
2526 + ],
2527 + "dev": true,
2528 + "license": "MIT",
2529 + "optional": true,
2530 + "os": [
2531 + "win32"
2532 + ]
2533 + },
2534 + "node_modules/@rollup/rollup-win32-x64-msvc": {
2535 + "version": "4.24.0",
2536 + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz",
2537 + "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==",
2538 + "cpu": [
2539 + "x64"
2540 + ],
2541 + "dev": true,
2542 + "license": "MIT",
2543 + "optional": true,
2544 + "os": [
2545 + "win32"
2546 + ]
2547 + },
2548 + "node_modules/@swc/core": {
2549 + "version": "1.13.2",
2550 + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.13.2.tgz",
2551 + "integrity": "sha512-YWqn+0IKXDhqVLKoac4v2tV6hJqB/wOh8/Br8zjqeqBkKa77Qb0Kw2i7LOFzjFNZbZaPH6AlMGlBwNrxaauaAg==",
2552 + "dev": true,
2553 + "hasInstallScript": true,
2554 + "license": "Apache-2.0",
2555 + "dependencies": {
2556 + "@swc/counter": "^0.1.3",
2557 + "@swc/types": "^0.1.23"
2558 + },
2559 + "engines": {
2560 + "node": ">=10"
2561 + },
2562 + "funding": {
2563 + "type": "opencollective",
2564 + "url": "https://opencollective.com/swc"
2565 + },
2566 + "optionalDependencies": {
2567 + "@swc/core-darwin-arm64": "1.13.2",
2568 + "@swc/core-darwin-x64": "1.13.2",
2569 + "@swc/core-linux-arm-gnueabihf": "1.13.2",
2570 + "@swc/core-linux-arm64-gnu": "1.13.2",
2571 + "@swc/core-linux-arm64-musl": "1.13.2",
2572 + "@swc/core-linux-x64-gnu": "1.13.2",
2573 + "@swc/core-linux-x64-musl": "1.13.2",
2574 + "@swc/core-win32-arm64-msvc": "1.13.2",
2575 + "@swc/core-win32-ia32-msvc": "1.13.2",
2576 + "@swc/core-win32-x64-msvc": "1.13.2"
2577 + },
2578 + "peerDependencies": {
2579 + "@swc/helpers": ">=0.5.17"
2580 + },
2581 + "peerDependenciesMeta": {
2582 + "@swc/helpers": {
2583 + "optional": true
2584 + }
2585 + }
2586 + },
2587 + "node_modules/@swc/core-darwin-arm64": {
2588 + "version": "1.13.2",
2589 + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.13.2.tgz",
2590 + "integrity": "sha512-44p7ivuLSGFJ15Vly4ivLJjg3ARo4879LtEBAabcHhSZygpmkP8eyjyWxrH3OxkY1eRZSIJe8yRZPFw4kPXFPw==",
2591 + "cpu": [
2592 + "arm64"
2593 + ],
2594 + "dev": true,
2595 + "license": "Apache-2.0 AND MIT",
2596 + "optional": true,
2597 + "os": [
2598 + "darwin"
2599 + ],
2600 + "engines": {
2601 + "node": ">=10"
2602 + }
2603 + },
2604 + "node_modules/@swc/core-darwin-x64": {
2605 + "version": "1.13.2",
2606 + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.13.2.tgz",
2607 + "integrity": "sha512-Lb9EZi7X2XDAVmuUlBm2UvVAgSCbD3qKqDCxSI4jEOddzVOpNCnyZ/xEampdngUIyDDhhJLYU9duC+Mcsv5Y+A==",
2608 + "cpu": [
2609 + "x64"
2610 + ],
2611 + "dev": true,
2612 + "license": "Apache-2.0 AND MIT",
2613 + "optional": true,
2614 + "os": [
2615 + "darwin"
2616 + ],
2617 + "engines": {
2618 + "node": ">=10"
2619 + }
2620 + },
2621 + "node_modules/@swc/core-linux-arm-gnueabihf": {
2622 + "version": "1.13.2",
2623 + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.13.2.tgz",
2624 + "integrity": "sha512-9TDe/92ee1x57x+0OqL1huG4BeljVx0nWW4QOOxp8CCK67Rpc/HHl2wciJ0Kl9Dxf2NvpNtkPvqj9+BUmM9WVA==",
2625 + "cpu": [
2626 + "arm"
2627 + ],
2628 + "dev": true,
2629 + "license": "Apache-2.0",
2630 + "optional": true,
2631 + "os": [
2632 + "linux"
2633 + ],
2634 + "engines": {
2635 + "node": ">=10"
2636 + }
2637 + },
2638 + "node_modules/@swc/core-linux-arm64-gnu": {
2639 + "version": "1.13.2",
2640 + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.13.2.tgz",
2641 + "integrity": "sha512-KJUSl56DBk7AWMAIEcU83zl5mg3vlQYhLELhjwRFkGFMvghQvdqQ3zFOYa4TexKA7noBZa3C8fb24rI5sw9Exg==",
2642 + "cpu": [
2643 + "arm64"
2644 + ],
2645 + "dev": true,
2646 + "license": "Apache-2.0 AND MIT",
2647 + "optional": true,
2648 + "os": [
2649 + "linux"
2650 + ],
2651 + "engines": {
2652 + "node": ">=10"
2653 + }
2654 + },
2655 + "node_modules/@swc/core-linux-arm64-musl": {
2656 + "version": "1.13.2",
2657 + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.13.2.tgz",
2658 + "integrity": "sha512-teU27iG1oyWpNh9CzcGQ48ClDRt/RCem7mYO7ehd2FY102UeTws2+OzLESS1TS1tEZipq/5xwx3FzbVgiolCiQ==",
2659 + "cpu": [
2660 + "arm64"
2661 + ],
2662 + "dev": true,
2663 + "license": "Apache-2.0 AND MIT",
2664 + "optional": true,
2665 + "os": [
2666 + "linux"
2667 + ],
2668 + "engines": {
2669 + "node": ">=10"
2670 + }
2671 + },
2672 + "node_modules/@swc/core-linux-x64-gnu": {
2673 + "version": "1.13.2",
2674 + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.13.2.tgz",
2675 + "integrity": "sha512-dRPsyPyqpLD0HMRCRpYALIh4kdOir8pPg4AhNQZLehKowigRd30RcLXGNVZcc31Ua8CiPI4QSgjOIxK+EQe4LQ==",
2676 + "cpu": [
2677 + "x64"
2678 + ],
2679 + "dev": true,
2680 + "license": "Apache-2.0 AND MIT",
2681 + "optional": true,
2682 + "os": [
2683 + "linux"
2684 + ],
2685 + "engines": {
2686 + "node": ">=10"
2687 + }
2688 + },
2689 + "node_modules/@swc/core-linux-x64-musl": {
2690 + "version": "1.13.2",
2691 + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.13.2.tgz",
2692 + "integrity": "sha512-CCxETW+KkYEQDqz1SYC15YIWYheqFC+PJVOW76Maa/8yu8Biw+HTAcblKf2isrlUtK8RvrQN94v3UXkC2NzCEw==",
2693 + "cpu": [
2694 + "x64"
2695 + ],
2696 + "dev": true,
2697 + "license": "Apache-2.0 AND MIT",
2698 + "optional": true,
2699 + "os": [
2700 + "linux"
2701 + ],
2702 + "engines": {
2703 + "node": ">=10"
2704 + }
2705 + },
2706 + "node_modules/@swc/core-win32-arm64-msvc": {
2707 + "version": "1.13.2",
2708 + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.13.2.tgz",
2709 + "integrity": "sha512-Wv/QTA6PjyRLlmKcN6AmSI4jwSMRl0VTLGs57PHTqYRwwfwd7y4s2fIPJVBNbAlXd795dOEP6d/bGSQSyhOX3A==",
2710 + "cpu": [
2711 + "arm64"
2712 + ],
2713 + "dev": true,
2714 + "license": "Apache-2.0 AND MIT",
2715 + "optional": true,
2716 + "os": [
2717 + "win32"
2718 + ],
2719 + "engines": {
2720 + "node": ">=10"
2721 + }
2722 + },
2723 + "node_modules/@swc/core-win32-ia32-msvc": {
2724 + "version": "1.13.2",
2725 + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.13.2.tgz",
2726 + "integrity": "sha512-PuCdtNynEkUNbUXX/wsyUC+t4mamIU5y00lT5vJcAvco3/r16Iaxl5UCzhXYaWZSNVZMzPp9qN8NlSL8M5pPxw==",
2727 + "cpu": [
2728 + "ia32"
2729 + ],
2730 + "dev": true,
2731 + "license": "Apache-2.0 AND MIT",
2732 + "optional": true,
2733 + "os": [
2734 + "win32"
2735 + ],
2736 + "engines": {
2737 + "node": ">=10"
2738 + }
2739 + },
2740 + "node_modules/@swc/core-win32-x64-msvc": {
2741 + "version": "1.13.2",
2742 + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.13.2.tgz",
2743 + "integrity": "sha512-qlmMkFZJus8cYuBURx1a3YAG2G7IW44i+FEYV5/32ylKkzGNAr9tDJSA53XNnNXkAB5EXSPsOz7bn5C3JlEtdQ==",
2744 + "cpu": [
2745 + "x64"
2746 + ],
2747 + "dev": true,
2748 + "license": "Apache-2.0 AND MIT",
2749 + "optional": true,
2750 + "os": [
2751 + "win32"
2752 + ],
2753 + "engines": {
2754 + "node": ">=10"
2755 + }
2756 + },
2757 + "node_modules/@swc/counter": {
2758 + "version": "0.1.3",
2759 + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
2760 + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
2761 + "dev": true,
2762 + "license": "Apache-2.0"
2763 + },
2764 + "node_modules/@swc/types": {
2765 + "version": "0.1.23",
2766 + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.23.tgz",
2767 + "integrity": "sha512-u1iIVZV9Q0jxY+yM2vw/hZGDNudsN85bBpTqzAQ9rzkxW9D+e3aEM4Han+ow518gSewkXgjmEK0BD79ZcNVgPw==",
2768 + "dev": true,
2769 + "license": "Apache-2.0",
2770 + "dependencies": {
2771 + "@swc/counter": "^0.1.3"
2772 + }
2773 + },
2774 + "node_modules/@tailwindcss/typography": {
2775 + "version": "0.5.16",
2776 + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.16.tgz",
2777 + "integrity": "sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==",
2778 + "dev": true,
2779 + "license": "MIT",
2780 + "dependencies": {
2781 + "lodash.castarray": "^4.4.0",
2782 + "lodash.isplainobject": "^4.0.6",
2783 + "lodash.merge": "^4.6.2",
2784 + "postcss-selector-parser": "6.0.10"
2785 + },
2786 + "peerDependencies": {
2787 + "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1"
2788 + }
2789 + },
2790 + "node_modules/@tailwindcss/typography/node_modules/postcss-selector-parser": {
2791 + "version": "6.0.10",
2792 + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
2793 + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
2794 + "dev": true,
2795 + "dependencies": {
2796 + "cssesc": "^3.0.0",
2797 + "util-deprecate": "^1.0.2"
2798 + },
2799 + "engines": {
2800 + "node": ">=4"
2801 + }
2802 + },
2803 + "node_modules/@tanstack/query-core": {
2804 + "version": "5.83.0",
2805 + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.83.0.tgz",
2806 + "integrity": "sha512-0M8dA+amXUkyz5cVUm/B+zSk3xkQAcuXuz5/Q/LveT4ots2rBpPTZOzd7yJa2Utsf8D2Upl5KyjhHRY+9lB/XA==",
2807 + "license": "MIT",
2808 + "funding": {
2809 + "type": "github",
2810 + "url": "https://github.com/sponsors/tannerlinsley"
2811 + }
2812 + },
2813 + "node_modules/@tanstack/react-query": {
2814 + "version": "5.83.0",
2815 + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.83.0.tgz",
2816 + "integrity": "sha512-/XGYhZ3foc5H0VM2jLSD/NyBRIOK4q9kfeml4+0x2DlL6xVuAcVEW+hTlTapAmejObg0i3eNqhkr2dT+eciwoQ==",
2817 + "license": "MIT",
2818 + "dependencies": {
2819 + "@tanstack/query-core": "5.83.0"
2820 + },
2821 + "funding": {
2822 + "type": "github",
2823 + "url": "https://github.com/sponsors/tannerlinsley"
2824 + },
2825 + "peerDependencies": {
2826 + "react": "^18 || ^19"
2827 + }
2828 + },
2829 + "node_modules/@types/d3-array": {
2830 + "version": "3.2.1",
2831 + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz",
2832 + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==",
2833 + "license": "MIT"
2834 + },
2835 + "node_modules/@types/d3-color": {
2836 + "version": "3.1.3",
2837 + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz",
2838 + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==",
2839 + "license": "MIT"
2840 + },
2841 + "node_modules/@types/d3-ease": {
2842 + "version": "3.0.2",
2843 + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz",
2844 + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==",
2845 + "license": "MIT"
2846 + },
2847 + "node_modules/@types/d3-interpolate": {
2848 + "version": "3.0.4",
2849 + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz",
2850 + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==",
2851 + "license": "MIT",
2852 + "dependencies": {
2853 + "@types/d3-color": "*"
2854 + }
2855 + },
2856 + "node_modules/@types/d3-path": {
2857 + "version": "3.1.0",
2858 + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz",
2859 + "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==",
2860 + "license": "MIT"
2861 + },
2862 + "node_modules/@types/d3-scale": {
2863 + "version": "4.0.8",
2864 + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz",
2865 + "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==",
2866 + "license": "MIT",
2867 + "dependencies": {
2868 + "@types/d3-time": "*"
2869 + }
2870 + },
2871 + "node_modules/@types/d3-shape": {
2872 + "version": "3.1.6",
2873 + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz",
2874 + "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==",
2875 + "license": "MIT",
2876 + "dependencies": {
2877 + "@types/d3-path": "*"
2878 + }
2879 + },
2880 + "node_modules/@types/d3-time": {
2881 + "version": "3.0.3",
2882 + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz",
2883 + "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==",
2884 + "license": "MIT"
2885 + },
2886 + "node_modules/@types/d3-timer": {
2887 + "version": "3.0.2",
2888 + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz",
2889 + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==",
2890 + "license": "MIT"
2891 + },
2892 + "node_modules/@types/estree": {
2893 + "version": "1.0.6",
2894 + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
2895 + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
2896 + "dev": true,
2897 + "license": "MIT"
2898 + },
2899 + "node_modules/@types/json-schema": {
2900 + "version": "7.0.15",
2901 + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
2902 + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
2903 + "dev": true,
2904 + "license": "MIT"
2905 + },
2906 + "node_modules/@types/node": {
2907 + "version": "22.16.5",
2908 + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.16.5.tgz",
2909 + "integrity": "sha512-bJFoMATwIGaxxx8VJPeM8TonI8t579oRvgAuT8zFugJsJZgzqv0Fu8Mhp68iecjzG7cnN3mO2dJQ5uUM2EFrgQ==",
2910 + "dev": true,
2911 + "license": "MIT",
2912 + "dependencies": {
2913 + "undici-types": "~6.21.0"
2914 + }
2915 + },
2916 + "node_modules/@types/prop-types": {
2917 + "version": "15.7.13",
2918 + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz",
2919 + "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==",
2920 + "devOptional": true,
2921 + "license": "MIT"
2922 + },
2923 + "node_modules/@types/react": {
2924 + "version": "18.3.23",
2925 + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.23.tgz",
2926 + "integrity": "sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==",
2927 + "devOptional": true,
2928 + "license": "MIT",
2929 + "dependencies": {
2930 + "@types/prop-types": "*",
2931 + "csstype": "^3.0.2"
2932 + }
2933 + },
2934 + "node_modules/@types/react-dom": {
2935 + "version": "18.3.7",
2936 + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz",
2937 + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==",
2938 + "devOptional": true,
2939 + "license": "MIT",
2940 + "peerDependencies": {
2941 + "@types/react": "^18.0.0"
2942 + }
2943 + },
2944 + "node_modules/@typescript-eslint/eslint-plugin": {
2945 + "version": "8.38.0",
2946 + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.38.0.tgz",
2947 + "integrity": "sha512-CPoznzpuAnIOl4nhj4tRr4gIPj5AfKgkiJmGQDaq+fQnRJTYlcBjbX3wbciGmpoPf8DREufuPRe1tNMZnGdanA==",
2948 + "dev": true,
2949 + "license": "MIT",
2950 + "dependencies": {
2951 + "@eslint-community/regexpp": "^4.10.0",
2952 + "@typescript-eslint/scope-manager": "8.38.0",
2953 + "@typescript-eslint/type-utils": "8.38.0",
2954 + "@typescript-eslint/utils": "8.38.0",
2955 + "@typescript-eslint/visitor-keys": "8.38.0",
2956 + "graphemer": "^1.4.0",
2957 + "ignore": "^7.0.0",
2958 + "natural-compare": "^1.4.0",
2959 + "ts-api-utils": "^2.1.0"
2960 + },
2961 + "engines": {
2962 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
2963 + },
2964 + "funding": {
2965 + "type": "opencollective",
2966 + "url": "https://opencollective.com/typescript-eslint"
2967 + },
2968 + "peerDependencies": {
2969 + "@typescript-eslint/parser": "^8.38.0",
2970 + "eslint": "^8.57.0 || ^9.0.0",
2971 + "typescript": ">=4.8.4 <5.9.0"
2972 + }
2973 + },
2974 + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
2975 + "version": "7.0.5",
2976 + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
2977 + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
2978 + "dev": true,
2979 + "license": "MIT",
2980 + "engines": {
2981 + "node": ">= 4"
2982 + }
2983 + },
2984 + "node_modules/@typescript-eslint/parser": {
2985 + "version": "8.38.0",
2986 + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.38.0.tgz",
2987 + "integrity": "sha512-Zhy8HCvBUEfBECzIl1PKqF4p11+d0aUJS1GeUiuqK9WmOug8YCmC4h4bjyBvMyAMI9sbRczmrYL5lKg/YMbrcQ==",
2988 + "dev": true,
2989 + "license": "MIT",
2990 + "dependencies": {
2991 + "@typescript-eslint/scope-manager": "8.38.0",
2992 + "@typescript-eslint/types": "8.38.0",
2993 + "@typescript-eslint/typescript-estree": "8.38.0",
2994 + "@typescript-eslint/visitor-keys": "8.38.0",
2995 + "debug": "^4.3.4"
2996 + },
2997 + "engines": {
2998 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
2999 + },
3000 + "funding": {
3001 + "type": "opencollective",
3002 + "url": "https://opencollective.com/typescript-eslint"
3003 + },
3004 + "peerDependencies": {
3005 + "eslint": "^8.57.0 || ^9.0.0",
3006 + "typescript": ">=4.8.4 <5.9.0"
3007 + }
3008 + },
3009 + "node_modules/@typescript-eslint/project-service": {
3010 + "version": "8.38.0",
3011 + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.38.0.tgz",
3012 + "integrity": "sha512-dbK7Jvqcb8c9QfH01YB6pORpqX1mn5gDZc9n63Ak/+jD67oWXn3Gs0M6vddAN+eDXBCS5EmNWzbSxsn9SzFWWg==",
3013 + "dev": true,
3014 + "license": "MIT",
3015 + "dependencies": {
3016 + "@typescript-eslint/tsconfig-utils": "^8.38.0",
3017 + "@typescript-eslint/types": "^8.38.0",
3018 + "debug": "^4.3.4"
3019 + },
3020 + "engines": {
3021 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
3022 + },
3023 + "funding": {
3024 + "type": "opencollective",
3025 + "url": "https://opencollective.com/typescript-eslint"
3026 + },
3027 + "peerDependencies": {
3028 + "typescript": ">=4.8.4 <5.9.0"
3029 + }
3030 + },
3031 + "node_modules/@typescript-eslint/scope-manager": {
3032 + "version": "8.38.0",
3033 + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.38.0.tgz",
3034 + "integrity": "sha512-WJw3AVlFFcdT9Ri1xs/lg8LwDqgekWXWhH3iAF+1ZM+QPd7oxQ6jvtW/JPwzAScxitILUIFs0/AnQ/UWHzbATQ==",
3035 + "dev": true,
3036 + "license": "MIT",
3037 + "dependencies": {
3038 + "@typescript-eslint/types": "8.38.0",
3039 + "@typescript-eslint/visitor-keys": "8.38.0"
3040 + },
3041 + "engines": {
3042 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
3043 + },
3044 + "funding": {
3045 + "type": "opencollective",
3046 + "url": "https://opencollective.com/typescript-eslint"
3047 + }
3048 + },
3049 + "node_modules/@typescript-eslint/tsconfig-utils": {
3050 + "version": "8.38.0",
3051 + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.38.0.tgz",
3052 + "integrity": "sha512-Lum9RtSE3EroKk/bYns+sPOodqb2Fv50XOl/gMviMKNvanETUuUcC9ObRbzrJ4VSd2JalPqgSAavwrPiPvnAiQ==",
3053 + "dev": true,
3054 + "license": "MIT",
3055 + "engines": {
3056 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
3057 + },
3058 + "funding": {
3059 + "type": "opencollective",
3060 + "url": "https://opencollective.com/typescript-eslint"
3061 + },
3062 + "peerDependencies": {
3063 + "typescript": ">=4.8.4 <5.9.0"
3064 + }
3065 + },
3066 + "node_modules/@typescript-eslint/type-utils": {
3067 + "version": "8.38.0",
3068 + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.38.0.tgz",
3069 + "integrity": "sha512-c7jAvGEZVf0ao2z+nnz8BUaHZD09Agbh+DY7qvBQqLiz8uJzRgVPj5YvOh8I8uEiH8oIUGIfHzMwUcGVco/SJg==",
3070 + "dev": true,
3071 + "license": "MIT",
3072 + "dependencies": {
3073 + "@typescript-eslint/types": "8.38.0",
3074 + "@typescript-eslint/typescript-estree": "8.38.0",
3075 + "@typescript-eslint/utils": "8.38.0",
3076 + "debug": "^4.3.4",
3077 + "ts-api-utils": "^2.1.0"
3078 + },
3079 + "engines": {
3080 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
3081 + },
3082 + "funding": {
3083 + "type": "opencollective",
3084 + "url": "https://opencollective.com/typescript-eslint"
3085 + },
3086 + "peerDependencies": {
3087 + "eslint": "^8.57.0 || ^9.0.0",
3088 + "typescript": ">=4.8.4 <5.9.0"
3089 + }
3090 + },
3091 + "node_modules/@typescript-eslint/types": {
3092 + "version": "8.38.0",
3093 + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.38.0.tgz",
3094 + "integrity": "sha512-wzkUfX3plUqij4YwWaJyqhiPE5UCRVlFpKn1oCRn2O1bJ592XxWJj8ROQ3JD5MYXLORW84063z3tZTb/cs4Tyw==",
3095 + "dev": true,
3096 + "license": "MIT",
3097 + "engines": {
3098 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
3099 + },
3100 + "funding": {
3101 + "type": "opencollective",
3102 + "url": "https://opencollective.com/typescript-eslint"
3103 + }
3104 + },
3105 + "node_modules/@typescript-eslint/typescript-estree": {
3106 + "version": "8.38.0",
3107 + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.38.0.tgz",
3108 + "integrity": "sha512-fooELKcAKzxux6fA6pxOflpNS0jc+nOQEEOipXFNjSlBS6fqrJOVY/whSn70SScHrcJ2LDsxWrneFoWYSVfqhQ==",
3109 + "dev": true,
3110 + "license": "MIT",
3111 + "dependencies": {
3112 + "@typescript-eslint/project-service": "8.38.0",
3113 + "@typescript-eslint/tsconfig-utils": "8.38.0",
3114 + "@typescript-eslint/types": "8.38.0",
3115 + "@typescript-eslint/visitor-keys": "8.38.0",
3116 + "debug": "^4.3.4",
3117 + "fast-glob": "^3.3.2",
3118 + "is-glob": "^4.0.3",
3119 + "minimatch": "^9.0.4",
3120 + "semver": "^7.6.0",
3121 + "ts-api-utils": "^2.1.0"
3122 + },
3123 + "engines": {
3124 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
3125 + },
3126 + "funding": {
3127 + "type": "opencollective",
3128 + "url": "https://opencollective.com/typescript-eslint"
3129 + },
3130 + "peerDependencies": {
3131 + "typescript": ">=4.8.4 <5.9.0"
3132 + }
3133 + },
3134 + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
3135 + "version": "2.0.2",
3136 + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
3137 + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
3138 + "dev": true,
3139 + "license": "MIT",
3140 + "dependencies": {
3141 + "balanced-match": "^1.0.0"
3142 + }
3143 + },
3144 + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
3145 + "version": "9.0.5",
3146 + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
3147 + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
3148 + "dev": true,
3149 + "license": "ISC",
3150 + "dependencies": {
3151 + "brace-expansion": "^2.0.1"
3152 + },
3153 + "engines": {
3154 + "node": ">=16 || 14 >=14.17"
3155 + },
3156 + "funding": {
3157 + "url": "https://github.com/sponsors/isaacs"
3158 + }
3159 + },
3160 + "node_modules/@typescript-eslint/utils": {
3161 + "version": "8.38.0",
3162 + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.38.0.tgz",
3163 + "integrity": "sha512-hHcMA86Hgt+ijJlrD8fX0j1j8w4C92zue/8LOPAFioIno+W0+L7KqE8QZKCcPGc/92Vs9x36w/4MPTJhqXdyvg==",
3164 + "dev": true,
3165 + "license": "MIT",
3166 + "dependencies": {
3167 + "@eslint-community/eslint-utils": "^4.7.0",
3168 + "@typescript-eslint/scope-manager": "8.38.0",
3169 + "@typescript-eslint/types": "8.38.0",
3170 + "@typescript-eslint/typescript-estree": "8.38.0"
3171 + },
3172 + "engines": {
3173 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
3174 + },
3175 + "funding": {
3176 + "type": "opencollective",
3177 + "url": "https://opencollective.com/typescript-eslint"
3178 + },
3179 + "peerDependencies": {
3180 + "eslint": "^8.57.0 || ^9.0.0",
3181 + "typescript": ">=4.8.4 <5.9.0"
3182 + }
3183 + },
3184 + "node_modules/@typescript-eslint/visitor-keys": {
3185 + "version": "8.38.0",
3186 + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.38.0.tgz",
3187 + "integrity": "sha512-pWrTcoFNWuwHlA9CvlfSsGWs14JxfN1TH25zM5L7o0pRLhsoZkDnTsXfQRJBEWJoV5DL0jf+Z+sxiud+K0mq1g==",
3188 + "dev": true,
3189 + "license": "MIT",
3190 + "dependencies": {
3191 + "@typescript-eslint/types": "8.38.0",
3192 + "eslint-visitor-keys": "^4.2.1"
3193 + },
3194 + "engines": {
3195 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
3196 + },
3197 + "funding": {
3198 + "type": "opencollective",
3199 + "url": "https://opencollective.com/typescript-eslint"
3200 + }
3201 + },
3202 + "node_modules/@vitejs/plugin-react-swc": {
3203 + "version": "3.11.0",
3204 + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.11.0.tgz",
3205 + "integrity": "sha512-YTJCGFdNMHCMfjODYtxRNVAYmTWQ1Lb8PulP/2/f/oEEtglw8oKxKIZmmRkyXrVrHfsKOaVkAc3NT9/dMutO5w==",
3206 + "dev": true,
3207 + "license": "MIT",
3208 + "dependencies": {
3209 + "@rolldown/pluginutils": "1.0.0-beta.27",
3210 + "@swc/core": "^1.12.11"
3211 + },
3212 + "peerDependencies": {
3213 + "vite": "^4 || ^5 || ^6 || ^7"
3214 + }
3215 + },
3216 + "node_modules/acorn": {
3217 + "version": "8.15.0",
3218 + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
3219 + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
3220 + "dev": true,
3221 + "license": "MIT",
3222 + "bin": {
3223 + "acorn": "bin/acorn"
3224 + },
3225 + "engines": {
3226 + "node": ">=0.4.0"
3227 + }
3228 + },
3229 + "node_modules/acorn-jsx": {
3230 + "version": "5.3.2",
3231 + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
3232 + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
3233 + "dev": true,
3234 + "license": "MIT",
3235 + "peerDependencies": {
3236 + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
3237 + }
3238 + },
3239 + "node_modules/ajv": {
3240 + "version": "6.12.6",
3241 + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
3242 + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
3243 + "dev": true,
3244 + "license": "MIT",
3245 + "dependencies": {
3246 + "fast-deep-equal": "^3.1.1",
3247 + "fast-json-stable-stringify": "^2.0.0",
3248 + "json-schema-traverse": "^0.4.1",
3249 + "uri-js": "^4.2.2"
3250 + },
3251 + "funding": {
3252 + "type": "github",
3253 + "url": "https://github.com/sponsors/epoberezkin"
3254 + }
3255 + },
3256 + "node_modules/ansi-regex": {
3257 + "version": "6.1.0",
3258 + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
3259 + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
3260 + "license": "MIT",
3261 + "engines": {
3262 + "node": ">=12"
3263 + },
3264 + "funding": {
3265 + "url": "https://github.com/chalk/ansi-regex?sponsor=1"
3266 + }
3267 + },
3268 + "node_modules/ansi-styles": {
3269 + "version": "4.3.0",
3270 + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
3271 + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
3272 + "license": "MIT",
3273 + "dependencies": {
3274 + "color-convert": "^2.0.1"
3275 + },
3276 + "engines": {
3277 + "node": ">=8"
3278 + },
3279 + "funding": {
3280 + "url": "https://github.com/chalk/ansi-styles?sponsor=1"
3281 + }
3282 + },
3283 + "node_modules/any-promise": {
3284 + "version": "1.3.0",
3285 + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
3286 + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
3287 + "license": "MIT"
3288 + },
3289 + "node_modules/anymatch": {
3290 + "version": "3.1.3",
3291 + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
3292 + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
3293 + "license": "ISC",
3294 + "dependencies": {
3295 + "normalize-path": "^3.0.0",
3296 + "picomatch": "^2.0.4"
3297 + },
3298 + "engines": {
3299 + "node": ">= 8"
3300 + }
3301 + },
3302 + "node_modules/arg": {
3303 + "version": "5.0.2",
3304 + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
3305 + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
3306 + "license": "MIT"
3307 + },
3308 + "node_modules/argparse": {
3309 + "version": "2.0.1",
3310 + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
3311 + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
3312 + "dev": true,
3313 + "license": "Python-2.0"
3314 + },
3315 + "node_modules/aria-hidden": {
3316 + "version": "1.2.4",
3317 + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz",
3318 + "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==",
3319 + "license": "MIT",
3320 + "dependencies": {
3321 + "tslib": "^2.0.0"
3322 + },
3323 + "engines": {
3324 + "node": ">=10"
3325 + }
3326 + },
3327 + "node_modules/autoprefixer": {
3328 + "version": "10.4.21",
3329 + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz",
3330 + "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==",
3331 + "dev": true,
3332 + "funding": [
3333 + {
3334 + "type": "opencollective",
3335 + "url": "https://opencollective.com/postcss/"
3336 + },
3337 + {
3338 + "type": "tidelift",
3339 + "url": "https://tidelift.com/funding/github/npm/autoprefixer"
3340 + },
3341 + {
3342 + "type": "github",
3343 + "url": "https://github.com/sponsors/ai"
3344 + }
3345 + ],
3346 + "license": "MIT",
3347 + "dependencies": {
3348 + "browserslist": "^4.24.4",
3349 + "caniuse-lite": "^1.0.30001702",
3350 + "fraction.js": "^4.3.7",
3351 + "normalize-range": "^0.1.2",
3352 + "picocolors": "^1.1.1",
3353 + "postcss-value-parser": "^4.2.0"
3354 + },
3355 + "bin": {
3356 + "autoprefixer": "bin/autoprefixer"
3357 + },
3358 + "engines": {
3359 + "node": "^10 || ^12 || >=14"
3360 + },
3361 + "peerDependencies": {
3362 + "postcss": "^8.1.0"
3363 + }
3364 + },
3365 + "node_modules/balanced-match": {
3366 + "version": "1.0.2",
3367 + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
3368 + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
3369 + "license": "MIT"
3370 + },
3371 + "node_modules/binary-extensions": {
3372 + "version": "2.3.0",
3373 + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
3374 + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
3375 + "license": "MIT",
3376 + "engines": {
3377 + "node": ">=8"
3378 + },
3379 + "funding": {
3380 + "url": "https://github.com/sponsors/sindresorhus"
3381 + }
3382 + },
3383 + "node_modules/brace-expansion": {
3384 + "version": "1.1.12",
3385 + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
3386 + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
3387 + "dev": true,
3388 + "license": "MIT",
3389 + "dependencies": {
3390 + "balanced-match": "^1.0.0",
3391 + "concat-map": "0.0.1"
3392 + }
3393 + },
3394 + "node_modules/braces": {
3395 + "version": "3.0.3",
3396 + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
3397 + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
3398 + "license": "MIT",
3399 + "dependencies": {
3400 + "fill-range": "^7.1.1"
3401 + },
3402 + "engines": {
3403 + "node": ">=8"
3404 + }
3405 + },
3406 + "node_modules/browserslist": {
3407 + "version": "4.25.1",
3408 + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz",
3409 + "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==",
3410 + "dev": true,
3411 + "funding": [
3412 + {
3413 + "type": "opencollective",
3414 + "url": "https://opencollective.com/browserslist"
3415 + },
3416 + {
3417 + "type": "tidelift",
3418 + "url": "https://tidelift.com/funding/github/npm/browserslist"
3419 + },
3420 + {
3421 + "type": "github",
3422 + "url": "https://github.com/sponsors/ai"
3423 + }
3424 + ],
3425 + "license": "MIT",
3426 + "dependencies": {
3427 + "caniuse-lite": "^1.0.30001726",
3428 + "electron-to-chromium": "^1.5.173",
3429 + "node-releases": "^2.0.19",
3430 + "update-browserslist-db": "^1.1.3"
3431 + },
3432 + "bin": {
3433 + "browserslist": "cli.js"
3434 + },
3435 + "engines": {
3436 + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
3437 + }
3438 + },
3439 + "node_modules/callsites": {
3440 + "version": "3.1.0",
3441 + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
3442 + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
3443 + "dev": true,
3444 + "license": "MIT",
3445 + "engines": {
3446 + "node": ">=6"
3447 + }
3448 + },
3449 + "node_modules/camelcase-css": {
3450 + "version": "2.0.1",
3451 + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
3452 + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
3453 + "license": "MIT",
3454 + "engines": {
3455 + "node": ">= 6"
3456 + }
3457 + },
3458 + "node_modules/caniuse-lite": {
3459 + "version": "1.0.30001727",
3460 + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz",
3461 + "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==",
3462 + "dev": true,
3463 + "funding": [
3464 + {
3465 + "type": "opencollective",
3466 + "url": "https://opencollective.com/browserslist"
3467 + },
3468 + {
3469 + "type": "tidelift",
3470 + "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
3471 + },
3472 + {
3473 + "type": "github",
3474 + "url": "https://github.com/sponsors/ai"
3475 + }
3476 + ],
3477 + "license": "CC-BY-4.0"
3478 + },
3479 + "node_modules/chalk": {
3480 + "version": "4.1.2",
3481 + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
3482 + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
3483 + "dev": true,
3484 + "license": "MIT",
3485 + "dependencies": {
3486 + "ansi-styles": "^4.1.0",
3487 + "supports-color": "^7.1.0"
3488 + },
3489 + "engines": {
3490 + "node": ">=10"
3491 + },
3492 + "funding": {
3493 + "url": "https://github.com/chalk/chalk?sponsor=1"
3494 + }
3495 + },
3496 + "node_modules/chokidar": {
3497 + "version": "3.6.0",
3498 + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
3499 + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
3500 + "license": "MIT",
3501 + "dependencies": {
3502 + "anymatch": "~3.1.2",
3503 + "braces": "~3.0.2",
3504 + "glob-parent": "~5.1.2",
3505 + "is-binary-path": "~2.1.0",
3506 + "is-glob": "~4.0.1",
3507 + "normalize-path": "~3.0.0",
3508 + "readdirp": "~3.6.0"
3509 + },
3510 + "engines": {
3511 + "node": ">= 8.10.0"
3512 + },
3513 + "funding": {
3514 + "url": "https://paulmillr.com/funding/"
3515 + },
3516 + "optionalDependencies": {
3517 + "fsevents": "~2.3.2"
3518 + }
3519 + },
3520 + "node_modules/chokidar/node_modules/glob-parent": {
3521 + "version": "5.1.2",
3522 + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
3523 + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
3524 + "license": "ISC",
3525 + "dependencies": {
3526 + "is-glob": "^4.0.1"
3527 + },
3528 + "engines": {
3529 + "node": ">= 6"
3530 + }
3531 + },
3532 + "node_modules/class-variance-authority": {
3533 + "version": "0.7.1",
3534 + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz",
3535 + "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==",
3536 + "dependencies": {
3537 + "clsx": "^2.1.1"
3538 + },
3539 + "funding": {
3540 + "url": "https://polar.sh/cva"
3541 + }
3542 + },
3543 + "node_modules/clsx": {
3544 + "version": "2.1.1",
3545 + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
3546 + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
3547 + "license": "MIT",
3548 + "engines": {
3549 + "node": ">=6"
3550 + }
3551 + },
3552 + "node_modules/cmdk": {
3553 + "version": "1.1.1",
3554 + "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-1.1.1.tgz",
3555 + "integrity": "sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==",
3556 + "license": "MIT",
3557 + "dependencies": {
3558 + "@radix-ui/react-compose-refs": "^1.1.1",
3559 + "@radix-ui/react-dialog": "^1.1.6",
3560 + "@radix-ui/react-id": "^1.1.0",
3561 + "@radix-ui/react-primitive": "^2.0.2"
3562 + },
3563 + "peerDependencies": {
3564 + "react": "^18 || ^19 || ^19.0.0-rc",
3565 + "react-dom": "^18 || ^19 || ^19.0.0-rc"
3566 + }
3567 + },
3568 + "node_modules/color-convert": {
3569 + "version": "2.0.1",
3570 + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
3571 + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
3572 + "license": "MIT",
3573 + "dependencies": {
3574 + "color-name": "~1.1.4"
3575 + },
3576 + "engines": {
3577 + "node": ">=7.0.0"
3578 + }
3579 + },
3580 + "node_modules/color-name": {
3581 + "version": "1.1.4",
3582 + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
3583 + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
3584 + "license": "MIT"
3585 + },
3586 + "node_modules/commander": {
3587 + "version": "4.1.1",
3588 + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
3589 + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
3590 + "license": "MIT",
3591 + "engines": {
3592 + "node": ">= 6"
3593 + }
3594 + },
3595 + "node_modules/concat-map": {
3596 + "version": "0.0.1",
3597 + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
3598 + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
3599 + "dev": true,
3600 + "license": "MIT"
3601 + },
3602 + "node_modules/cross-spawn": {
3603 + "version": "7.0.6",
3604 + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
3605 + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
3606 + "dependencies": {
3607 + "path-key": "^3.1.0",
3608 + "shebang-command": "^2.0.0",
3609 + "which": "^2.0.1"
3610 + },
3611 + "engines": {
3612 + "node": ">= 8"
3613 + }
3614 + },
3615 + "node_modules/cssesc": {
3616 + "version": "3.0.0",
3617 + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
3618 + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
3619 + "license": "MIT",
3620 + "bin": {
3621 + "cssesc": "bin/cssesc"
3622 + },
3623 + "engines": {
3624 + "node": ">=4"
3625 + }
3626 + },
3627 + "node_modules/csstype": {
3628 + "version": "3.1.3",
3629 + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
3630 + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
3631 + "license": "MIT"
3632 + },
3633 + "node_modules/d3-array": {
3634 + "version": "3.2.4",
3635 + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",
3636 + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==",
3637 + "license": "ISC",
3638 + "dependencies": {
3639 + "internmap": "1 - 2"
3640 + },
3641 + "engines": {
3642 + "node": ">=12"
3643 + }
3644 + },
3645 + "node_modules/d3-color": {
3646 + "version": "3.1.0",
3647 + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz",
3648 + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==",
3649 + "license": "ISC",
3650 + "engines": {
3651 + "node": ">=12"
3652 + }
3653 + },
3654 + "node_modules/d3-ease": {
3655 + "version": "3.0.1",
3656 + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",
3657 + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==",
3658 + "license": "BSD-3-Clause",
3659 + "engines": {
3660 + "node": ">=12"
3661 + }
3662 + },
3663 + "node_modules/d3-format": {
3664 + "version": "3.1.0",
3665 + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz",
3666 + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==",
3667 + "license": "ISC",
3668 + "engines": {
3669 + "node": ">=12"
3670 + }
3671 + },
3672 + "node_modules/d3-interpolate": {
3673 + "version": "3.0.1",
3674 + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
3675 + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
3676 + "license": "ISC",
3677 + "dependencies": {
3678 + "d3-color": "1 - 3"
3679 + },
3680 + "engines": {
3681 + "node": ">=12"
3682 + }
3683 + },
3684 + "node_modules/d3-path": {
3685 + "version": "3.1.0",
3686 + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz",
3687 + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==",
3688 + "license": "ISC",
3689 + "engines": {
3690 + "node": ">=12"
3691 + }
3692 + },
3693 + "node_modules/d3-scale": {
3694 + "version": "4.0.2",
3695 + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
3696 + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",
3697 + "license": "ISC",
3698 + "dependencies": {
3699 + "d3-array": "2.10.0 - 3",
3700 + "d3-format": "1 - 3",
3701 + "d3-interpolate": "1.2.0 - 3",
3702 + "d3-time": "2.1.1 - 3",
3703 + "d3-time-format": "2 - 4"
3704 + },
3705 + "engines": {
3706 + "node": ">=12"
3707 + }
3708 + },
3709 + "node_modules/d3-shape": {
3710 + "version": "3.2.0",
3711 + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz",
3712 + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==",
3713 + "license": "ISC",
3714 + "dependencies": {
3715 + "d3-path": "^3.1.0"
3716 + },
3717 + "engines": {
3718 + "node": ">=12"
3719 + }
3720 + },
3721 + "node_modules/d3-time": {
3722 + "version": "3.1.0",
3723 + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz",
3724 + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==",
3725 + "license": "ISC",
3726 + "dependencies": {
3727 + "d3-array": "2 - 3"
3728 + },
3729 + "engines": {
3730 + "node": ">=12"
3731 + }
3732 + },
3733 + "node_modules/d3-time-format": {
3734 + "version": "4.1.0",
3735 + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz",
3736 + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==",
3737 + "license": "ISC",
3738 + "dependencies": {
3739 + "d3-time": "1 - 3"
3740 + },
3741 + "engines": {
3742 + "node": ">=12"
3743 + }
3744 + },
3745 + "node_modules/d3-timer": {
3746 + "version": "3.0.1",
3747 + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
3748 + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",
3749 + "license": "ISC",
3750 + "engines": {
3751 + "node": ">=12"
3752 + }
3753 + },
3754 + "node_modules/date-fns": {
3755 + "version": "3.6.0",
3756 + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz",
3757 + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==",
3758 + "license": "MIT",
3759 + "funding": {
3760 + "type": "github",
3761 + "url": "https://github.com/sponsors/kossnocorp"
3762 + }
3763 + },
3764 + "node_modules/debug": {
3765 + "version": "4.3.7",
3766 + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
3767 + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
3768 + "dev": true,
3769 + "license": "MIT",
3770 + "dependencies": {
3771 + "ms": "^2.1.3"
3772 + },
3773 + "engines": {
3774 + "node": ">=6.0"
3775 + },
3776 + "peerDependenciesMeta": {
3777 + "supports-color": {
3778 + "optional": true
3779 + }
3780 + }
3781 + },
3782 + "node_modules/decimal.js-light": {
3783 + "version": "2.5.1",
3784 + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz",
3785 + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==",
3786 + "license": "MIT"
3787 + },
3788 + "node_modules/deep-is": {
3789 + "version": "0.1.4",
3790 + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
3791 + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
3792 + "dev": true,
3793 + "license": "MIT"
3794 + },
3795 + "node_modules/detect-node-es": {
3796 + "version": "1.1.0",
3797 + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
3798 + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==",
3799 + "license": "MIT"
3800 + },
3801 + "node_modules/didyoumean": {
3802 + "version": "1.2.2",
3803 + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
3804 + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
3805 + "license": "Apache-2.0"
3806 + },
3807 + "node_modules/dlv": {
3808 + "version": "1.1.3",
3809 + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
3810 + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
3811 + "license": "MIT"
3812 + },
3813 + "node_modules/dom-helpers": {
3814 + "version": "5.2.1",
3815 + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
3816 + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
3817 + "license": "MIT",
3818 + "dependencies": {
3819 + "@babel/runtime": "^7.8.7",
3820 + "csstype": "^3.0.2"
3821 + }
3822 + },
3823 + "node_modules/eastasianwidth": {
3824 + "version": "0.2.0",
3825 + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
3826 + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
3827 + "license": "MIT"
3828 + },
3829 + "node_modules/electron-to-chromium": {
3830 + "version": "1.5.192",
3831 + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.192.tgz",
3832 + "integrity": "sha512-rP8Ez0w7UNw/9j5eSXCe10o1g/8B1P5SM90PCCMVkIRQn2R0LEHWz4Eh9RnxkniuDe1W0cTSOB3MLlkTGDcuCg==",
3833 + "dev": true,
3834 + "license": "ISC"
3835 + },
3836 + "node_modules/embla-carousel": {
3837 + "version": "8.6.0",
3838 + "resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.6.0.tgz",
3839 + "integrity": "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==",
3840 + "license": "MIT"
3841 + },
3842 + "node_modules/embla-carousel-react": {
3843 + "version": "8.6.0",
3844 + "resolved": "https://registry.npmjs.org/embla-carousel-react/-/embla-carousel-react-8.6.0.tgz",
3845 + "integrity": "sha512-0/PjqU7geVmo6F734pmPqpyHqiM99olvyecY7zdweCw+6tKEXnrE90pBiBbMMU8s5tICemzpQ3hi5EpxzGW+JA==",
3846 + "license": "MIT",
3847 + "dependencies": {
3848 + "embla-carousel": "8.6.0",
3849 + "embla-carousel-reactive-utils": "8.6.0"
3850 + },
3851 + "peerDependencies": {
3852 + "react": "^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
3853 + }
3854 + },
3855 + "node_modules/embla-carousel-reactive-utils": {
3856 + "version": "8.6.0",
3857 + "resolved": "https://registry.npmjs.org/embla-carousel-reactive-utils/-/embla-carousel-reactive-utils-8.6.0.tgz",
3858 + "integrity": "sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A==",
3859 + "license": "MIT",
3860 + "peerDependencies": {
3861 + "embla-carousel": "8.6.0"
3862 + }
3863 + },
3864 + "node_modules/emoji-regex": {
3865 + "version": "9.2.2",
3866 + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
3867 + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
3868 + "license": "MIT"
3869 + },
3870 + "node_modules/esbuild": {
3871 + "version": "0.21.5",
3872 + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
3873 + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
3874 + "dev": true,
3875 + "hasInstallScript": true,
3876 + "license": "MIT",
3877 + "bin": {
3878 + "esbuild": "bin/esbuild"
3879 + },
3880 + "engines": {
3881 + "node": ">=12"
3882 + },
3883 + "optionalDependencies": {
3884 + "@esbuild/aix-ppc64": "0.21.5",
3885 + "@esbuild/android-arm": "0.21.5",
3886 + "@esbuild/android-arm64": "0.21.5",
3887 + "@esbuild/android-x64": "0.21.5",
3888 + "@esbuild/darwin-arm64": "0.21.5",
3889 + "@esbuild/darwin-x64": "0.21.5",
3890 + "@esbuild/freebsd-arm64": "0.21.5",
3891 + "@esbuild/freebsd-x64": "0.21.5",
3892 + "@esbuild/linux-arm": "0.21.5",
3893 + "@esbuild/linux-arm64": "0.21.5",
3894 + "@esbuild/linux-ia32": "0.21.5",
3895 + "@esbuild/linux-loong64": "0.21.5",
3896 + "@esbuild/linux-mips64el": "0.21.5",
3897 + "@esbuild/linux-ppc64": "0.21.5",
3898 + "@esbuild/linux-riscv64": "0.21.5",
3899 + "@esbuild/linux-s390x": "0.21.5",
3900 + "@esbuild/linux-x64": "0.21.5",
3901 + "@esbuild/netbsd-x64": "0.21.5",
3902 + "@esbuild/openbsd-x64": "0.21.5",
3903 + "@esbuild/sunos-x64": "0.21.5",
3904 + "@esbuild/win32-arm64": "0.21.5",
3905 + "@esbuild/win32-ia32": "0.21.5",
3906 + "@esbuild/win32-x64": "0.21.5"
3907 + }
3908 + },
3909 + "node_modules/escalade": {
3910 + "version": "3.2.0",
3911 + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
3912 + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
3913 + "dev": true,
3914 + "license": "MIT",
3915 + "engines": {
3916 + "node": ">=6"
3917 + }
3918 + },
3919 + "node_modules/escape-string-regexp": {
3920 + "version": "4.0.0",
3921 + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
3922 + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
3923 + "dev": true,
3924 + "license": "MIT",
3925 + "engines": {
3926 + "node": ">=10"
3927 + },
3928 + "funding": {
3929 + "url": "https://github.com/sponsors/sindresorhus"
3930 + }
3931 + },
3932 + "node_modules/eslint": {
3933 + "version": "9.32.0",
3934 + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.32.0.tgz",
3935 + "integrity": "sha512-LSehfdpgMeWcTZkWZVIJl+tkZ2nuSkyyB9C27MZqFWXuph7DvaowgcTvKqxvpLW1JZIk8PN7hFY3Rj9LQ7m7lg==",
3936 + "dev": true,
3937 + "license": "MIT",
3938 + "dependencies": {
3939 + "@eslint-community/eslint-utils": "^4.2.0",
3940 + "@eslint-community/regexpp": "^4.12.1",
3941 + "@eslint/config-array": "^0.21.0",
3942 + "@eslint/config-helpers": "^0.3.0",
3943 + "@eslint/core": "^0.15.0",
3944 + "@eslint/eslintrc": "^3.3.1",
3945 + "@eslint/js": "9.32.0",
3946 + "@eslint/plugin-kit": "^0.3.4",
3947 + "@humanfs/node": "^0.16.6",
3948 + "@humanwhocodes/module-importer": "^1.0.1",
3949 + "@humanwhocodes/retry": "^0.4.2",
3950 + "@types/estree": "^1.0.6",
3951 + "@types/json-schema": "^7.0.15",
3952 + "ajv": "^6.12.4",
3953 + "chalk": "^4.0.0",
3954 + "cross-spawn": "^7.0.6",
3955 + "debug": "^4.3.2",
3956 + "escape-string-regexp": "^4.0.0",
3957 + "eslint-scope": "^8.4.0",
3958 + "eslint-visitor-keys": "^4.2.1",
3959 + "espree": "^10.4.0",
3960 + "esquery": "^1.5.0",
3961 + "esutils": "^2.0.2",
3962 + "fast-deep-equal": "^3.1.3",
3963 + "file-entry-cache": "^8.0.0",
3964 + "find-up": "^5.0.0",
3965 + "glob-parent": "^6.0.2",
3966 + "ignore": "^5.2.0",
3967 + "imurmurhash": "^0.1.4",
3968 + "is-glob": "^4.0.0",
3969 + "json-stable-stringify-without-jsonify": "^1.0.1",
3970 + "lodash.merge": "^4.6.2",
3971 + "minimatch": "^3.1.2",
3972 + "natural-compare": "^1.4.0",
3973 + "optionator": "^0.9.3"
3974 + },
3975 + "bin": {
3976 + "eslint": "bin/eslint.js"
3977 + },
3978 + "engines": {
3979 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
3980 + },
3981 + "funding": {
3982 + "url": "https://eslint.org/donate"
3983 + },
3984 + "peerDependencies": {
3985 + "jiti": "*"
3986 + },
3987 + "peerDependenciesMeta": {
3988 + "jiti": {
3989 + "optional": true
3990 + }
3991 + }
3992 + },
3993 + "node_modules/eslint-plugin-react-hooks": {
3994 + "version": "5.2.0",
3995 + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz",
3996 + "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==",
3997 + "dev": true,
3998 + "license": "MIT",
3999 + "engines": {
4000 + "node": ">=10"
4001 + },
4002 + "peerDependencies": {
4003 + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0"
4004 + }
4005 + },
4006 + "node_modules/eslint-plugin-react-refresh": {
4007 + "version": "0.4.20",
4008 + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.20.tgz",
4009 + "integrity": "sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA==",
4010 + "dev": true,
4011 + "license": "MIT",
4012 + "peerDependencies": {
4013 + "eslint": ">=8.40"
4014 + }
4015 + },
4016 + "node_modules/eslint-scope": {
4017 + "version": "8.4.0",
4018 + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
4019 + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
4020 + "dev": true,
4021 + "license": "BSD-2-Clause",
4022 + "dependencies": {
4023 + "esrecurse": "^4.3.0",
4024 + "estraverse": "^5.2.0"
4025 + },
4026 + "engines": {
4027 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
4028 + },
4029 + "funding": {
4030 + "url": "https://opencollective.com/eslint"
4031 + }
4032 + },
4033 + "node_modules/eslint-visitor-keys": {
4034 + "version": "4.2.1",
4035 + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
4036 + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
4037 + "dev": true,
4038 + "license": "Apache-2.0",
4039 + "engines": {
4040 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
4041 + },
4042 + "funding": {
4043 + "url": "https://opencollective.com/eslint"
4044 + }
4045 + },
4046 + "node_modules/espree": {
4047 + "version": "10.4.0",
4048 + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
4049 + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
4050 + "dev": true,
4051 + "license": "BSD-2-Clause",
4052 + "dependencies": {
4053 + "acorn": "^8.15.0",
4054 + "acorn-jsx": "^5.3.2",
4055 + "eslint-visitor-keys": "^4.2.1"
4056 + },
4057 + "engines": {
4058 + "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
4059 + },
4060 + "funding": {
4061 + "url": "https://opencollective.com/eslint"
4062 + }
4063 + },
4064 + "node_modules/esquery": {
4065 + "version": "1.6.0",
4066 + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
4067 + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
4068 + "dev": true,
4069 + "license": "BSD-3-Clause",
4070 + "dependencies": {
4071 + "estraverse": "^5.1.0"
4072 + },
4073 + "engines": {
4074 + "node": ">=0.10"
4075 + }
4076 + },
4077 + "node_modules/esrecurse": {
4078 + "version": "4.3.0",
4079 + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
4080 + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
4081 + "dev": true,
4082 + "license": "BSD-2-Clause",
4083 + "dependencies": {
4084 + "estraverse": "^5.2.0"
4085 + },
4086 + "engines": {
4087 + "node": ">=4.0"
4088 + }
4089 + },
4090 + "node_modules/estraverse": {
4091 + "version": "5.3.0",
4092 + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
4093 + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
4094 + "dev": true,
4095 + "license": "BSD-2-Clause",
4096 + "engines": {
4097 + "node": ">=4.0"
4098 + }
4099 + },
4100 + "node_modules/estree-walker": {
4101 + "version": "3.0.3",
4102 + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
4103 + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
4104 + "dev": true,
4105 + "license": "MIT",
4106 + "dependencies": {
4107 + "@types/estree": "^1.0.0"
4108 + }
4109 + },
4110 + "node_modules/esutils": {
4111 + "version": "2.0.3",
4112 + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
4113 + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
4114 + "dev": true,
4115 + "license": "BSD-2-Clause",
4116 + "engines": {
4117 + "node": ">=0.10.0"
4118 + }
4119 + },
4120 + "node_modules/eventemitter3": {
4121 + "version": "4.0.7",
4122 + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
4123 + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
4124 + "license": "MIT"
4125 + },
4126 + "node_modules/fast-deep-equal": {
4127 + "version": "3.1.3",
4128 + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
4129 + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
4130 + "dev": true,
4131 + "license": "MIT"
4132 + },
4133 + "node_modules/fast-equals": {
4134 + "version": "5.2.2",
4135 + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.2.2.tgz",
4136 + "integrity": "sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw==",
4137 + "license": "MIT",
4138 + "engines": {
4139 + "node": ">=6.0.0"
4140 + }
4141 + },
4142 + "node_modules/fast-glob": {
4143 + "version": "3.3.2",
4144 + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
4145 + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
4146 + "license": "MIT",
4147 + "dependencies": {
4148 + "@nodelib/fs.stat": "^2.0.2",
4149 + "@nodelib/fs.walk": "^1.2.3",
4150 + "glob-parent": "^5.1.2",
4151 + "merge2": "^1.3.0",
4152 + "micromatch": "^4.0.4"
4153 + },
4154 + "engines": {
4155 + "node": ">=8.6.0"
4156 + }
4157 + },
4158 + "node_modules/fast-glob/node_modules/glob-parent": {
4159 + "version": "5.1.2",
4160 + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
4161 + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
4162 + "license": "ISC",
4163 + "dependencies": {
4164 + "is-glob": "^4.0.1"
4165 + },
4166 + "engines": {
4167 + "node": ">= 6"
4168 + }
4169 + },
4170 + "node_modules/fast-json-stable-stringify": {
4171 + "version": "2.1.0",
4172 + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
4173 + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
4174 + "dev": true,
4175 + "license": "MIT"
4176 + },
4177 + "node_modules/fast-levenshtein": {
4178 + "version": "2.0.6",
4179 + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
4180 + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
4181 + "dev": true,
4182 + "license": "MIT"
4183 + },
4184 + "node_modules/fastq": {
4185 + "version": "1.17.1",
4186 + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
4187 + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
4188 + "license": "ISC",
4189 + "dependencies": {
4190 + "reusify": "^1.0.4"
4191 + }
4192 + },
4193 + "node_modules/file-entry-cache": {
4194 + "version": "8.0.0",
4195 + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
4196 + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
4197 + "dev": true,
4198 + "license": "MIT",
4199 + "dependencies": {
4200 + "flat-cache": "^4.0.0"
4201 + },
4202 + "engines": {
4203 + "node": ">=16.0.0"
4204 + }
4205 + },
4206 + "node_modules/fill-range": {
4207 + "version": "7.1.1",
4208 + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
4209 + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
4210 + "license": "MIT",
4211 + "dependencies": {
4212 + "to-regex-range": "^5.0.1"
4213 + },
4214 + "engines": {
4215 + "node": ">=8"
4216 + }
4217 + },
4218 + "node_modules/find-up": {
4219 + "version": "5.0.0",
4220 + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
4221 + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
4222 + "dev": true,
4223 + "license": "MIT",
4224 + "dependencies": {
4225 + "locate-path": "^6.0.0",
4226 + "path-exists": "^4.0.0"
4227 + },
4228 + "engines": {
4229 + "node": ">=10"
4230 + },
4231 + "funding": {
4232 + "url": "https://github.com/sponsors/sindresorhus"
4233 + }
4234 + },
4235 + "node_modules/flat-cache": {
4236 + "version": "4.0.1",
4237 + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
4238 + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
4239 + "dev": true,
4240 + "license": "MIT",
4241 + "dependencies": {
4242 + "flatted": "^3.2.9",
4243 + "keyv": "^4.5.4"
4244 + },
4245 + "engines": {
4246 + "node": ">=16"
4247 + }
4248 + },
4249 + "node_modules/flatted": {
4250 + "version": "3.3.1",
4251 + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
4252 + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
4253 + "dev": true,
4254 + "license": "ISC"
4255 + },
4256 + "node_modules/foreground-child": {
4257 + "version": "3.3.0",
4258 + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
4259 + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
4260 + "license": "ISC",
4261 + "dependencies": {
4262 + "cross-spawn": "^7.0.0",
4263 + "signal-exit": "^4.0.1"
4264 + },
4265 + "engines": {
4266 + "node": ">=14"
4267 + },
4268 + "funding": {
4269 + "url": "https://github.com/sponsors/isaacs"
4270 + }
4271 + },
4272 + "node_modules/fraction.js": {
4273 + "version": "4.3.7",
4274 + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
4275 + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
4276 + "dev": true,
4277 + "license": "MIT",
4278 + "engines": {
4279 + "node": "*"
4280 + },
4281 + "funding": {
4282 + "type": "patreon",
4283 + "url": "https://github.com/sponsors/rawify"
4284 + }
4285 + },
4286 + "node_modules/fsevents": {
4287 + "version": "2.3.3",
4288 + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
4289 + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
4290 + "hasInstallScript": true,
4291 + "license": "MIT",
4292 + "optional": true,
4293 + "os": [
4294 + "darwin"
4295 + ],
4296 + "engines": {
4297 + "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
4298 + }
4299 + },
4300 + "node_modules/function-bind": {
4301 + "version": "1.1.2",
4302 + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
4303 + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
4304 + "license": "MIT",
4305 + "funding": {
4306 + "url": "https://github.com/sponsors/ljharb"
4307 + }
4308 + },
4309 + "node_modules/get-nonce": {
4310 + "version": "1.0.1",
4311 + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz",
4312 + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==",
4313 + "license": "MIT",
4314 + "engines": {
4315 + "node": ">=6"
4316 + }
4317 + },
4318 + "node_modules/glob": {
4319 + "version": "10.4.5",
4320 + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
4321 + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
4322 + "license": "ISC",
4323 + "dependencies": {
4324 + "foreground-child": "^3.1.0",
4325 + "jackspeak": "^3.1.2",
4326 + "minimatch": "^9.0.4",
4327 + "minipass": "^7.1.2",
4328 + "package-json-from-dist": "^1.0.0",
4329 + "path-scurry": "^1.11.1"
4330 + },
4331 + "bin": {
4332 + "glob": "dist/esm/bin.mjs"
4333 + },
4334 + "funding": {
4335 + "url": "https://github.com/sponsors/isaacs"
4336 + }
4337 + },
4338 + "node_modules/glob-parent": {
4339 + "version": "6.0.2",
4340 + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
4341 + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
4342 + "license": "ISC",
4343 + "dependencies": {
4344 + "is-glob": "^4.0.3"
4345 + },
4346 + "engines": {
4347 + "node": ">=10.13.0"
4348 + }
4349 + },
4350 + "node_modules/glob/node_modules/brace-expansion": {
4351 + "version": "2.0.2",
4352 + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
4353 + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
4354 + "license": "MIT",
4355 + "dependencies": {
4356 + "balanced-match": "^1.0.0"
4357 + }
4358 + },
4359 + "node_modules/glob/node_modules/minimatch": {
4360 + "version": "9.0.5",
4361 + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
4362 + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
4363 + "license": "ISC",
4364 + "dependencies": {
4365 + "brace-expansion": "^2.0.1"
4366 + },
4367 + "engines": {
4368 + "node": ">=16 || 14 >=14.17"
4369 + },
4370 + "funding": {
4371 + "url": "https://github.com/sponsors/isaacs"
4372 + }
4373 + },
4374 + "node_modules/globals": {
4375 + "version": "15.15.0",
4376 + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz",
4377 + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==",
4378 + "dev": true,
4379 + "license": "MIT",
4380 + "engines": {
4381 + "node": ">=18"
4382 + },
4383 + "funding": {
4384 + "url": "https://github.com/sponsors/sindresorhus"
4385 + }
4386 + },
4387 + "node_modules/graphemer": {
4388 + "version": "1.4.0",
4389 + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
4390 + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
4391 + "dev": true,
4392 + "license": "MIT"
4393 + },
4394 + "node_modules/has-flag": {
4395 + "version": "4.0.0",
4396 + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
4397 + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
4398 + "dev": true,
4399 + "license": "MIT",
4400 + "engines": {
4401 + "node": ">=8"
4402 + }
4403 + },
4404 + "node_modules/hasown": {
4405 + "version": "2.0.2",
4406 + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
4407 + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
4408 + "license": "MIT",
4409 + "dependencies": {
4410 + "function-bind": "^1.1.2"
4411 + },
4412 + "engines": {
4413 + "node": ">= 0.4"
4414 + }
4415 + },
4416 + "node_modules/ignore": {
4417 + "version": "5.3.2",
4418 + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
4419 + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
4420 + "dev": true,
4421 + "license": "MIT",
4422 + "engines": {
4423 + "node": ">= 4"
4424 + }
4425 + },
4426 + "node_modules/import-fresh": {
4427 + "version": "3.3.1",
4428 + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
4429 + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
4430 + "dev": true,
4431 + "license": "MIT",
4432 + "dependencies": {
4433 + "parent-module": "^1.0.0",
4434 + "resolve-from": "^4.0.0"
4435 + },
4436 + "engines": {
4437 + "node": ">=6"
4438 + },
4439 + "funding": {
4440 + "url": "https://github.com/sponsors/sindresorhus"
4441 + }
4442 + },
4443 + "node_modules/imurmurhash": {
4444 + "version": "0.1.4",
4445 + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
4446 + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
4447 + "dev": true,
4448 + "license": "MIT",
4449 + "engines": {
4450 + "node": ">=0.8.19"
4451 + }
4452 + },
4453 + "node_modules/input-otp": {
4454 + "version": "1.4.2",
4455 + "resolved": "https://registry.npmjs.org/input-otp/-/input-otp-1.4.2.tgz",
4456 + "integrity": "sha512-l3jWwYNvrEa6NTCt7BECfCm48GvwuZzkoeG3gBL2w4CHeOXW3eKFmf9UNYkNfYc3mxMrthMnxjIE07MT0zLBQA==",
4457 + "license": "MIT",
4458 + "peerDependencies": {
4459 + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc",
4460 + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc"
4461 + }
4462 + },
4463 + "node_modules/internmap": {
4464 + "version": "2.0.3",
4465 + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz",
4466 + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==",
4467 + "license": "ISC",
4468 + "engines": {
4469 + "node": ">=12"
4470 + }
4471 + },
4472 + "node_modules/is-binary-path": {
4473 + "version": "2.1.0",
4474 + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
4475 + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
4476 + "license": "MIT",
4477 + "dependencies": {
4478 + "binary-extensions": "^2.0.0"
4479 + },
4480 + "engines": {
4481 + "node": ">=8"
4482 + }
4483 + },
4484 + "node_modules/is-core-module": {
4485 + "version": "2.15.1",
4486 + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz",
4487 + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==",
4488 + "license": "MIT",
4489 + "dependencies": {
4490 + "hasown": "^2.0.2"
4491 + },
4492 + "engines": {
4493 + "node": ">= 0.4"
4494 + },
4495 + "funding": {
4496 + "url": "https://github.com/sponsors/ljharb"
4497 + }
4498 + },
4499 + "node_modules/is-extglob": {
4500 + "version": "2.1.1",
4501 + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
4502 + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
4503 + "license": "MIT",
4504 + "engines": {
4505 + "node": ">=0.10.0"
4506 + }
4507 + },
4508 + "node_modules/is-fullwidth-code-point": {
4509 + "version": "3.0.0",
4510 + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
4511 + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
4512 + "license": "MIT",
4513 + "engines": {
4514 + "node": ">=8"
4515 + }
4516 + },
4517 + "node_modules/is-glob": {
4518 + "version": "4.0.3",
4519 + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
4520 + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
4521 + "license": "MIT",
4522 + "dependencies": {
4523 + "is-extglob": "^2.1.1"
4524 + },
4525 + "engines": {
4526 + "node": ">=0.10.0"
4527 + }
4528 + },
4529 + "node_modules/is-number": {
4530 + "version": "7.0.0",
4531 + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
4532 + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
4533 + "license": "MIT",
4534 + "engines": {
4535 + "node": ">=0.12.0"
4536 + }
4537 + },
4538 + "node_modules/isexe": {
4539 + "version": "2.0.0",
4540 + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
4541 + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
4542 + "license": "ISC"
4543 + },
4544 + "node_modules/jackspeak": {
4545 + "version": "3.4.3",
4546 + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
4547 + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
4548 + "license": "BlueOak-1.0.0",
4549 + "dependencies": {
4550 + "@isaacs/cliui": "^8.0.2"
4551 + },
4552 + "funding": {
4553 + "url": "https://github.com/sponsors/isaacs"
4554 + },
4555 + "optionalDependencies": {
4556 + "@pkgjs/parseargs": "^0.11.0"
4557 + }
4558 + },
4559 + "node_modules/jiti": {
4560 + "version": "1.21.6",
4561 + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz",
4562 + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==",
4563 + "license": "MIT",
4564 + "bin": {
4565 + "jiti": "bin/jiti.js"
4566 + }
4567 + },
4568 + "node_modules/js-tokens": {
4569 + "version": "4.0.0",
4570 + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
4571 + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
4572 + "license": "MIT"
4573 + },
4574 + "node_modules/js-yaml": {
4575 + "version": "4.1.0",
4576 + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
4577 + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
4578 + "dev": true,
4579 + "license": "MIT",
4580 + "dependencies": {
4581 + "argparse": "^2.0.1"
4582 + },
4583 + "bin": {
4584 + "js-yaml": "bin/js-yaml.js"
4585 + }
4586 + },
4587 + "node_modules/json-buffer": {
4588 + "version": "3.0.1",
4589 + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
4590 + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
4591 + "dev": true,
4592 + "license": "MIT"
4593 + },
4594 + "node_modules/json-schema-traverse": {
4595 + "version": "0.4.1",
4596 + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
4597 + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
4598 + "dev": true,
4599 + "license": "MIT"
4600 + },
4601 + "node_modules/json-stable-stringify-without-jsonify": {
4602 + "version": "1.0.1",
4603 + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
4604 + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
4605 + "dev": true,
4606 + "license": "MIT"
4607 + },
4608 + "node_modules/keyv": {
4609 + "version": "4.5.4",
4610 + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
4611 + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
4612 + "dev": true,
4613 + "license": "MIT",
4614 + "dependencies": {
4615 + "json-buffer": "3.0.1"
4616 + }
4617 + },
4618 + "node_modules/levn": {
4619 + "version": "0.4.1",
4620 + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
4621 + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
4622 + "dev": true,
4623 + "license": "MIT",
4624 + "dependencies": {
4625 + "prelude-ls": "^1.2.1",
4626 + "type-check": "~0.4.0"
4627 + },
4628 + "engines": {
4629 + "node": ">= 0.8.0"
4630 + }
4631 + },
4632 + "node_modules/lilconfig": {
4633 + "version": "3.1.3",
4634 + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
4635 + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
4636 + "license": "MIT",
4637 + "engines": {
4638 + "node": ">=14"
4639 + },
4640 + "funding": {
4641 + "url": "https://github.com/sponsors/antonk52"
4642 + }
4643 + },
4644 + "node_modules/lines-and-columns": {
4645 + "version": "1.2.4",
4646 + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
4647 + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
4648 + "license": "MIT"
4649 + },
4650 + "node_modules/locate-path": {
4651 + "version": "6.0.0",
4652 + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
4653 + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
4654 + "dev": true,
4655 + "license": "MIT",
4656 + "dependencies": {
4657 + "p-locate": "^5.0.0"
4658 + },
4659 + "engines": {
4660 + "node": ">=10"
4661 + },
4662 + "funding": {
4663 + "url": "https://github.com/sponsors/sindresorhus"
4664 + }
4665 + },
4666 + "node_modules/lodash": {
4667 + "version": "4.17.21",
4668 + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
4669 + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
4670 + "license": "MIT"
4671 + },
4672 + "node_modules/lodash.castarray": {
4673 + "version": "4.4.0",
4674 + "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz",
4675 + "integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==",
4676 + "dev": true
4677 + },
4678 + "node_modules/lodash.isplainobject": {
4679 + "version": "4.0.6",
4680 + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
4681 + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
4682 + "dev": true
4683 + },
4684 + "node_modules/lodash.merge": {
4685 + "version": "4.6.2",
4686 + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
4687 + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
4688 + "dev": true,
4689 + "license": "MIT"
4690 + },
4691 + "node_modules/loose-envify": {
4692 + "version": "1.4.0",
4693 + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
4694 + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
4695 + "license": "MIT",
4696 + "dependencies": {
4697 + "js-tokens": "^3.0.0 || ^4.0.0"
4698 + },
4699 + "bin": {
4700 + "loose-envify": "cli.js"
4701 + }
4702 + },
4703 + "node_modules/lovable-tagger": {
4704 + "version": "1.1.11",
4705 + "resolved": "https://registry.npmjs.org/lovable-tagger/-/lovable-tagger-1.1.11.tgz",
4706 + "integrity": "sha512-G1gUZi8CebQpB/5+IHWYekRyeRFF2RR7iXSjGO+iVWpwlpa19swgYCYem2z+IkBJO0fKRYJ98xz4yhdt++MzLA==",
4707 + "dev": true,
4708 + "license": "MIT",
4709 + "dependencies": {
4710 + "@babel/parser": "^7.25.9",
4711 + "@babel/types": "^7.25.8",
4712 + "esbuild": "^0.25.0",
4713 + "estree-walker": "^3.0.3",
4714 + "magic-string": "^0.30.12",
4715 + "tailwindcss": "^3.4.17"
4716 + },
4717 + "peerDependencies": {
4718 + "vite": ">=5.0.0 <8.0.0"
4719 + }
4720 + },
4721 + "node_modules/lovable-tagger/node_modules/@esbuild/aix-ppc64": {
4722 + "version": "0.25.0",
4723 + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.0.tgz",
4724 + "integrity": "sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==",
4725 + "cpu": [
4726 + "ppc64"
4727 + ],
4728 + "dev": true,
4729 + "license": "MIT",
4730 + "optional": true,
4731 + "os": [
4732 + "aix"
4733 + ],
4734 + "engines": {
4735 + "node": ">=18"
4736 + }
4737 + },
4738 + "node_modules/lovable-tagger/node_modules/@esbuild/android-arm": {
4739 + "version": "0.25.0",
4740 + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.0.tgz",
4741 + "integrity": "sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==",
4742 + "cpu": [
4743 + "arm"
4744 + ],
4745 + "dev": true,
4746 + "license": "MIT",
4747 + "optional": true,
4748 + "os": [
4749 + "android"
4750 + ],
4751 + "engines": {
4752 + "node": ">=18"
4753 + }
4754 + },
4755 + "node_modules/lovable-tagger/node_modules/@esbuild/android-arm64": {
4756 + "version": "0.25.0",
4757 + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.0.tgz",
4758 + "integrity": "sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==",
4759 + "cpu": [
4760 + "arm64"
4761 + ],
4762 + "dev": true,
4763 + "license": "MIT",
4764 + "optional": true,
4765 + "os": [
4766 + "android"
4767 + ],
4768 + "engines": {
4769 + "node": ">=18"
4770 + }
4771 + },
4772 + "node_modules/lovable-tagger/node_modules/@esbuild/android-x64": {
4773 + "version": "0.25.0",
4774 + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.0.tgz",
4775 + "integrity": "sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==",
4776 + "cpu": [
4777 + "x64"
4778 + ],
4779 + "dev": true,
4780 + "license": "MIT",
4781 + "optional": true,
4782 + "os": [
4783 + "android"
4784 + ],
4785 + "engines": {
4786 + "node": ">=18"
4787 + }
4788 + },
4789 + "node_modules/lovable-tagger/node_modules/@esbuild/darwin-arm64": {
4790 + "version": "0.25.0",
4791 + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.0.tgz",
4792 + "integrity": "sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==",
4793 + "cpu": [
4794 + "arm64"
4795 + ],
4796 + "dev": true,
4797 + "license": "MIT",
4798 + "optional": true,
4799 + "os": [
4800 + "darwin"
4801 + ],
4802 + "engines": {
4803 + "node": ">=18"
4804 + }
4805 + },
4806 + "node_modules/lovable-tagger/node_modules/@esbuild/darwin-x64": {
4807 + "version": "0.25.0",
4808 + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.0.tgz",
4809 + "integrity": "sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==",
4810 + "cpu": [
4811 + "x64"
4812 + ],
4813 + "dev": true,
4814 + "license": "MIT",
4815 + "optional": true,
4816 + "os": [
4817 + "darwin"
4818 + ],
4819 + "engines": {
4820 + "node": ">=18"
4821 + }
4822 + },
4823 + "node_modules/lovable-tagger/node_modules/@esbuild/freebsd-arm64": {
4824 + "version": "0.25.0",
4825 + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.0.tgz",
4826 + "integrity": "sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==",
4827 + "cpu": [
4828 + "arm64"
4829 + ],
4830 + "dev": true,
4831 + "license": "MIT",
4832 + "optional": true,
4833 + "os": [
4834 + "freebsd"
4835 + ],
4836 + "engines": {
4837 + "node": ">=18"
4838 + }
4839 + },
4840 + "node_modules/lovable-tagger/node_modules/@esbuild/freebsd-x64": {
4841 + "version": "0.25.0",
4842 + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.0.tgz",
4843 + "integrity": "sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==",
4844 + "cpu": [
4845 + "x64"
4846 + ],
4847 + "dev": true,
4848 + "license": "MIT",
4849 + "optional": true,
4850 + "os": [
4851 + "freebsd"
4852 + ],
4853 + "engines": {
4854 + "node": ">=18"
4855 + }
4856 + },
4857 + "node_modules/lovable-tagger/node_modules/@esbuild/linux-arm": {
4858 + "version": "0.25.0",
4859 + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.0.tgz",
4860 + "integrity": "sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==",
4861 + "cpu": [
4862 + "arm"
4863 + ],
4864 + "dev": true,
4865 + "license": "MIT",
4866 + "optional": true,
4867 + "os": [
4868 + "linux"
4869 + ],
4870 + "engines": {
4871 + "node": ">=18"
4872 + }
4873 + },
4874 + "node_modules/lovable-tagger/node_modules/@esbuild/linux-arm64": {
4875 + "version": "0.25.0",
4876 + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.0.tgz",
4877 + "integrity": "sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==",
4878 + "cpu": [
4879 + "arm64"
4880 + ],
4881 + "dev": true,
4882 + "license": "MIT",
4883 + "optional": true,
4884 + "os": [
4885 + "linux"
4886 + ],
4887 + "engines": {
4888 + "node": ">=18"
4889 + }
4890 + },
4891 + "node_modules/lovable-tagger/node_modules/@esbuild/linux-ia32": {
4892 + "version": "0.25.0",
4893 + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.0.tgz",
4894 + "integrity": "sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==",
4895 + "cpu": [
4896 + "ia32"
4897 + ],
4898 + "dev": true,
4899 + "license": "MIT",
4900 + "optional": true,
4901 + "os": [
4902 + "linux"
4903 + ],
4904 + "engines": {
4905 + "node": ">=18"
4906 + }
4907 + },
4908 + "node_modules/lovable-tagger/node_modules/@esbuild/linux-loong64": {
4909 + "version": "0.25.0",
4910 + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.0.tgz",
4911 + "integrity": "sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==",
4912 + "cpu": [
4913 + "loong64"
4914 + ],
4915 + "dev": true,
4916 + "license": "MIT",
4917 + "optional": true,
4918 + "os": [
4919 + "linux"
4920 + ],
4921 + "engines": {
4922 + "node": ">=18"
4923 + }
4924 + },
4925 + "node_modules/lovable-tagger/node_modules/@esbuild/linux-mips64el": {
4926 + "version": "0.25.0",
4927 + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.0.tgz",
4928 + "integrity": "sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==",
4929 + "cpu": [
4930 + "mips64el"
4931 + ],
4932 + "dev": true,
4933 + "license": "MIT",
4934 + "optional": true,
4935 + "os": [
4936 + "linux"
4937 + ],
4938 + "engines": {
4939 + "node": ">=18"
4940 + }
4941 + },
4942 + "node_modules/lovable-tagger/node_modules/@esbuild/linux-ppc64": {
4943 + "version": "0.25.0",
4944 + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.0.tgz",
4945 + "integrity": "sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==",
4946 + "cpu": [
4947 + "ppc64"
4948 + ],
4949 + "dev": true,
4950 + "license": "MIT",
4951 + "optional": true,
4952 + "os": [
4953 + "linux"
4954 + ],
4955 + "engines": {
4956 + "node": ">=18"
4957 + }
4958 + },
4959 + "node_modules/lovable-tagger/node_modules/@esbuild/linux-riscv64": {
4960 + "version": "0.25.0",
4961 + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.0.tgz",
4962 + "integrity": "sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==",
4963 + "cpu": [
4964 + "riscv64"
4965 + ],
4966 + "dev": true,
4967 + "license": "MIT",
4968 + "optional": true,
4969 + "os": [
4970 + "linux"
4971 + ],
4972 + "engines": {
4973 + "node": ">=18"
4974 + }
4975 + },
4976 + "node_modules/lovable-tagger/node_modules/@esbuild/linux-s390x": {
4977 + "version": "0.25.0",
4978 + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.0.tgz",
4979 + "integrity": "sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==",
4980 + "cpu": [
4981 + "s390x"
4982 + ],
4983 + "dev": true,
4984 + "license": "MIT",
4985 + "optional": true,
4986 + "os": [
4987 + "linux"
4988 + ],
4989 + "engines": {
4990 + "node": ">=18"
4991 + }
4992 + },
4993 + "node_modules/lovable-tagger/node_modules/@esbuild/linux-x64": {
4994 + "version": "0.25.0",
4995 + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.0.tgz",
4996 + "integrity": "sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==",
4997 + "cpu": [
4998 + "x64"
4999 + ],

This file is too large to show in full.

package.json new
+83
@@ -0,0 +1,83 @@
1 +{
2 + "name": "vite_react_shadcn_ts",
3 + "private": true,
4 + "version": "0.0.0",
5 + "type": "module",
6 + "scripts": {
7 + "dev": "vite",
8 + "build": "vite build",
9 + "build:dev": "vite build --mode development",
10 + "lint": "eslint .",
11 + "preview": "vite preview"
12 + },
13 + "dependencies": {
14 + "@hookform/resolvers": "^3.10.0",
15 + "@radix-ui/react-accordion": "^1.2.11",
16 + "@radix-ui/react-alert-dialog": "^1.1.14",
17 + "@radix-ui/react-aspect-ratio": "^1.1.7",
18 + "@radix-ui/react-avatar": "^1.1.10",
19 + "@radix-ui/react-checkbox": "^1.3.2",
20 + "@radix-ui/react-collapsible": "^1.1.11",
21 + "@radix-ui/react-context-menu": "^2.2.15",
22 + "@radix-ui/react-dialog": "^1.1.14",
23 + "@radix-ui/react-dropdown-menu": "^2.1.15",
24 + "@radix-ui/react-hover-card": "^1.1.14",
25 + "@radix-ui/react-label": "^2.1.7",
26 + "@radix-ui/react-menubar": "^1.1.15",
27 + "@radix-ui/react-navigation-menu": "^1.2.13",
28 + "@radix-ui/react-popover": "^1.1.14",
29 + "@radix-ui/react-progress": "^1.1.7",
30 + "@radix-ui/react-radio-group": "^1.3.7",
31 + "@radix-ui/react-scroll-area": "^1.2.9",
32 + "@radix-ui/react-select": "^2.2.5",
33 + "@radix-ui/react-separator": "^1.1.7",
34 + "@radix-ui/react-slider": "^1.3.5",
35 + "@radix-ui/react-slot": "^1.2.3",
36 + "@radix-ui/react-switch": "^1.2.5",
37 + "@radix-ui/react-tabs": "^1.1.12",
38 + "@radix-ui/react-toast": "^1.2.14",
39 + "@radix-ui/react-toggle": "^1.1.9",
40 + "@radix-ui/react-toggle-group": "^1.1.10",
41 + "@radix-ui/react-tooltip": "^1.2.7",
42 + "@tanstack/react-query": "^5.83.0",
43 + "class-variance-authority": "^0.7.1",
44 + "clsx": "^2.1.1",
45 + "cmdk": "^1.1.1",
46 + "date-fns": "^3.6.0",
47 + "embla-carousel-react": "^8.6.0",
48 + "input-otp": "^1.4.2",
49 + "lucide-react": "^0.462.0",
50 + "next-themes": "^0.3.0",
51 + "react": "^18.3.1",
52 + "react-day-picker": "^8.10.1",
53 + "react-dom": "^18.3.1",
54 + "react-hook-form": "^7.61.1",
55 + "react-resizable-panels": "^2.1.9",
56 + "react-router-dom": "^6.30.1",
57 + "recharts": "^2.15.4",
58 + "sonner": "^1.7.4",
59 + "tailwind-merge": "^2.6.0",
60 + "tailwindcss-animate": "^1.0.7",
61 + "vaul": "^0.9.9",
62 + "zod": "^3.25.76"
63 + },
64 + "devDependencies": {
65 + "@eslint/js": "^9.32.0",
66 + "@tailwindcss/typography": "^0.5.16",
67 + "@types/node": "^22.16.5",
68 + "@types/react": "^18.3.23",
69 + "@types/react-dom": "^18.3.7",
70 + "@vitejs/plugin-react-swc": "^3.11.0",
71 + "autoprefixer": "^10.4.21",
72 + "eslint": "^9.32.0",
73 + "eslint-plugin-react-hooks": "^5.2.0",
74 + "eslint-plugin-react-refresh": "^0.4.20",
75 + "globals": "^15.15.0",
76 + "lovable-tagger": "^1.1.11",
77 + "postcss": "^8.5.6",
78 + "tailwindcss": "^3.4.17",
79 + "typescript": "^5.8.3",
80 + "typescript-eslint": "^8.38.0",
81 + "vite": "^5.4.19"
82 + }
83 +}
postcss.config.js new
+6
@@ -0,0 +1,6 @@
1 +export default {
2 + plugins: {
3 + tailwindcss: {},
4 + autoprefixer: {},
5 + },
6 +};
public/favicon.ico
Binary files /dev/null and b/public/favicon.ico differ
public/placeholder.svg new
+1
@@ -0,0 +1 @@
1 +<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="1200" fill="none"><rect width="1200" height="1200" fill="#EAEAEA" rx="3"/><g opacity=".5"><g opacity=".5"><path fill="#FAFAFA" d="M600.709 736.5c-75.454 0-136.621-61.167-136.621-136.62 0-75.454 61.167-136.621 136.621-136.621 75.453 0 136.62 61.167 136.62 136.621 0 75.453-61.167 136.62-136.62 136.62Z"/><path stroke="#C9C9C9" stroke-width="2.418" d="M600.709 736.5c-75.454 0-136.621-61.167-136.621-136.62 0-75.454 61.167-136.621 136.621-136.621 75.453 0 136.62 61.167 136.62 136.621 0 75.453-61.167 136.62-136.62 136.62Z"/></g><path stroke="url(#a)" stroke-width="2.418" d="M0-1.209h553.581" transform="scale(1 -1) rotate(45 1163.11 91.165)"/><path stroke="url(#b)" stroke-width="2.418" d="M404.846 598.671h391.726"/><path stroke="url(#c)" stroke-width="2.418" d="M599.5 795.742V404.017"/><path stroke="url(#d)" stroke-width="2.418" d="m795.717 796.597-391.441-391.44"/><path fill="#fff" d="M600.709 656.704c-31.384 0-56.825-25.441-56.825-56.824 0-31.384 25.441-56.825 56.825-56.825 31.383 0 56.824 25.441 56.824 56.825 0 31.383-25.441 56.824-56.824 56.824Z"/><g clip-path="url(#e)"><path fill="#666" fill-rule="evenodd" d="M616.426 586.58h-31.434v16.176l3.553-3.554.531-.531h9.068l.074-.074 8.463-8.463h2.565l7.18 7.181V586.58Zm-15.715 14.654 3.698 3.699 1.283 1.282-2.565 2.565-1.282-1.283-5.2-5.199h-6.066l-5.514 5.514-.073.073v2.876a2.418 2.418 0 0 0 2.418 2.418h26.598a2.418 2.418 0 0 0 2.418-2.418v-8.317l-8.463-8.463-7.181 7.181-.071.072Zm-19.347 5.442v4.085a6.045 6.045 0 0 0 6.046 6.045h26.598a6.044 6.044 0 0 0 6.045-6.045v-7.108l1.356-1.355-1.282-1.283-.074-.073v-17.989h-38.689v23.43l-.146.146.146.147Z" clip-rule="evenodd"/></g><path stroke="#C9C9C9" stroke-width="2.418" d="M600.709 656.704c-31.384 0-56.825-25.441-56.825-56.824 0-31.384 25.441-56.825 56.825-56.825 31.383 0 56.824 25.441 56.824 56.825 0 31.383-25.441 56.824-56.824 56.824Z"/></g><defs><linearGradient id="a" x1="554.061" x2="-.48" y1=".083" y2=".087" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="b" x1="796.912" x2="404.507" y1="599.963" y2="599.965" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="c" x1="600.792" x2="600.794" y1="403.677" y2="796.082" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="d" x1="404.85" x2="796.972" y1="403.903" y2="796.02" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><clipPath id="e"><path fill="#fff" d="M581.364 580.535h38.689v38.689h-38.689z"/></clipPath></defs></svg>
\ No newline at end of file
public/robots.txt new
+14
@@ -0,0 +1,14 @@
1 +User-agent: Googlebot
2 +Allow: /
3 +
4 +User-agent: Bingbot
5 +Allow: /
6 +
7 +User-agent: Twitterbot
8 +Allow: /
9 +
10 +User-agent: facebookexternalhit
11 +Allow: /
12 +
13 +User-agent: *
14 +Allow: /
src/App.css new
+42
@@ -0,0 +1,42 @@
1 +#root {
2 + max-width: 1280px;
3 + margin: 0 auto;
4 + padding: 2rem;
5 + text-align: center;
6 +}
7 +
8 +.logo {
9 + height: 6em;
10 + padding: 1.5em;
11 + will-change: filter;
12 + transition: filter 300ms;
13 +}
14 +.logo:hover {
15 + filter: drop-shadow(0 0 2em #646cffaa);
16 +}
17 +.logo.react:hover {
18 + filter: drop-shadow(0 0 2em #61dafbaa);
19 +}
20 +
21 +@keyframes logo-spin {
22 + from {
23 + transform: rotate(0deg);
24 + }
25 + to {
26 + transform: rotate(360deg);
27 + }
28 +}
29 +
30 +@media (prefers-reduced-motion: no-preference) {
31 + a:nth-of-type(2) .logo {
32 + animation: logo-spin infinite 20s linear;
33 + }
34 +}
35 +
36 +.card {
37 + padding: 2em;
38 +}
39 +
40 +.read-the-docs {
41 + color: #888;
42 +}
src/App.tsx new
+27
@@ -0,0 +1,27 @@
1 +import { Toaster } from "@/components/ui/toaster";
2 +import { Toaster as Sonner } from "@/components/ui/sonner";
3 +import { TooltipProvider } from "@/components/ui/tooltip";
4 +import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
5 +import { BrowserRouter, Routes, Route } from "react-router-dom";
6 +import Index from "./pages/Index";
7 +import NotFound from "./pages/NotFound";
8 +
9 +const queryClient = new QueryClient();
10 +
11 +const App = () => (
12 + <QueryClientProvider client={queryClient}>
13 + <TooltipProvider>
14 + <Toaster />
15 + <Sonner />
16 + <BrowserRouter>
17 + <Routes>
18 + <Route path="/" element={<Index />} />
19 + {/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */}
20 + <Route path="*" element={<NotFound />} />
21 + </Routes>
22 + </BrowserRouter>
23 + </TooltipProvider>
24 + </QueryClientProvider>
25 +);
26 +
27 +export default App;
src/components/NavLink.tsx new
+28
@@ -0,0 +1,28 @@
1 +import { NavLink as RouterNavLink, NavLinkProps } from "react-router-dom";
2 +import { forwardRef } from "react";
3 +import { cn } from "@/lib/utils";
4 +
5 +interface NavLinkCompatProps extends Omit<NavLinkProps, "className"> {
6 + className?: string;
7 + activeClassName?: string;
8 + pendingClassName?: string;
9 +}
10 +
11 +const NavLink = forwardRef<HTMLAnchorElement, NavLinkCompatProps>(
12 + ({ className, activeClassName, pendingClassName, to, ...props }, ref) => {
13 + return (
14 + <RouterNavLink
15 + ref={ref}
16 + to={to}
17 + className={({ isActive, isPending }) =>
18 + cn(className, isActive && activeClassName, isPending && pendingClassName)
19 + }
20 + {...props}
21 + />
22 + );
23 + },
24 +);
25 +
26 +NavLink.displayName = "NavLink";
27 +
28 +export { NavLink };
src/components/ui/accordion.tsx new
+52
@@ -0,0 +1,52 @@
1 +import * as React from "react";
2 +import * as AccordionPrimitive from "@radix-ui/react-accordion";
3 +import { ChevronDown } from "lucide-react";
4 +
5 +import { cn } from "@/lib/utils";
6 +
7 +const Accordion = AccordionPrimitive.Root;
8 +
9 +const AccordionItem = React.forwardRef<
10 + React.ElementRef<typeof AccordionPrimitive.Item>,
11 + React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
12 +>(({ className, ...props }, ref) => (
13 + <AccordionPrimitive.Item ref={ref} className={cn("border-b", className)} {...props} />
14 +));
15 +AccordionItem.displayName = "AccordionItem";
16 +
17 +const AccordionTrigger = React.forwardRef<
18 + React.ElementRef<typeof AccordionPrimitive.Trigger>,
19 + React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>
20 +>(({ className, children, ...props }, ref) => (
21 + <AccordionPrimitive.Header className="flex">
22 + <AccordionPrimitive.Trigger
23 + ref={ref}
24 + className={cn(
25 + "flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",
26 + className,
27 + )}
28 + {...props}
29 + >
30 + {children}
31 + <ChevronDown className="h-4 w-4 shrink-0 transition-transform duration-200" />
32 + </AccordionPrimitive.Trigger>
33 + </AccordionPrimitive.Header>
34 +));
35 +AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName;
36 +
37 +const AccordionContent = React.forwardRef<
38 + React.ElementRef<typeof AccordionPrimitive.Content>,
39 + React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
40 +>(({ className, children, ...props }, ref) => (
41 + <AccordionPrimitive.Content
42 + ref={ref}
43 + className="overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
44 + {...props}
45 + >
46 + <div className={cn("pb-4 pt-0", className)}>{children}</div>
47 + </AccordionPrimitive.Content>
48 +));
49 +
50 +AccordionContent.displayName = AccordionPrimitive.Content.displayName;
51 +
52 +export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };
src/components/ui/alert-dialog.tsx new
+104
@@ -0,0 +1,104 @@
1 +import * as React from "react";
2 +import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
3 +
4 +import { cn } from "@/lib/utils";
5 +import { buttonVariants } from "@/components/ui/button";
6 +
7 +const AlertDialog = AlertDialogPrimitive.Root;
8 +
9 +const AlertDialogTrigger = AlertDialogPrimitive.Trigger;
10 +
11 +const AlertDialogPortal = AlertDialogPrimitive.Portal;
12 +
13 +const AlertDialogOverlay = React.forwardRef<
14 + React.ElementRef<typeof AlertDialogPrimitive.Overlay>,
15 + React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Overlay>
16 +>(({ className, ...props }, ref) => (
17 + <AlertDialogPrimitive.Overlay
18 + className={cn(
19 + "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
20 + className,
21 + )}
22 + {...props}
23 + ref={ref}
24 + />
25 +));
26 +AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;
27 +
28 +const AlertDialogContent = React.forwardRef<
29 + React.ElementRef<typeof AlertDialogPrimitive.Content>,
30 + React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Content>
31 +>(({ className, ...props }, ref) => (
32 + <AlertDialogPortal>
33 + <AlertDialogOverlay />
34 + <AlertDialogPrimitive.Content
35 + ref={ref}
36 + className={cn(
37 + "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
38 + className,
39 + )}
40 + {...props}
41 + />
42 + </AlertDialogPortal>
43 +));
44 +AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;
45 +
46 +const AlertDialogHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
47 + <div className={cn("flex flex-col space-y-2 text-center sm:text-left", className)} {...props} />
48 +);
49 +AlertDialogHeader.displayName = "AlertDialogHeader";
50 +
51 +const AlertDialogFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
52 + <div className={cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className)} {...props} />
53 +);
54 +AlertDialogFooter.displayName = "AlertDialogFooter";
55 +
56 +const AlertDialogTitle = React.forwardRef<
57 + React.ElementRef<typeof AlertDialogPrimitive.Title>,
58 + React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Title>
59 +>(({ className, ...props }, ref) => (
60 + <AlertDialogPrimitive.Title ref={ref} className={cn("text-lg font-semibold", className)} {...props} />
61 +));
62 +AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
63 +
64 +const AlertDialogDescription = React.forwardRef<
65 + React.ElementRef<typeof AlertDialogPrimitive.Description>,
66 + React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Description>
67 +>(({ className, ...props }, ref) => (
68 + <AlertDialogPrimitive.Description ref={ref} className={cn("text-sm text-muted-foreground", className)} {...props} />
69 +));
70 +AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName;
71 +
72 +const AlertDialogAction = React.forwardRef<
73 + React.ElementRef<typeof AlertDialogPrimitive.Action>,
74 + React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Action>
75 +>(({ className, ...props }, ref) => (
76 + <AlertDialogPrimitive.Action ref={ref} className={cn(buttonVariants(), className)} {...props} />
77 +));
78 +AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;
79 +
80 +const AlertDialogCancel = React.forwardRef<
81 + React.ElementRef<typeof AlertDialogPrimitive.Cancel>,
82 + React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Cancel>
83 +>(({ className, ...props }, ref) => (
84 + <AlertDialogPrimitive.Cancel
85 + ref={ref}
86 + className={cn(buttonVariants({ variant: "outline" }), "mt-2 sm:mt-0", className)}
87 + {...props}
88 + />
89 +));
90 +AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;
91 +
92 +export {
93 + AlertDialog,
94 + AlertDialogPortal,
95 + AlertDialogOverlay,
96 + AlertDialogTrigger,
97 + AlertDialogContent,
98 + AlertDialogHeader,
99 + AlertDialogFooter,
100 + AlertDialogTitle,
101 + AlertDialogDescription,
102 + AlertDialogAction,
103 + AlertDialogCancel,
104 +};
src/components/ui/alert.tsx new
+43
@@ -0,0 +1,43 @@
1 +import * as React from "react";
2 +import { cva, type VariantProps } from "class-variance-authority";
3 +
4 +import { cn } from "@/lib/utils";
5 +
6 +const alertVariants = cva(
7 + "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",
8 + {
9 + variants: {
10 + variant: {
11 + default: "bg-background text-foreground",
12 + destructive: "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive",
13 + },
14 + },
15 + defaultVariants: {
16 + variant: "default",
17 + },
18 + },
19 +);
20 +
21 +const Alert = React.forwardRef<
22 + HTMLDivElement,
23 + React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>
24 +>(({ className, variant, ...props }, ref) => (
25 + <div ref={ref} role="alert" className={cn(alertVariants({ variant }), className)} {...props} />
26 +));
27 +Alert.displayName = "Alert";
28 +
29 +const AlertTitle = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLHeadingElement>>(
30 + ({ className, ...props }, ref) => (
31 + <h5 ref={ref} className={cn("mb-1 font-medium leading-none tracking-tight", className)} {...props} />
32 + ),
33 +);
34 +AlertTitle.displayName = "AlertTitle";
35 +
36 +const AlertDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
37 + ({ className, ...props }, ref) => (
38 + <div ref={ref} className={cn("text-sm [&_p]:leading-relaxed", className)} {...props} />
39 + ),
40 +);
41 +AlertDescription.displayName = "AlertDescription";
42 +
43 +export { Alert, AlertTitle, AlertDescription };
src/components/ui/aspect-ratio.tsx new
+5
@@ -0,0 +1,5 @@
1 +import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio";
2 +
3 +const AspectRatio = AspectRatioPrimitive.Root;
4 +
5 +export { AspectRatio };
src/components/ui/avatar.tsx new
+38
@@ -0,0 +1,38 @@
1 +import * as React from "react";
2 +import * as AvatarPrimitive from "@radix-ui/react-avatar";
3 +
4 +import { cn } from "@/lib/utils";
5 +
6 +const Avatar = React.forwardRef<
7 + React.ElementRef<typeof AvatarPrimitive.Root>,
8 + React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
9 +>(({ className, ...props }, ref) => (
10 + <AvatarPrimitive.Root
11 + ref={ref}
12 + className={cn("relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full", className)}
13 + {...props}
14 + />
15 +));
16 +Avatar.displayName = AvatarPrimitive.Root.displayName;
17 +
18 +const AvatarImage = React.forwardRef<
19 + React.ElementRef<typeof AvatarPrimitive.Image>,
20 + React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
21 +>(({ className, ...props }, ref) => (
22 + <AvatarPrimitive.Image ref={ref} className={cn("aspect-square h-full w-full", className)} {...props} />
23 +));
24 +AvatarImage.displayName = AvatarPrimitive.Image.displayName;
25 +
26 +const AvatarFallback = React.forwardRef<
27 + React.ElementRef<typeof AvatarPrimitive.Fallback>,
28 + React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
29 +>(({ className, ...props }, ref) => (
30 + <AvatarPrimitive.Fallback
31 + ref={ref}
32 + className={cn("flex h-full w-full items-center justify-center rounded-full bg-muted", className)}
33 + {...props}
34 + />
35 +));
36 +AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
37 +
38 +export { Avatar, AvatarImage, AvatarFallback };
src/components/ui/badge.tsx new
+29
@@ -0,0 +1,29 @@
1 +import * as React from "react";
2 +import { cva, type VariantProps } from "class-variance-authority";
3 +
4 +import { cn } from "@/lib/utils";
5 +
6 +const badgeVariants = cva(
7 + "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",
8 + {
9 + variants: {
10 + variant: {
11 + default: "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
12 + secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
13 + destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
14 + outline: "text-foreground",
15 + },
16 + },
17 + defaultVariants: {
18 + variant: "default",
19 + },
20 + },
21 +);
22 +
23 +export interface BadgeProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {}
24 +
25 +function Badge({ className, variant, ...props }: BadgeProps) {
26 + return <div className={cn(badgeVariants({ variant }), className)} {...props} />;
27 +}
28 +
29 +export { Badge, badgeVariants };
src/components/ui/breadcrumb.tsx new
+90
@@ -0,0 +1,90 @@
1 +import * as React from "react";
2 +import { Slot } from "@radix-ui/react-slot";
3 +import { ChevronRight, MoreHorizontal } from "lucide-react";
4 +
5 +import { cn } from "@/lib/utils";
6 +
7 +const Breadcrumb = React.forwardRef<
8 + HTMLElement,
9 + React.ComponentPropsWithoutRef<"nav"> & {
10 + separator?: React.ReactNode;
11 + }
12 +>(({ ...props }, ref) => <nav ref={ref} aria-label="breadcrumb" {...props} />);
13 +Breadcrumb.displayName = "Breadcrumb";
14 +
15 +const BreadcrumbList = React.forwardRef<HTMLOListElement, React.ComponentPropsWithoutRef<"ol">>(
16 + ({ className, ...props }, ref) => (
17 + <ol
18 + ref={ref}
19 + className={cn(
20 + "flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5",
21 + className,
22 + )}
23 + {...props}
24 + />
25 + ),
26 +);
27 +BreadcrumbList.displayName = "BreadcrumbList";
28 +
29 +const BreadcrumbItem = React.forwardRef<HTMLLIElement, React.ComponentPropsWithoutRef<"li">>(
30 + ({ className, ...props }, ref) => (
31 + <li ref={ref} className={cn("inline-flex items-center gap-1.5", className)} {...props} />
32 + ),
33 +);
34 +BreadcrumbItem.displayName = "BreadcrumbItem";
35 +
36 +const BreadcrumbLink = React.forwardRef<
37 + HTMLAnchorElement,
38 + React.ComponentPropsWithoutRef<"a"> & {
39 + asChild?: boolean;
40 + }
41 +>(({ asChild, className, ...props }, ref) => {
42 + const Comp = asChild ? Slot : "a";
43 +
44 + return <Comp ref={ref} className={cn("transition-colors hover:text-foreground", className)} {...props} />;
45 +});
46 +BreadcrumbLink.displayName = "BreadcrumbLink";
47 +
48 +const BreadcrumbPage = React.forwardRef<HTMLSpanElement, React.ComponentPropsWithoutRef<"span">>(
49 + ({ className, ...props }, ref) => (
50 + <span
51 + ref={ref}
52 + role="link"
53 + aria-disabled="true"
54 + aria-current="page"
55 + className={cn("font-normal text-foreground", className)}
56 + {...props}
57 + />
58 + ),
59 +);
60 +BreadcrumbPage.displayName = "BreadcrumbPage";
61 +
62 +const BreadcrumbSeparator = ({ children, className, ...props }: React.ComponentProps<"li">) => (
63 + <li role="presentation" aria-hidden="true" className={cn("[&>svg]:size-3.5", className)} {...props}>
64 + {children ?? <ChevronRight />}
65 + </li>
66 +);
67 +BreadcrumbSeparator.displayName = "BreadcrumbSeparator";
68 +
69 +const BreadcrumbEllipsis = ({ className, ...props }: React.ComponentProps<"span">) => (
70 + <span
71 + role="presentation"
72 + aria-hidden="true"
73 + className={cn("flex h-9 w-9 items-center justify-center", className)}
74 + {...props}
75 + >
76 + <MoreHorizontal className="h-4 w-4" />
77 + <span className="sr-only">More</span>
78 + </span>
79 +);
80 +BreadcrumbEllipsis.displayName = "BreadcrumbElipssis";
81 +
82 +export {
83 + Breadcrumb,
84 + BreadcrumbList,
85 + BreadcrumbItem,
86 + BreadcrumbLink,
87 + BreadcrumbPage,
88 + BreadcrumbSeparator,
89 + BreadcrumbEllipsis,
90 +};
src/components/ui/button.tsx new
+47
@@ -0,0 +1,47 @@
1 +import * as React from "react";
2 +import { Slot } from "@radix-ui/react-slot";
3 +import { cva, type VariantProps } from "class-variance-authority";
4 +
5 +import { cn } from "@/lib/utils";
6 +
7 +const buttonVariants = cva(
8 + "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",
9 + {
10 + variants: {
11 + variant: {
12 + default: "bg-primary text-primary-foreground hover:bg-primary/90",
13 + destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
14 + outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
15 + secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
16 + ghost: "hover:bg-accent hover:text-accent-foreground",
17 + link: "text-primary underline-offset-4 hover:underline",
18 + },
19 + size: {
20 + default: "h-10 px-4 py-2",
21 + sm: "h-9 rounded-md px-3",
22 + lg: "h-11 rounded-md px-8",
23 + icon: "h-10 w-10",
24 + },
25 + },
26 + defaultVariants: {
27 + variant: "default",
28 + size: "default",
29 + },
30 + },
31 +);
32 +
33 +export interface ButtonProps
34 + extends React.ButtonHTMLAttributes<HTMLButtonElement>,
35 + VariantProps<typeof buttonVariants> {
36 + asChild?: boolean;
37 +}
38 +
39 +const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
40 + ({ className, variant, size, asChild = false, ...props }, ref) => {
41 + const Comp = asChild ? Slot : "button";
42 + return <Comp className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...props} />;
43 + },
44 +);
45 +Button.displayName = "Button";
46 +
47 +export { Button, buttonVariants };
src/components/ui/calendar.tsx new
+54
@@ -0,0 +1,54 @@
1 +import * as React from "react";
2 +import { ChevronLeft, ChevronRight } from "lucide-react";
3 +import { DayPicker } from "react-day-picker";
4 +
5 +import { cn } from "@/lib/utils";
6 +import { buttonVariants } from "@/components/ui/button";
7 +
8 +export type CalendarProps = React.ComponentProps<typeof DayPicker>;
9 +
10 +function Calendar({ className, classNames, showOutsideDays = true, ...props }: CalendarProps) {
11 + return (
12 + <DayPicker
13 + showOutsideDays={showOutsideDays}
14 + className={cn("p-3", className)}
15 + classNames={{
16 + months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0",
17 + month: "space-y-4",
18 + caption: "flex justify-center pt-1 relative items-center",
19 + caption_label: "text-sm font-medium",
20 + nav: "space-x-1 flex items-center",
21 + nav_button: cn(
22 + buttonVariants({ variant: "outline" }),
23 + "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100",
24 + ),
25 + nav_button_previous: "absolute left-1",
26 + nav_button_next: "absolute right-1",
27 + table: "w-full border-collapse space-y-1",
28 + head_row: "flex",
29 + head_cell: "text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]",
30 + row: "flex w-full mt-2",
31 + cell: "h-9 w-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20",
32 + day: cn(buttonVariants({ variant: "ghost" }), "h-9 w-9 p-0 font-normal aria-selected:opacity-100"),
33 + day_range_end: "day-range-end",
34 + day_selected:
35 + "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
36 + day_today: "bg-accent text-accent-foreground",
37 + day_outside:
38 + "day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30",
39 + day_disabled: "text-muted-foreground opacity-50",
40 + day_range_middle: "aria-selected:bg-accent aria-selected:text-accent-foreground",
41 + day_hidden: "invisible",
42 + ...classNames,
43 + }}
44 + components={{
45 + IconLeft: ({ ..._props }) => <ChevronLeft className="h-4 w-4" />,
46 + IconRight: ({ ..._props }) => <ChevronRight className="h-4 w-4" />,
47 + }}
48 + {...props}
49 + />
50 + );
51 +}
52 +Calendar.displayName = "Calendar";
53 +
54 +export { Calendar };
src/components/ui/card.tsx new
+43
@@ -0,0 +1,43 @@
1 +import * as React from "react";
2 +
3 +import { cn } from "@/lib/utils";
4 +
5 +const Card = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(({ className, ...props }, ref) => (
6 + <div ref={ref} className={cn("rounded-lg border bg-card text-card-foreground shadow-sm", className)} {...props} />
7 +));
8 +Card.displayName = "Card";
9 +
10 +const CardHeader = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
11 + ({ className, ...props }, ref) => (
12 + <div ref={ref} className={cn("flex flex-col space-y-1.5 p-6", className)} {...props} />
13 + ),
14 +);
15 +CardHeader.displayName = "CardHeader";
16 +
17 +const CardTitle = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLHeadingElement>>(
18 + ({ className, ...props }, ref) => (
19 + <h3 ref={ref} className={cn("text-2xl font-semibold leading-none tracking-tight", className)} {...props} />
20 + ),
21 +);
22 +CardTitle.displayName = "CardTitle";
23 +
24 +const CardDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
25 + ({ className, ...props }, ref) => (
26 + <p ref={ref} className={cn("text-sm text-muted-foreground", className)} {...props} />
27 + ),
28 +);
29 +CardDescription.displayName = "CardDescription";
30 +
31 +const CardContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
32 + ({ className, ...props }, ref) => <div ref={ref} className={cn("p-6 pt-0", className)} {...props} />,
33 +);
34 +CardContent.displayName = "CardContent";
35 +
36 +const CardFooter = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
37 + ({ className, ...props }, ref) => (
38 + <div ref={ref} className={cn("flex items-center p-6 pt-0", className)} {...props} />
39 + ),
40 +);
41 +CardFooter.displayName = "CardFooter";
42 +
43 +export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent };
src/components/ui/carousel.tsx new
+224
@@ -0,0 +1,224 @@
1 +import * as React from "react";
2 +import useEmblaCarousel, { type UseEmblaCarouselType } from "embla-carousel-react";
3 +import { ArrowLeft, ArrowRight } from "lucide-react";
4 +
5 +import { cn } from "@/lib/utils";
6 +import { Button } from "@/components/ui/button";
7 +
8 +type CarouselApi = UseEmblaCarouselType[1];
9 +type UseCarouselParameters = Parameters<typeof useEmblaCarousel>;
10 +type CarouselOptions = UseCarouselParameters[0];
11 +type CarouselPlugin = UseCarouselParameters[1];
12 +
13 +type CarouselProps = {
14 + opts?: CarouselOptions;
15 + plugins?: CarouselPlugin;
16 + orientation?: "horizontal" | "vertical";
17 + setApi?: (api: CarouselApi) => void;
18 +};
19 +
20 +type CarouselContextProps = {
21 + carouselRef: ReturnType<typeof useEmblaCarousel>[0];
22 + api: ReturnType<typeof useEmblaCarousel>[1];
23 + scrollPrev: () => void;
24 + scrollNext: () => void;
25 + canScrollPrev: boolean;
26 + canScrollNext: boolean;
27 +} & CarouselProps;
28 +
29 +const CarouselContext = React.createContext<CarouselContextProps | null>(null);
30 +
31 +function useCarousel() {
32 + const context = React.useContext(CarouselContext);
33 +
34 + if (!context) {
35 + throw new Error("useCarousel must be used within a <Carousel />");
36 + }
37 +
38 + return context;
39 +}
40 +
41 +const Carousel = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement> & CarouselProps>(
42 + ({ orientation = "horizontal", opts, setApi, plugins, className, children, ...props }, ref) => {
43 + const [carouselRef, api] = useEmblaCarousel(
44 + {
45 + ...opts,
46 + axis: orientation === "horizontal" ? "x" : "y",
47 + },
48 + plugins,
49 + );
50 + const [canScrollPrev, setCanScrollPrev] = React.useState(false);
51 + const [canScrollNext, setCanScrollNext] = React.useState(false);
52 +
53 + const onSelect = React.useCallback((api: CarouselApi) => {
54 + if (!api) {
55 + return;
56 + }
57 +
58 + setCanScrollPrev(api.canScrollPrev());
59 + setCanScrollNext(api.canScrollNext());
60 + }, []);
61 +
62 + const scrollPrev = React.useCallback(() => {
63 + api?.scrollPrev();
64 + }, [api]);
65 +
66 + const scrollNext = React.useCallback(() => {
67 + api?.scrollNext();
68 + }, [api]);
69 +
70 + const handleKeyDown = React.useCallback(
71 + (event: React.KeyboardEvent<HTMLDivElement>) => {
72 + if (event.key === "ArrowLeft") {
73 + event.preventDefault();
74 + scrollPrev();
75 + } else if (event.key === "ArrowRight") {
76 + event.preventDefault();
77 + scrollNext();
78 + }
79 + },
80 + [scrollPrev, scrollNext],
81 + );
82 +
83 + React.useEffect(() => {
84 + if (!api || !setApi) {
85 + return;
86 + }
87 +
88 + setApi(api);
89 + }, [api, setApi]);
90 +
91 + React.useEffect(() => {
92 + if (!api) {
93 + return;
94 + }
95 +
96 + onSelect(api);
97 + api.on("reInit", onSelect);
98 + api.on("select", onSelect);
99 +
100 + return () => {
101 + api?.off("select", onSelect);
102 + };
103 + }, [api, onSelect]);
104 +
105 + return (
106 + <CarouselContext.Provider
107 + value={{
108 + carouselRef,
109 + api: api,
110 + opts,
111 + orientation: orientation || (opts?.axis === "y" ? "vertical" : "horizontal"),
112 + scrollPrev,
113 + scrollNext,
114 + canScrollPrev,
115 + canScrollNext,
116 + }}
117 + >
118 + <div
119 + ref={ref}
120 + onKeyDownCapture={handleKeyDown}
121 + className={cn("relative", className)}
122 + role="region"
123 + aria-roledescription="carousel"
124 + {...props}
125 + >
126 + {children}
127 + </div>
128 + </CarouselContext.Provider>
129 + );
130 + },
131 +);
132 +Carousel.displayName = "Carousel";
133 +
134 +const CarouselContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
135 + ({ className, ...props }, ref) => {
136 + const { carouselRef, orientation } = useCarousel();
137 +
138 + return (
139 + <div ref={carouselRef} className="overflow-hidden">
140 + <div
141 + ref={ref}
142 + className={cn("flex", orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col", className)}
143 + {...props}
144 + />
145 + </div>
146 + );
147 + },
148 +);
149 +CarouselContent.displayName = "CarouselContent";
150 +
151 +const CarouselItem = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
152 + ({ className, ...props }, ref) => {
153 + const { orientation } = useCarousel();
154 +
155 + return (
156 + <div
157 + ref={ref}
158 + role="group"
159 + aria-roledescription="slide"
160 + className={cn("min-w-0 shrink-0 grow-0 basis-full", orientation === "horizontal" ? "pl-4" : "pt-4", className)}
161 + {...props}
162 + />
163 + );
164 + },
165 +);
166 +CarouselItem.displayName = "CarouselItem";
167 +
168 +const CarouselPrevious = React.forwardRef<HTMLButtonElement, React.ComponentProps<typeof Button>>(
169 + ({ className, variant = "outline", size = "icon", ...props }, ref) => {
170 + const { orientation, scrollPrev, canScrollPrev } = useCarousel();
171 +
172 + return (
173 + <Button
174 + ref={ref}
175 + variant={variant}
176 + size={size}
177 + className={cn(
178 + "absolute h-8 w-8 rounded-full",
179 + orientation === "horizontal"
180 + ? "-left-12 top-1/2 -translate-y-1/2"
181 + : "-top-12 left-1/2 -translate-x-1/2 rotate-90",
182 + className,
183 + )}
184 + disabled={!canScrollPrev}
185 + onClick={scrollPrev}
186 + {...props}
187 + >
188 + <ArrowLeft className="h-4 w-4" />
189 + <span className="sr-only">Previous slide</span>
190 + </Button>
191 + );
192 + },
193 +);
194 +CarouselPrevious.displayName = "CarouselPrevious";
195 +
196 +const CarouselNext = React.forwardRef<HTMLButtonElement, React.ComponentProps<typeof Button>>(
197 + ({ className, variant = "outline", size = "icon", ...props }, ref) => {
198 + const { orientation, scrollNext, canScrollNext } = useCarousel();
199 +
200 + return (
201 + <Button
202 + ref={ref}
203 + variant={variant}
204 + size={size}
205 + className={cn(
206 + "absolute h-8 w-8 rounded-full",
207 + orientation === "horizontal"
208 + ? "-right-12 top-1/2 -translate-y-1/2"
209 + : "-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
210 + className,
211 + )}
212 + disabled={!canScrollNext}
213 + onClick={scrollNext}
214 + {...props}
215 + >
216 + <ArrowRight className="h-4 w-4" />
217 + <span className="sr-only">Next slide</span>
218 + </Button>
219 + );
220 + },
221 +);
222 +CarouselNext.displayName = "CarouselNext";
223 +
224 +export { type CarouselApi, Carousel, CarouselContent, CarouselItem, CarouselPrevious, CarouselNext };
src/components/ui/chart.tsx new
+303
@@ -0,0 +1,303 @@
1 +import * as React from "react";
2 +import * as RechartsPrimitive from "recharts";
3 +
4 +import { cn } from "@/lib/utils";
5 +
6 +// Format: { THEME_NAME: CSS_SELECTOR }
7 +const THEMES = { light: "", dark: ".dark" } as const;
8 +
9 +export type ChartConfig = {
10 + [k in string]: {
11 + label?: React.ReactNode;
12 + icon?: React.ComponentType;
13 + } & ({ color?: string; theme?: never } | { color?: never; theme: Record<keyof typeof THEMES, string> });
14 +};
15 +
16 +type ChartContextProps = {
17 + config: ChartConfig;
18 +};
19 +
20 +const ChartContext = React.createContext<ChartContextProps | null>(null);
21 +
22 +function useChart() {
23 + const context = React.useContext(ChartContext);
24 +
25 + if (!context) {
26 + throw new Error("useChart must be used within a <ChartContainer />");
27 + }
28 +
29 + return context;
30 +}
31 +
32 +const ChartContainer = React.forwardRef<
33 + HTMLDivElement,
34 + React.ComponentProps<"div"> & {
35 + config: ChartConfig;
36 + children: React.ComponentProps<typeof RechartsPrimitive.ResponsiveContainer>["children"];
37 + }
38 +>(({ id, className, children, config, ...props }, ref) => {
39 + const uniqueId = React.useId();
40 + const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`;
41 +
42 + return (
43 + <ChartContext.Provider value={{ config }}>
44 + <div
45 + data-chart={chartId}
46 + ref={ref}
47 + className={cn(
48 + "flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-none [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-sector]:outline-none [&_.recharts-surface]:outline-none",
49 + className,
50 + )}
51 + {...props}
52 + >
53 + <ChartStyle id={chartId} config={config} />
54 + <RechartsPrimitive.ResponsiveContainer>{children}</RechartsPrimitive.ResponsiveContainer>
55 + </div>
56 + </ChartContext.Provider>
57 + );
58 +});
59 +ChartContainer.displayName = "Chart";
60 +
61 +const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {
62 + const colorConfig = Object.entries(config).filter(([_, config]) => config.theme || config.color);
63 +
64 + if (!colorConfig.length) {
65 + return null;
66 + }
67 +
68 + return (
69 + <style
70 + dangerouslySetInnerHTML={{
71 + __html: Object.entries(THEMES)
72 + .map(
73 + ([theme, prefix]) => `
74 +${prefix} [data-chart=${id}] {
75 +${colorConfig
76 + .map(([key, itemConfig]) => {
77 + const color = itemConfig.theme?.[theme as keyof typeof itemConfig.theme] || itemConfig.color;
78 + return color ? ` --color-${key}: ${color};` : null;
79 + })
80 + .join("\n")}
81 +}
82 +`,
83 + )
84 + .join("\n"),
85 + }}
86 + />
87 + );
88 +};
89 +
90 +const ChartTooltip = RechartsPrimitive.Tooltip;
91 +
92 +const ChartTooltipContent = React.forwardRef<
93 + HTMLDivElement,
94 + React.ComponentProps<typeof RechartsPrimitive.Tooltip> &
95 + React.ComponentProps<"div"> & {
96 + hideLabel?: boolean;
97 + hideIndicator?: boolean;
98 + indicator?: "line" | "dot" | "dashed";
99 + nameKey?: string;
100 + labelKey?: string;
101 + }
102 +>(
103 + (
104 + {
105 + active,
106 + payload,
107 + className,
108 + indicator = "dot",
109 + hideLabel = false,
110 + hideIndicator = false,
111 + label,
112 + labelFormatter,
113 + labelClassName,
114 + formatter,
115 + color,
116 + nameKey,
117 + labelKey,
118 + },
119 + ref,
120 + ) => {
121 + const { config } = useChart();
122 +
123 + const tooltipLabel = React.useMemo(() => {
124 + if (hideLabel || !payload?.length) {
125 + return null;
126 + }
127 +
128 + const [item] = payload;
129 + const key = `${labelKey || item.dataKey || item.name || "value"}`;
130 + const itemConfig = getPayloadConfigFromPayload(config, item, key);
131 + const value =
132 + !labelKey && typeof label === "string"
133 + ? config[label as keyof typeof config]?.label || label
134 + : itemConfig?.label;
135 +
136 + if (labelFormatter) {
137 + return <div className={cn("font-medium", labelClassName)}>{labelFormatter(value, payload)}</div>;
138 + }
139 +
140 + if (!value) {
141 + return null;
142 + }
143 +
144 + return <div className={cn("font-medium", labelClassName)}>{value}</div>;
145 + }, [label, labelFormatter, payload, hideLabel, labelClassName, config, labelKey]);
146 +
147 + if (!active || !payload?.length) {
148 + return null;
149 + }
150 +
151 + const nestLabel = payload.length === 1 && indicator !== "dot";
152 +
153 + return (
154 + <div
155 + ref={ref}
156 + className={cn(
157 + "grid min-w-[8rem] items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl",
158 + className,
159 + )}
160 + >
161 + {!nestLabel ? tooltipLabel : null}
162 + <div className="grid gap-1.5">
163 + {payload.map((item, index) => {
164 + const key = `${nameKey || item.name || item.dataKey || "value"}`;
165 + const itemConfig = getPayloadConfigFromPayload(config, item, key);
166 + const indicatorColor = color || item.payload.fill || item.color;
167 +
168 + return (
169 + <div
170 + key={item.dataKey}
171 + className={cn(
172 + "flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground",
173 + indicator === "dot" && "items-center",
174 + )}
175 + >
176 + {formatter && item?.value !== undefined && item.name ? (
177 + formatter(item.value, item.name, item, index, item.payload)
178 + ) : (
179 + <>
180 + {itemConfig?.icon ? (
181 + <itemConfig.icon />
182 + ) : (
183 + !hideIndicator && (
184 + <div
185 + className={cn("shrink-0 rounded-[2px] border-[--color-border] bg-[--color-bg]", {
186 + "h-2.5 w-2.5": indicator === "dot",
187 + "w-1": indicator === "line",
188 + "w-0 border-[1.5px] border-dashed bg-transparent": indicator === "dashed",
189 + "my-0.5": nestLabel && indicator === "dashed",
190 + })}
191 + style={
192 + {
193 + "--color-bg": indicatorColor,
194 + "--color-border": indicatorColor,
195 + } as React.CSSProperties
196 + }
197 + />
198 + )
199 + )}
200 + <div
201 + className={cn(
202 + "flex flex-1 justify-between leading-none",
203 + nestLabel ? "items-end" : "items-center",
204 + )}
205 + >
206 + <div className="grid gap-1.5">
207 + {nestLabel ? tooltipLabel : null}
208 + <span className="text-muted-foreground">{itemConfig?.label || item.name}</span>
209 + </div>
210 + {item.value && (
211 + <span className="font-mono font-medium tabular-nums text-foreground">
212 + {item.value.toLocaleString()}
213 + </span>
214 + )}
215 + </div>
216 + </>
217 + )}
218 + </div>
219 + );
220 + })}
221 + </div>
222 + </div>
223 + );
224 + },
225 +);
226 +ChartTooltipContent.displayName = "ChartTooltip";
227 +
228 +const ChartLegend = RechartsPrimitive.Legend;
229 +
230 +const ChartLegendContent = React.forwardRef<
231 + HTMLDivElement,
232 + React.ComponentProps<"div"> &
233 + Pick<RechartsPrimitive.LegendProps, "payload" | "verticalAlign"> & {
234 + hideIcon?: boolean;
235 + nameKey?: string;
236 + }
237 +>(({ className, hideIcon = false, payload, verticalAlign = "bottom", nameKey }, ref) => {
238 + const { config } = useChart();
239 +
240 + if (!payload?.length) {
241 + return null;
242 + }
243 +
244 + return (
245 + <div
246 + ref={ref}
247 + className={cn("flex items-center justify-center gap-4", verticalAlign === "top" ? "pb-3" : "pt-3", className)}
248 + >
249 + {payload.map((item) => {
250 + const key = `${nameKey || item.dataKey || "value"}`;
251 + const itemConfig = getPayloadConfigFromPayload(config, item, key);
252 +
253 + return (
254 + <div
255 + key={item.value}
256 + className={cn("flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground")}
257 + >
258 + {itemConfig?.icon && !hideIcon ? (
259 + <itemConfig.icon />
260 + ) : (
261 + <div
262 + className="h-2 w-2 shrink-0 rounded-[2px]"
263 + style={{
264 + backgroundColor: item.color,
265 + }}
266 + />
267 + )}
268 + {itemConfig?.label}
269 + </div>
270 + );
271 + })}
272 + </div>
273 + );
274 +});
275 +ChartLegendContent.displayName = "ChartLegend";
276 +
277 +// Helper to extract item config from a payload.
278 +function getPayloadConfigFromPayload(config: ChartConfig, payload: unknown, key: string) {
279 + if (typeof payload !== "object" || payload === null) {
280 + return undefined;
281 + }
282 +
283 + const payloadPayload =
284 + "payload" in payload && typeof payload.payload === "object" && payload.payload !== null
285 + ? payload.payload
286 + : undefined;
287 +
288 + let configLabelKey: string = key;
289 +
290 + if (key in payload && typeof payload[key as keyof typeof payload] === "string") {
291 + configLabelKey = payload[key as keyof typeof payload] as string;
292 + } else if (
293 + payloadPayload &&
294 + key in payloadPayload &&
295 + typeof payloadPayload[key as keyof typeof payloadPayload] === "string"
296 + ) {
297 + configLabelKey = payloadPayload[key as keyof typeof payloadPayload] as string;
298 + }
299 +
300 + return configLabelKey in config ? config[configLabelKey] : config[key as keyof typeof config];
301 +}
302 +
303 +export { ChartContainer, ChartTooltip, ChartTooltipContent, ChartLegend, ChartLegendContent, ChartStyle };
src/components/ui/checkbox.tsx new
+26
@@ -0,0 +1,26 @@
1 +import * as React from "react";
2 +import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
3 +import { Check } from "lucide-react";
4 +
5 +import { cn } from "@/lib/utils";
6 +
7 +const Checkbox = React.forwardRef<
8 + React.ElementRef<typeof CheckboxPrimitive.Root>,
9 + React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>
10 +>(({ className, ...props }, ref) => (
11 + <CheckboxPrimitive.Root
12 + ref={ref}
13 + className={cn(
14 + "peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
15 + className,
16 + )}
17 + {...props}
18 + >
19 + <CheckboxPrimitive.Indicator className={cn("flex items-center justify-center text-current")}>
20 + <Check className="h-4 w-4" />
21 + </CheckboxPrimitive.Indicator>
22 + </CheckboxPrimitive.Root>
23 +));
24 +Checkbox.displayName = CheckboxPrimitive.Root.displayName;
25 +
26 +export { Checkbox };
src/components/ui/collapsible.tsx new
+9
@@ -0,0 +1,9 @@
1 +import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
2 +
3 +const Collapsible = CollapsiblePrimitive.Root;
4 +
5 +const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger;
6 +
7 +const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent;
8 +
9 +export { Collapsible, CollapsibleTrigger, CollapsibleContent };
src/components/ui/command.tsx new
+132
@@ -0,0 +1,132 @@
1 +import * as React from "react";
2 +import { type DialogProps } from "@radix-ui/react-dialog";
3 +import { Command as CommandPrimitive } from "cmdk";
4 +import { Search } from "lucide-react";
5 +
6 +import { cn } from "@/lib/utils";
7 +import { Dialog, DialogContent } from "@/components/ui/dialog";
8 +
9 +const Command = React.forwardRef<
10 + React.ElementRef<typeof CommandPrimitive>,
11 + React.ComponentPropsWithoutRef<typeof CommandPrimitive>
12 +>(({ className, ...props }, ref) => (
13 + <CommandPrimitive
14 + ref={ref}
15 + className={cn(
16 + "flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
17 + className,
18 + )}
19 + {...props}
20 + />
21 +));
22 +Command.displayName = CommandPrimitive.displayName;
23 +
24 +interface CommandDialogProps extends DialogProps {}
25 +
26 +const CommandDialog = ({ children, ...props }: CommandDialogProps) => {
27 + return (
28 + <Dialog {...props}>
29 + <DialogContent className="overflow-hidden p-0 shadow-lg">
30 + <Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
31 + {children}
32 + </Command>
33 + </DialogContent>
34 + </Dialog>
35 + );
36 +};
37 +
38 +const CommandInput = React.forwardRef<
39 + React.ElementRef<typeof CommandPrimitive.Input>,
40 + React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
41 +>(({ className, ...props }, ref) => (
42 + <div className="flex items-center border-b px-3" cmdk-input-wrapper="">
43 + <Search className="mr-2 h-4 w-4 shrink-0 opacity-50" />
44 + <CommandPrimitive.Input
45 + ref={ref}
46 + className={cn(
47 + "flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
48 + className,
49 + )}
50 + {...props}
51 + />
52 + </div>
53 +));
54 +
55 +CommandInput.displayName = CommandPrimitive.Input.displayName;
56 +
57 +const CommandList = React.forwardRef<
58 + React.ElementRef<typeof CommandPrimitive.List>,
59 + React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
60 +>(({ className, ...props }, ref) => (
61 + <CommandPrimitive.List
62 + ref={ref}
63 + className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)}
64 + {...props}
65 + />
66 +));
67 +
68 +CommandList.displayName = CommandPrimitive.List.displayName;
69 +
70 +const CommandEmpty = React.forwardRef<
71 + React.ElementRef<typeof CommandPrimitive.Empty>,
72 + React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
73 +>((props, ref) => <CommandPrimitive.Empty ref={ref} className="py-6 text-center text-sm" {...props} />);
74 +
75 +CommandEmpty.displayName = CommandPrimitive.Empty.displayName;
76 +
77 +const CommandGroup = React.forwardRef<
78 + React.ElementRef<typeof CommandPrimitive.Group>,
79 + React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>
80 +>(({ className, ...props }, ref) => (
81 + <CommandPrimitive.Group
82 + ref={ref}
83 + className={cn(
84 + "overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
85 + className,
86 + )}
87 + {...props}
88 + />
89 +));
90 +
91 +CommandGroup.displayName = CommandPrimitive.Group.displayName;
92 +
93 +const CommandSeparator = React.forwardRef<
94 + React.ElementRef<typeof CommandPrimitive.Separator>,
95 + React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>
96 +>(({ className, ...props }, ref) => (
97 + <CommandPrimitive.Separator ref={ref} className={cn("-mx-1 h-px bg-border", className)} {...props} />
98 +));
99 +CommandSeparator.displayName = CommandPrimitive.Separator.displayName;
100 +
101 +const CommandItem = React.forwardRef<
102 + React.ElementRef<typeof CommandPrimitive.Item>,
103 + React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
104 +>(({ className, ...props }, ref) => (
105 + <CommandPrimitive.Item
106 + ref={ref}
107 + className={cn(
108 + "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected='true']:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50",
109 + className,
110 + )}
111 + {...props}
112 + />
113 +));
114 +
115 +CommandItem.displayName = CommandPrimitive.Item.displayName;
116 +
117 +const CommandShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {
118 + return <span className={cn("ml-auto text-xs tracking-widest text-muted-foreground", className)} {...props} />;
119 +};
120 +CommandShortcut.displayName = "CommandShortcut";
121 +
122 +export {
123 + Command,
124 + CommandDialog,
125 + CommandInput,
126 + CommandList,
127 + CommandEmpty,
128 + CommandGroup,
129 + CommandItem,
130 + CommandShortcut,
131 + CommandSeparator,
132 +};
src/components/ui/context-menu.tsx new
+178
@@ -0,0 +1,178 @@
1 +import * as React from "react";
2 +import * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
3 +import { Check, ChevronRight, Circle } from "lucide-react";
4 +
5 +import { cn } from "@/lib/utils";
6 +
7 +const ContextMenu = ContextMenuPrimitive.Root;
8 +
9 +const ContextMenuTrigger = ContextMenuPrimitive.Trigger;
10 +
11 +const ContextMenuGroup = ContextMenuPrimitive.Group;
12 +
13 +const ContextMenuPortal = ContextMenuPrimitive.Portal;
14 +
15 +const ContextMenuSub = ContextMenuPrimitive.Sub;
16 +
17 +const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup;
18 +
19 +const ContextMenuSubTrigger = React.forwardRef<
20 + React.ElementRef<typeof ContextMenuPrimitive.SubTrigger>,
21 + React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubTrigger> & {
22 + inset?: boolean;
23 + }
24 +>(({ className, inset, children, ...props }, ref) => (
25 + <ContextMenuPrimitive.SubTrigger
26 + ref={ref}
27 + className={cn(
28 + "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[state=open]:bg-accent data-[state=open]:text-accent-foreground focus:bg-accent focus:text-accent-foreground",
29 + inset && "pl-8",
30 + className,
31 + )}
32 + {...props}
33 + >
34 + {children}
35 + <ChevronRight className="ml-auto h-4 w-4" />
36 + </ContextMenuPrimitive.SubTrigger>
37 +));
38 +ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName;
39 +
40 +const ContextMenuSubContent = React.forwardRef<
41 + React.ElementRef<typeof ContextMenuPrimitive.SubContent>,
42 + React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubContent>
43 +>(({ className, ...props }, ref) => (
44 + <ContextMenuPrimitive.SubContent
45 + ref={ref}
46 + className={cn(
47 + "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
48 + className,
49 + )}
50 + {...props}
51 + />
52 +));
53 +ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName;
54 +
55 +const ContextMenuContent = React.forwardRef<
56 + React.ElementRef<typeof ContextMenuPrimitive.Content>,
57 + React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Content>
58 +>(({ className, ...props }, ref) => (
59 + <ContextMenuPrimitive.Portal>
60 + <ContextMenuPrimitive.Content
61 + ref={ref}
62 + className={cn(
63 + "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in fade-in-80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
64 + className,
65 + )}
66 + {...props}
67 + />
68 + </ContextMenuPrimitive.Portal>
69 +));
70 +ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName;
71 +
72 +const ContextMenuItem = React.forwardRef<
73 + React.ElementRef<typeof ContextMenuPrimitive.Item>,
74 + React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Item> & {
75 + inset?: boolean;
76 + }
77 +>(({ className, inset, ...props }, ref) => (
78 + <ContextMenuPrimitive.Item
79 + ref={ref}
80 + className={cn(
81 + "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
82 + inset && "pl-8",
83 + className,
84 + )}
85 + {...props}
86 + />
87 +));
88 +ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName;
89 +
90 +const ContextMenuCheckboxItem = React.forwardRef<
91 + React.ElementRef<typeof ContextMenuPrimitive.CheckboxItem>,
92 + React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.CheckboxItem>
93 +>(({ className, children, checked, ...props }, ref) => (
94 + <ContextMenuPrimitive.CheckboxItem
95 + ref={ref}
96 + className={cn(
97 + "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
98 + className,
99 + )}
100 + checked={checked}
101 + {...props}
102 + >
103 + <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
104 + <ContextMenuPrimitive.ItemIndicator>
105 + <Check className="h-4 w-4" />
106 + </ContextMenuPrimitive.ItemIndicator>
107 + </span>
108 + {children}
109 + </ContextMenuPrimitive.CheckboxItem>
110 +));
111 +ContextMenuCheckboxItem.displayName = ContextMenuPrimitive.CheckboxItem.displayName;
112 +
113 +const ContextMenuRadioItem = React.forwardRef<
114 + React.ElementRef<typeof ContextMenuPrimitive.RadioItem>,
115 + React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.RadioItem>
116 +>(({ className, children, ...props }, ref) => (
117 + <ContextMenuPrimitive.RadioItem
118 + ref={ref}
119 + className={cn(
120 + "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
121 + className,
122 + )}
123 + {...props}
124 + >
125 + <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
126 + <ContextMenuPrimitive.ItemIndicator>
127 + <Circle className="h-2 w-2 fill-current" />
128 + </ContextMenuPrimitive.ItemIndicator>
129 + </span>
130 + {children}
131 + </ContextMenuPrimitive.RadioItem>
132 +));
133 +ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName;
134 +
135 +const ContextMenuLabel = React.forwardRef<
136 + React.ElementRef<typeof ContextMenuPrimitive.Label>,
137 + React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Label> & {
138 + inset?: boolean;
139 + }
140 +>(({ className, inset, ...props }, ref) => (
141 + <ContextMenuPrimitive.Label
142 + ref={ref}
143 + className={cn("px-2 py-1.5 text-sm font-semibold text-foreground", inset && "pl-8", className)}
144 + {...props}
145 + />
146 +));
147 +ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName;
148 +
149 +const ContextMenuSeparator = React.forwardRef<
150 + React.ElementRef<typeof ContextMenuPrimitive.Separator>,
151 + React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Separator>
152 +>(({ className, ...props }, ref) => (
153 + <ContextMenuPrimitive.Separator ref={ref} className={cn("-mx-1 my-1 h-px bg-border", className)} {...props} />
154 +));
155 +ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName;
156 +
157 +const ContextMenuShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {
158 + return <span className={cn("ml-auto text-xs tracking-widest text-muted-foreground", className)} {...props} />;
159 +};
160 +ContextMenuShortcut.displayName = "ContextMenuShortcut";
161 +
162 +export {
163 + ContextMenu,
164 + ContextMenuTrigger,
165 + ContextMenuContent,
166 + ContextMenuItem,
167 + ContextMenuCheckboxItem,
168 + ContextMenuRadioItem,
169 + ContextMenuLabel,
170 + ContextMenuSeparator,
171 + ContextMenuShortcut,
172 + ContextMenuGroup,
173 + ContextMenuPortal,
174 + ContextMenuSub,
175 + ContextMenuSubContent,
176 + ContextMenuSubTrigger,
177 + ContextMenuRadioGroup,
178 +};
src/components/ui/dialog.tsx new
+95
@@ -0,0 +1,95 @@
1 +import * as React from "react";
2 +import * as DialogPrimitive from "@radix-ui/react-dialog";
3 +import { X } from "lucide-react";
4 +
5 +import { cn } from "@/lib/utils";
6 +
7 +const Dialog = DialogPrimitive.Root;
8 +
9 +const DialogTrigger = DialogPrimitive.Trigger;
10 +
11 +const DialogPortal = DialogPrimitive.Portal;
12 +
13 +const DialogClose = DialogPrimitive.Close;
14 +
15 +const DialogOverlay = React.forwardRef<
16 + React.ElementRef<typeof DialogPrimitive.Overlay>,
17 + React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
18 +>(({ className, ...props }, ref) => (
19 + <DialogPrimitive.Overlay
20 + ref={ref}
21 + className={cn(
22 + "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
23 + className,
24 + )}
25 + {...props}
26 + />
27 +));
28 +DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
29 +
30 +const DialogContent = React.forwardRef<
31 + React.ElementRef<typeof DialogPrimitive.Content>,
32 + React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
33 +>(({ className, children, ...props }, ref) => (
34 + <DialogPortal>
35 + <DialogOverlay />
36 + <DialogPrimitive.Content
37 + ref={ref}
38 + className={cn(
39 + "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
40 + className,
41 + )}
42 + {...props}
43 + >
44 + {children}
45 + <DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity data-[state=open]:bg-accent data-[state=open]:text-muted-foreground hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none">
46 + <X className="h-4 w-4" />
47 + <span className="sr-only">Close</span>
48 + </DialogPrimitive.Close>
49 + </DialogPrimitive.Content>
50 + </DialogPortal>
51 +));
52 +DialogContent.displayName = DialogPrimitive.Content.displayName;
53 +
54 +const DialogHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
55 + <div className={cn("flex flex-col space-y-1.5 text-center sm:text-left", className)} {...props} />
56 +);
57 +DialogHeader.displayName = "DialogHeader";
58 +
59 +const DialogFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
60 + <div className={cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className)} {...props} />
61 +);
62 +DialogFooter.displayName = "DialogFooter";
63 +
64 +const DialogTitle = React.forwardRef<
65 + React.ElementRef<typeof DialogPrimitive.Title>,
66 + React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
67 +>(({ className, ...props }, ref) => (
68 + <DialogPrimitive.Title
69 + ref={ref}
70 + className={cn("text-lg font-semibold leading-none tracking-tight", className)}
71 + {...props}
72 + />
73 +));
74 +DialogTitle.displayName = DialogPrimitive.Title.displayName;
75 +
76 +const DialogDescription = React.forwardRef<
77 + React.ElementRef<typeof DialogPrimitive.Description>,
78 + React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
79 +>(({ className, ...props }, ref) => (
80 + <DialogPrimitive.Description ref={ref} className={cn("text-sm text-muted-foreground", className)} {...props} />
81 +));
82 +DialogDescription.displayName = DialogPrimitive.Description.displayName;
83 +
84 +export {
85 + Dialog,
86 + DialogPortal,
87 + DialogOverlay,
88 + DialogClose,
89 + DialogTrigger,
90 + DialogContent,
91 + DialogHeader,
92 + DialogFooter,
93 + DialogTitle,
94 + DialogDescription,
95 +};
src/components/ui/drawer.tsx new
+87
@@ -0,0 +1,87 @@
1 +import * as React from "react";
2 +import { Drawer as DrawerPrimitive } from "vaul";
3 +
4 +import { cn } from "@/lib/utils";
5 +
6 +const Drawer = ({ shouldScaleBackground = true, ...props }: React.ComponentProps<typeof DrawerPrimitive.Root>) => (
7 + <DrawerPrimitive.Root shouldScaleBackground={shouldScaleBackground} {...props} />
8 +);
9 +Drawer.displayName = "Drawer";
10 +
11 +const DrawerTrigger = DrawerPrimitive.Trigger;
12 +
13 +const DrawerPortal = DrawerPrimitive.Portal;
14 +
15 +const DrawerClose = DrawerPrimitive.Close;
16 +
17 +const DrawerOverlay = React.forwardRef<
18 + React.ElementRef<typeof DrawerPrimitive.Overlay>,
19 + React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Overlay>
20 +>(({ className, ...props }, ref) => (
21 + <DrawerPrimitive.Overlay ref={ref} className={cn("fixed inset-0 z-50 bg-black/80", className)} {...props} />
22 +));
23 +DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName;
24 +
25 +const DrawerContent = React.forwardRef<
26 + React.ElementRef<typeof DrawerPrimitive.Content>,
27 + React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Content>
28 +>(({ className, children, ...props }, ref) => (
29 + <DrawerPortal>
30 + <DrawerOverlay />
31 + <DrawerPrimitive.Content
32 + ref={ref}
33 + className={cn(
34 + "fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background",
35 + className,
36 + )}
37 + {...props}
38 + >
39 + <div className="mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted" />
40 + {children}
41 + </DrawerPrimitive.Content>
42 + </DrawerPortal>
43 +));
44 +DrawerContent.displayName = "DrawerContent";
45 +
46 +const DrawerHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
47 + <div className={cn("grid gap-1.5 p-4 text-center sm:text-left", className)} {...props} />
48 +);
49 +DrawerHeader.displayName = "DrawerHeader";
50 +
51 +const DrawerFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
52 + <div className={cn("mt-auto flex flex-col gap-2 p-4", className)} {...props} />
53 +);
54 +DrawerFooter.displayName = "DrawerFooter";
55 +
56 +const DrawerTitle = React.forwardRef<
57 + React.ElementRef<typeof DrawerPrimitive.Title>,
58 + React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Title>
59 +>(({ className, ...props }, ref) => (
60 + <DrawerPrimitive.Title
61 + ref={ref}
62 + className={cn("text-lg font-semibold leading-none tracking-tight", className)}
63 + {...props}
64 + />
65 +));
66 +DrawerTitle.displayName = DrawerPrimitive.Title.displayName;
67 +
68 +const DrawerDescription = React.forwardRef<
69 + React.ElementRef<typeof DrawerPrimitive.Description>,
70 + React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Description>
71 +>(({ className, ...props }, ref) => (
72 + <DrawerPrimitive.Description ref={ref} className={cn("text-sm text-muted-foreground", className)} {...props} />
73 +));
74 +DrawerDescription.displayName = DrawerPrimitive.Description.displayName;
75 +
76 +export {
77 + Drawer,
78 + DrawerPortal,
79 + DrawerOverlay,
80 + DrawerTrigger,
81 + DrawerClose,
82 + DrawerContent,
83 + DrawerHeader,
84 + DrawerFooter,
85 + DrawerTitle,
86 + DrawerDescription,
87 +};
src/components/ui/dropdown-menu.tsx new
+179
@@ -0,0 +1,179 @@
1 +import * as React from "react";
2 +import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
3 +import { Check, ChevronRight, Circle } from "lucide-react";
4 +
5 +import { cn } from "@/lib/utils";
6 +
7 +const DropdownMenu = DropdownMenuPrimitive.Root;
8 +
9 +const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
10 +
11 +const DropdownMenuGroup = DropdownMenuPrimitive.Group;
12 +
13 +const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
14 +
15 +const DropdownMenuSub = DropdownMenuPrimitive.Sub;
16 +
17 +const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
18 +
19 +const DropdownMenuSubTrigger = React.forwardRef<
20 + React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
21 + React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
22 + inset?: boolean;
23 + }
24 +>(({ className, inset, children, ...props }, ref) => (
25 + <DropdownMenuPrimitive.SubTrigger
26 + ref={ref}
27 + className={cn(
28 + "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[state=open]:bg-accent focus:bg-accent",
29 + inset && "pl-8",
30 + className,
31 + )}
32 + {...props}
33 + >
34 + {children}
35 + <ChevronRight className="ml-auto h-4 w-4" />
36 + </DropdownMenuPrimitive.SubTrigger>
37 +));
38 +DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
39 +
40 +const DropdownMenuSubContent = React.forwardRef<
41 + React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
42 + React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
43 +>(({ className, ...props }, ref) => (
44 + <DropdownMenuPrimitive.SubContent
45 + ref={ref}
46 + className={cn(
47 + "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
48 + className,
49 + )}
50 + {...props}
51 + />
52 +));
53 +DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
54 +
55 +const DropdownMenuContent = React.forwardRef<
56 + React.ElementRef<typeof DropdownMenuPrimitive.Content>,
57 + React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
58 +>(({ className, sideOffset = 4, ...props }, ref) => (
59 + <DropdownMenuPrimitive.Portal>
60 + <DropdownMenuPrimitive.Content
61 + ref={ref}
62 + sideOffset={sideOffset}
63 + className={cn(
64 + "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
65 + className,
66 + )}
67 + {...props}
68 + />
69 + </DropdownMenuPrimitive.Portal>
70 +));
71 +DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
72 +
73 +const DropdownMenuItem = React.forwardRef<
74 + React.ElementRef<typeof DropdownMenuPrimitive.Item>,
75 + React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
76 + inset?: boolean;
77 + }
78 +>(({ className, inset, ...props }, ref) => (
79 + <DropdownMenuPrimitive.Item
80 + ref={ref}
81 + className={cn(
82 + "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
83 + inset && "pl-8",
84 + className,
85 + )}
86 + {...props}
87 + />
88 +));
89 +DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
90 +
91 +const DropdownMenuCheckboxItem = React.forwardRef<
92 + React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
93 + React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
94 +>(({ className, children, checked, ...props }, ref) => (
95 + <DropdownMenuPrimitive.CheckboxItem
96 + ref={ref}
97 + className={cn(
98 + "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
99 + className,
100 + )}
101 + checked={checked}
102 + {...props}
103 + >
104 + <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
105 + <DropdownMenuPrimitive.ItemIndicator>
106 + <Check className="h-4 w-4" />
107 + </DropdownMenuPrimitive.ItemIndicator>
108 + </span>
109 + {children}
110 + </DropdownMenuPrimitive.CheckboxItem>
111 +));
112 +DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
113 +
114 +const DropdownMenuRadioItem = React.forwardRef<
115 + React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
116 + React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
117 +>(({ className, children, ...props }, ref) => (
118 + <DropdownMenuPrimitive.RadioItem
119 + ref={ref}
120 + className={cn(
121 + "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
122 + className,
123 + )}
124 + {...props}
125 + >
126 + <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
127 + <DropdownMenuPrimitive.ItemIndicator>
128 + <Circle className="h-2 w-2 fill-current" />
129 + </DropdownMenuPrimitive.ItemIndicator>
130 + </span>
131 + {children}
132 + </DropdownMenuPrimitive.RadioItem>
133 +));
134 +DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
135 +
136 +const DropdownMenuLabel = React.forwardRef<
137 + React.ElementRef<typeof DropdownMenuPrimitive.Label>,
138 + React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
139 + inset?: boolean;
140 + }
141 +>(({ className, inset, ...props }, ref) => (
142 + <DropdownMenuPrimitive.Label
143 + ref={ref}
144 + className={cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className)}
145 + {...props}
146 + />
147 +));
148 +DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
149 +
150 +const DropdownMenuSeparator = React.forwardRef<
151 + React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
152 + React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
153 +>(({ className, ...props }, ref) => (
154 + <DropdownMenuPrimitive.Separator ref={ref} className={cn("-mx-1 my-1 h-px bg-muted", className)} {...props} />
155 +));
156 +DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
157 +
158 +const DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {
159 + return <span className={cn("ml-auto text-xs tracking-widest opacity-60", className)} {...props} />;
160 +};
161 +DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
162 +
163 +export {
164 + DropdownMenu,
165 + DropdownMenuTrigger,
166 + DropdownMenuContent,
167 + DropdownMenuItem,
168 + DropdownMenuCheckboxItem,
169 + DropdownMenuRadioItem,
170 + DropdownMenuLabel,
171 + DropdownMenuSeparator,
172 + DropdownMenuShortcut,
173 + DropdownMenuGroup,
174 + DropdownMenuPortal,
175 + DropdownMenuSub,
176 + DropdownMenuSubContent,
177 + DropdownMenuSubTrigger,
178 + DropdownMenuRadioGroup,
179 +};
src/components/ui/form.tsx new
+129
@@ -0,0 +1,129 @@
1 +import * as React from "react";
2 +import * as LabelPrimitive from "@radix-ui/react-label";
3 +import { Slot } from "@radix-ui/react-slot";
4 +import { Controller, ControllerProps, FieldPath, FieldValues, FormProvider, useFormContext } from "react-hook-form";
5 +
6 +import { cn } from "@/lib/utils";
7 +import { Label } from "@/components/ui/label";
8 +
9 +const Form = FormProvider;
10 +
11 +type FormFieldContextValue<
12 + TFieldValues extends FieldValues = FieldValues,
13 + TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
14 +> = {
15 + name: TName;
16 +};
17 +
18 +const FormFieldContext = React.createContext<FormFieldContextValue>({} as FormFieldContextValue);
19 +
20 +const FormField = <
21 + TFieldValues extends FieldValues = FieldValues,
22 + TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
23 +>({
24 + ...props
25 +}: ControllerProps<TFieldValues, TName>) => {
26 + return (
27 + <FormFieldContext.Provider value={{ name: props.name }}>
28 + <Controller {...props} />
29 + </FormFieldContext.Provider>
30 + );
31 +};
32 +
33 +const useFormField = () => {
34 + const fieldContext = React.useContext(FormFieldContext);
35 + const itemContext = React.useContext(FormItemContext);
36 + const { getFieldState, formState } = useFormContext();
37 +
38 + const fieldState = getFieldState(fieldContext.name, formState);
39 +
40 + if (!fieldContext) {
41 + throw new Error("useFormField should be used within <FormField>");
42 + }
43 +
44 + const { id } = itemContext;
45 +
46 + return {
47 + id,
48 + name: fieldContext.name,
49 + formItemId: `${id}-form-item`,
50 + formDescriptionId: `${id}-form-item-description`,
51 + formMessageId: `${id}-form-item-message`,
52 + ...fieldState,
53 + };
54 +};
55 +
56 +type FormItemContextValue = {
57 + id: string;
58 +};
59 +
60 +const FormItemContext = React.createContext<FormItemContextValue>({} as FormItemContextValue);
61 +
62 +const FormItem = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
63 + ({ className, ...props }, ref) => {
64 + const id = React.useId();
65 +
66 + return (
67 + <FormItemContext.Provider value={{ id }}>
68 + <div ref={ref} className={cn("space-y-2", className)} {...props} />
69 + </FormItemContext.Provider>
70 + );
71 + },
72 +);
73 +FormItem.displayName = "FormItem";
74 +
75 +const FormLabel = React.forwardRef<
76 + React.ElementRef<typeof LabelPrimitive.Root>,
77 + React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>
78 +>(({ className, ...props }, ref) => {
79 + const { error, formItemId } = useFormField();
80 +
81 + return <Label ref={ref} className={cn(error && "text-destructive", className)} htmlFor={formItemId} {...props} />;
82 +});
83 +FormLabel.displayName = "FormLabel";
84 +
85 +const FormControl = React.forwardRef<React.ElementRef<typeof Slot>, React.ComponentPropsWithoutRef<typeof Slot>>(
86 + ({ ...props }, ref) => {
87 + const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
88 +
89 + return (
90 + <Slot
91 + ref={ref}
92 + id={formItemId}
93 + aria-describedby={!error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`}
94 + aria-invalid={!!error}
95 + {...props}
96 + />
97 + );
98 + },
99 +);
100 +FormControl.displayName = "FormControl";
101 +
102 +const FormDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
103 + ({ className, ...props }, ref) => {
104 + const { formDescriptionId } = useFormField();
105 +
106 + return <p ref={ref} id={formDescriptionId} className={cn("text-sm text-muted-foreground", className)} {...props} />;
107 + },
108 +);
109 +FormDescription.displayName = "FormDescription";
110 +
111 +const FormMessage = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
112 + ({ className, children, ...props }, ref) => {
113 + const { error, formMessageId } = useFormField();
114 + const body = error ? String(error?.message) : children;
115 +
116 + if (!body) {
117 + return null;
118 + }
119 +
120 + return (
121 + <p ref={ref} id={formMessageId} className={cn("text-sm font-medium text-destructive", className)} {...props}>
122 + {body}
123 + </p>
124 + );
125 + },
126 +);
127 +FormMessage.displayName = "FormMessage";
128 +
129 +export { useFormField, Form, FormItem, FormLabel, FormControl, FormDescription, FormMessage, FormField };
src/components/ui/hover-card.tsx new
+27
@@ -0,0 +1,27 @@
1 +import * as React from "react";
2 +import * as HoverCardPrimitive from "@radix-ui/react-hover-card";
3 +
4 +import { cn } from "@/lib/utils";
5 +
6 +const HoverCard = HoverCardPrimitive.Root;
7 +
8 +const HoverCardTrigger = HoverCardPrimitive.Trigger;
9 +
10 +const HoverCardContent = React.forwardRef<
11 + React.ElementRef<typeof HoverCardPrimitive.Content>,
12 + React.ComponentPropsWithoutRef<typeof HoverCardPrimitive.Content>
13 +>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
14 + <HoverCardPrimitive.Content
15 + ref={ref}
16 + align={align}
17 + sideOffset={sideOffset}
18 + className={cn(
19 + "z-50 w-64 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
20 + className,
21 + )}
22 + {...props}
23 + />
24 +));
25 +HoverCardContent.displayName = HoverCardPrimitive.Content.displayName;
26 +
27 +export { HoverCard, HoverCardTrigger, HoverCardContent };
src/components/ui/input-otp.tsx new
+61
@@ -0,0 +1,61 @@
1 +import * as React from "react";
2 +import { OTPInput, OTPInputContext } from "input-otp";
3 +import { Dot } from "lucide-react";
4 +
5 +import { cn } from "@/lib/utils";
6 +
7 +const InputOTP = React.forwardRef<React.ElementRef<typeof OTPInput>, React.ComponentPropsWithoutRef<typeof OTPInput>>(
8 + ({ className, containerClassName, ...props }, ref) => (
9 + <OTPInput
10 + ref={ref}
11 + containerClassName={cn("flex items-center gap-2 has-[:disabled]:opacity-50", containerClassName)}
12 + className={cn("disabled:cursor-not-allowed", className)}
13 + {...props}
14 + />
15 + ),
16 +);
17 +InputOTP.displayName = "InputOTP";
18 +
19 +const InputOTPGroup = React.forwardRef<React.ElementRef<"div">, React.ComponentPropsWithoutRef<"div">>(
20 + ({ className, ...props }, ref) => <div ref={ref} className={cn("flex items-center", className)} {...props} />,
21 +);
22 +InputOTPGroup.displayName = "InputOTPGroup";
23 +
24 +const InputOTPSlot = React.forwardRef<
25 + React.ElementRef<"div">,
26 + React.ComponentPropsWithoutRef<"div"> & { index: number }
27 +>(({ index, className, ...props }, ref) => {
28 + const inputOTPContext = React.useContext(OTPInputContext);
29 + const { char, hasFakeCaret, isActive } = inputOTPContext.slots[index];
30 +
31 + return (
32 + <div
33 + ref={ref}
34 + className={cn(
35 + "relative flex h-10 w-10 items-center justify-center border-y border-r border-input text-sm transition-all first:rounded-l-md first:border-l last:rounded-r-md",
36 + isActive && "z-10 ring-2 ring-ring ring-offset-background",
37 + className,
38 + )}
39 + {...props}
40 + >
41 + {char}
42 + {hasFakeCaret && (
43 + <div className="pointer-events-none absolute inset-0 flex items-center justify-center">
44 + <div className="animate-caret-blink h-4 w-px bg-foreground duration-1000" />
45 + </div>
46 + )}
47 + </div>
48 + );
49 +});
50 +InputOTPSlot.displayName = "InputOTPSlot";
51 +
52 +const InputOTPSeparator = React.forwardRef<React.ElementRef<"div">, React.ComponentPropsWithoutRef<"div">>(
53 + ({ ...props }, ref) => (
54 + <div ref={ref} role="separator" {...props}>
55 + <Dot />
56 + </div>
57 + ),
58 +);
59 +InputOTPSeparator.displayName = "InputOTPSeparator";
60 +
61 +export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator };
src/components/ui/input.tsx new
+22
@@ -0,0 +1,22 @@
1 +import * as React from "react";
2 +
3 +import { cn } from "@/lib/utils";
4 +
5 +const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
6 + ({ className, type, ...props }, ref) => {
7 + return (
8 + <input
9 + type={type}
10 + className={cn(
11 + "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
12 + className,
13 + )}
14 + ref={ref}
15 + {...props}
16 + />
17 + );
18 + },
19 +);
20 +Input.displayName = "Input";
21 +
22 +export { Input };
src/components/ui/label.tsx new
+17
@@ -0,0 +1,17 @@
1 +import * as React from "react";
2 +import * as LabelPrimitive from "@radix-ui/react-label";
3 +import { cva, type VariantProps } from "class-variance-authority";
4 +
5 +import { cn } from "@/lib/utils";
6 +
7 +const labelVariants = cva("text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70");
8 +
9 +const Label = React.forwardRef<
10 + React.ElementRef<typeof LabelPrimitive.Root>,
11 + React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> & VariantProps<typeof labelVariants>
12 +>(({ className, ...props }, ref) => (
13 + <LabelPrimitive.Root ref={ref} className={cn(labelVariants(), className)} {...props} />
14 +));
15 +Label.displayName = LabelPrimitive.Root.displayName;
16 +
17 +export { Label };
src/components/ui/menubar.tsx new
+207
@@ -0,0 +1,207 @@
1 +import * as React from "react";
2 +import * as MenubarPrimitive from "@radix-ui/react-menubar";
3 +import { Check, ChevronRight, Circle } from "lucide-react";
4 +
5 +import { cn } from "@/lib/utils";
6 +
7 +const MenubarMenu = MenubarPrimitive.Menu;
8 +
9 +const MenubarGroup = MenubarPrimitive.Group;
10 +
11 +const MenubarPortal = MenubarPrimitive.Portal;
12 +
13 +const MenubarSub = MenubarPrimitive.Sub;
14 +
15 +const MenubarRadioGroup = MenubarPrimitive.RadioGroup;
16 +
17 +const Menubar = React.forwardRef<
18 + React.ElementRef<typeof MenubarPrimitive.Root>,
19 + React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Root>
20 +>(({ className, ...props }, ref) => (
21 + <MenubarPrimitive.Root
22 + ref={ref}
23 + className={cn("flex h-10 items-center space-x-1 rounded-md border bg-background p-1", className)}
24 + {...props}
25 + />
26 +));
27 +Menubar.displayName = MenubarPrimitive.Root.displayName;
28 +
29 +const MenubarTrigger = React.forwardRef<
30 + React.ElementRef<typeof MenubarPrimitive.Trigger>,
31 + React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Trigger>
32 +>(({ className, ...props }, ref) => (
33 + <MenubarPrimitive.Trigger
34 + ref={ref}
35 + className={cn(
36 + "flex cursor-default select-none items-center rounded-sm px-3 py-1.5 text-sm font-medium outline-none data-[state=open]:bg-accent data-[state=open]:text-accent-foreground focus:bg-accent focus:text-accent-foreground",
37 + className,
38 + )}
39 + {...props}
40 + />
41 +));
42 +MenubarTrigger.displayName = MenubarPrimitive.Trigger.displayName;
43 +
44 +const MenubarSubTrigger = React.forwardRef<
45 + React.ElementRef<typeof MenubarPrimitive.SubTrigger>,
46 + React.ComponentPropsWithoutRef<typeof MenubarPrimitive.SubTrigger> & {
47 + inset?: boolean;
48 + }
49 +>(({ className, inset, children, ...props }, ref) => (
50 + <MenubarPrimitive.SubTrigger
51 + ref={ref}
52 + className={cn(
53 + "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[state=open]:bg-accent data-[state=open]:text-accent-foreground focus:bg-accent focus:text-accent-foreground",
54 + inset && "pl-8",
55 + className,
56 + )}
57 + {...props}
58 + >
59 + {children}
60 + <ChevronRight className="ml-auto h-4 w-4" />
61 + </MenubarPrimitive.SubTrigger>
62 +));
63 +MenubarSubTrigger.displayName = MenubarPrimitive.SubTrigger.displayName;
64 +
65 +const MenubarSubContent = React.forwardRef<
66 + React.ElementRef<typeof MenubarPrimitive.SubContent>,
67 + React.ComponentPropsWithoutRef<typeof MenubarPrimitive.SubContent>
68 +>(({ className, ...props }, ref) => (
69 + <MenubarPrimitive.SubContent
70 + ref={ref}
71 + className={cn(
72 + "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
73 + className,
74 + )}
75 + {...props}
76 + />
77 +));
78 +MenubarSubContent.displayName = MenubarPrimitive.SubContent.displayName;
79 +
80 +const MenubarContent = React.forwardRef<
81 + React.ElementRef<typeof MenubarPrimitive.Content>,
82 + React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Content>
83 +>(({ className, align = "start", alignOffset = -4, sideOffset = 8, ...props }, ref) => (
84 + <MenubarPrimitive.Portal>
85 + <MenubarPrimitive.Content
86 + ref={ref}
87 + align={align}
88 + alignOffset={alignOffset}
89 + sideOffset={sideOffset}
90 + className={cn(
91 + "z-50 min-w-[12rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
92 + className,
93 + )}
94 + {...props}
95 + />
96 + </MenubarPrimitive.Portal>
97 +));
98 +MenubarContent.displayName = MenubarPrimitive.Content.displayName;
99 +
100 +const MenubarItem = React.forwardRef<
101 + React.ElementRef<typeof MenubarPrimitive.Item>,
102 + React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Item> & {
103 + inset?: boolean;
104 + }
105 +>(({ className, inset, ...props }, ref) => (
106 + <MenubarPrimitive.Item
107 + ref={ref}
108 + className={cn(
109 + "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
110 + inset && "pl-8",
111 + className,
112 + )}
113 + {...props}
114 + />
115 +));
116 +MenubarItem.displayName = MenubarPrimitive.Item.displayName;
117 +
118 +const MenubarCheckboxItem = React.forwardRef<
119 + React.ElementRef<typeof MenubarPrimitive.CheckboxItem>,
120 + React.ComponentPropsWithoutRef<typeof MenubarPrimitive.CheckboxItem>
121 +>(({ className, children, checked, ...props }, ref) => (
122 + <MenubarPrimitive.CheckboxItem
123 + ref={ref}
124 + className={cn(
125 + "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
126 + className,
127 + )}
128 + checked={checked}
129 + {...props}
130 + >
131 + <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
132 + <MenubarPrimitive.ItemIndicator>
133 + <Check className="h-4 w-4" />
134 + </MenubarPrimitive.ItemIndicator>
135 + </span>
136 + {children}
137 + </MenubarPrimitive.CheckboxItem>
138 +));
139 +MenubarCheckboxItem.displayName = MenubarPrimitive.CheckboxItem.displayName;
140 +
141 +const MenubarRadioItem = React.forwardRef<
142 + React.ElementRef<typeof MenubarPrimitive.RadioItem>,
143 + React.ComponentPropsWithoutRef<typeof MenubarPrimitive.RadioItem>
144 +>(({ className, children, ...props }, ref) => (
145 + <MenubarPrimitive.RadioItem
146 + ref={ref}
147 + className={cn(
148 + "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
149 + className,
150 + )}
151 + {...props}
152 + >
153 + <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
154 + <MenubarPrimitive.ItemIndicator>
155 + <Circle className="h-2 w-2 fill-current" />
156 + </MenubarPrimitive.ItemIndicator>
157 + </span>
158 + {children}
159 + </MenubarPrimitive.RadioItem>
160 +));
161 +MenubarRadioItem.displayName = MenubarPrimitive.RadioItem.displayName;
162 +
163 +const MenubarLabel = React.forwardRef<
164 + React.ElementRef<typeof MenubarPrimitive.Label>,
165 + React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Label> & {
166 + inset?: boolean;
167 + }
168 +>(({ className, inset, ...props }, ref) => (
169 + <MenubarPrimitive.Label
170 + ref={ref}
171 + className={cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className)}
172 + {...props}
173 + />
174 +));
175 +MenubarLabel.displayName = MenubarPrimitive.Label.displayName;
176 +
177 +const MenubarSeparator = React.forwardRef<
178 + React.ElementRef<typeof MenubarPrimitive.Separator>,
179 + React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Separator>
180 +>(({ className, ...props }, ref) => (
181 + <MenubarPrimitive.Separator ref={ref} className={cn("-mx-1 my-1 h-px bg-muted", className)} {...props} />
182 +));
183 +MenubarSeparator.displayName = MenubarPrimitive.Separator.displayName;
184 +
185 +const MenubarShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {
186 + return <span className={cn("ml-auto text-xs tracking-widest text-muted-foreground", className)} {...props} />;
187 +};
188 +MenubarShortcut.displayname = "MenubarShortcut";
189 +
190 +export {
191 + Menubar,
192 + MenubarMenu,
193 + MenubarTrigger,
194 + MenubarContent,
195 + MenubarItem,
196 + MenubarSeparator,
197 + MenubarLabel,
198 + MenubarCheckboxItem,
199 + MenubarRadioGroup,
200 + MenubarRadioItem,
201 + MenubarPortal,
202 + MenubarSubContent,
203 + MenubarSubTrigger,
204 + MenubarGroup,
205 + MenubarSub,
206 + MenubarShortcut,
207 +};
src/components/ui/navigation-menu.tsx new
+120
@@ -0,0 +1,120 @@
1 +import * as React from "react";
2 +import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu";
3 +import { cva } from "class-variance-authority";
4 +import { ChevronDown } from "lucide-react";
5 +
6 +import { cn } from "@/lib/utils";
7 +
8 +const NavigationMenu = React.forwardRef<
9 + React.ElementRef<typeof NavigationMenuPrimitive.Root>,
10 + React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Root>
11 +>(({ className, children, ...props }, ref) => (
12 + <NavigationMenuPrimitive.Root
13 + ref={ref}
14 + className={cn("relative z-10 flex max-w-max flex-1 items-center justify-center", className)}
15 + {...props}
16 + >
17 + {children}
18 + <NavigationMenuViewport />
19 + </NavigationMenuPrimitive.Root>
20 +));
21 +NavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName;
22 +
23 +const NavigationMenuList = React.forwardRef<
24 + React.ElementRef<typeof NavigationMenuPrimitive.List>,
25 + React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.List>
26 +>(({ className, ...props }, ref) => (
27 + <NavigationMenuPrimitive.List
28 + ref={ref}
29 + className={cn("group flex flex-1 list-none items-center justify-center space-x-1", className)}
30 + {...props}
31 + />
32 +));
33 +NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName;
34 +
35 +const NavigationMenuItem = NavigationMenuPrimitive.Item;
36 +
37 +const navigationMenuTriggerStyle = cva(
38 + "group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50",
39 +);
40 +
41 +const NavigationMenuTrigger = React.forwardRef<
42 + React.ElementRef<typeof NavigationMenuPrimitive.Trigger>,
43 + React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Trigger>
44 +>(({ className, children, ...props }, ref) => (
45 + <NavigationMenuPrimitive.Trigger
46 + ref={ref}
47 + className={cn(navigationMenuTriggerStyle(), "group", className)}
48 + {...props}
49 + >
50 + {children}{" "}
51 + <ChevronDown
52 + className="relative top-[1px] ml-1 h-3 w-3 transition duration-200 group-data-[state=open]:rotate-180"
53 + aria-hidden="true"
54 + />
55 + </NavigationMenuPrimitive.Trigger>
56 +));
57 +NavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName;
58 +
59 +const NavigationMenuContent = React.forwardRef<
60 + React.ElementRef<typeof NavigationMenuPrimitive.Content>,
61 + React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Content>
62 +>(({ className, ...props }, ref) => (
63 + <NavigationMenuPrimitive.Content
64 + ref={ref}
65 + className={cn(
66 + "left-0 top-0 w-full data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 md:absolute md:w-auto",
67 + className,
68 + )}
69 + {...props}
70 + />
71 +));
72 +NavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName;
73 +
74 +const NavigationMenuLink = NavigationMenuPrimitive.Link;
75 +
76 +const NavigationMenuViewport = React.forwardRef<
77 + React.ElementRef<typeof NavigationMenuPrimitive.Viewport>,
78 + React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Viewport>
79 +>(({ className, ...props }, ref) => (
80 + <div className={cn("absolute left-0 top-full flex justify-center")}>
81 + <NavigationMenuPrimitive.Viewport
82 + className={cn(
83 + "origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[var(--radix-navigation-menu-viewport-width)]",
84 + className,
85 + )}
86 + ref={ref}
87 + {...props}
88 + />
89 + </div>
90 +));
91 +NavigationMenuViewport.displayName = NavigationMenuPrimitive.Viewport.displayName;
92 +
93 +const NavigationMenuIndicator = React.forwardRef<
94 + React.ElementRef<typeof NavigationMenuPrimitive.Indicator>,
95 + React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Indicator>
96 +>(({ className, ...props }, ref) => (
97 + <NavigationMenuPrimitive.Indicator
98 + ref={ref}
99 + className={cn(
100 + "top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in",
101 + className,
102 + )}
103 + {...props}
104 + >
105 + <div className="relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-border shadow-md" />
106 + </NavigationMenuPrimitive.Indicator>
107 +));
108 +NavigationMenuIndicator.displayName = NavigationMenuPrimitive.Indicator.displayName;
109 +
110 +export {
111 + navigationMenuTriggerStyle,
112 + NavigationMenu,
113 + NavigationMenuList,
114 + NavigationMenuItem,
115 + NavigationMenuContent,
116 + NavigationMenuTrigger,
117 + NavigationMenuLink,
118 + NavigationMenuIndicator,
119 + NavigationMenuViewport,
120 +};
src/components/ui/pagination.tsx new
+81
@@ -0,0 +1,81 @@
1 +import * as React from "react";
2 +import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react";
3 +
4 +import { cn } from "@/lib/utils";
5 +import { ButtonProps, buttonVariants } from "@/components/ui/button";
6 +
7 +const Pagination = ({ className, ...props }: React.ComponentProps<"nav">) => (
8 + <nav
9 + role="navigation"
10 + aria-label="pagination"
11 + className={cn("mx-auto flex w-full justify-center", className)}
12 + {...props}
13 + />
14 +);
15 +Pagination.displayName = "Pagination";
16 +
17 +const PaginationContent = React.forwardRef<HTMLUListElement, React.ComponentProps<"ul">>(
18 + ({ className, ...props }, ref) => (
19 + <ul ref={ref} className={cn("flex flex-row items-center gap-1", className)} {...props} />
20 + ),
21 +);
22 +PaginationContent.displayName = "PaginationContent";
23 +
24 +const PaginationItem = React.forwardRef<HTMLLIElement, React.ComponentProps<"li">>(({ className, ...props }, ref) => (
25 + <li ref={ref} className={cn("", className)} {...props} />
26 +));
27 +PaginationItem.displayName = "PaginationItem";
28 +
29 +type PaginationLinkProps = {
30 + isActive?: boolean;
31 +} & Pick<ButtonProps, "size"> &
32 + React.ComponentProps<"a">;
33 +
34 +const PaginationLink = ({ className, isActive, size = "icon", ...props }: PaginationLinkProps) => (
35 + <a
36 + aria-current={isActive ? "page" : undefined}
37 + className={cn(
38 + buttonVariants({
39 + variant: isActive ? "outline" : "ghost",
40 + size,
41 + }),
42 + className,
43 + )}
44 + {...props}
45 + />
46 +);
47 +PaginationLink.displayName = "PaginationLink";
48 +
49 +const PaginationPrevious = ({ className, ...props }: React.ComponentProps<typeof PaginationLink>) => (
50 + <PaginationLink aria-label="Go to previous page" size="default" className={cn("gap-1 pl-2.5", className)} {...props}>
51 + <ChevronLeft className="h-4 w-4" />
52 + <span>Previous</span>
53 + </PaginationLink>
54 +);
55 +PaginationPrevious.displayName = "PaginationPrevious";
56 +
57 +const PaginationNext = ({ className, ...props }: React.ComponentProps<typeof PaginationLink>) => (
58 + <PaginationLink aria-label="Go to next page" size="default" className={cn("gap-1 pr-2.5", className)} {...props}>
59 + <span>Next</span>
60 + <ChevronRight className="h-4 w-4" />
61 + </PaginationLink>
62 +);
63 +PaginationNext.displayName = "PaginationNext";
64 +
65 +const PaginationEllipsis = ({ className, ...props }: React.ComponentProps<"span">) => (
66 + <span aria-hidden className={cn("flex h-9 w-9 items-center justify-center", className)} {...props}>
67 + <MoreHorizontal className="h-4 w-4" />
68 + <span className="sr-only">More pages</span>
69 + </span>
70 +);
71 +PaginationEllipsis.displayName = "PaginationEllipsis";
72 +
73 +export {
74 + Pagination,
75 + PaginationContent,
76 + PaginationEllipsis,
77 + PaginationItem,
78 + PaginationLink,
79 + PaginationNext,
80 + PaginationPrevious,
81 +};
src/components/ui/popover.tsx new
+29
@@ -0,0 +1,29 @@
1 +import * as React from "react";
2 +import * as PopoverPrimitive from "@radix-ui/react-popover";
3 +
4 +import { cn } from "@/lib/utils";
5 +
6 +const Popover = PopoverPrimitive.Root;
7 +
8 +const PopoverTrigger = PopoverPrimitive.Trigger;
9 +
10 +const PopoverContent = React.forwardRef<
11 + React.ElementRef<typeof PopoverPrimitive.Content>,
12 + React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
13 +>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
14 + <PopoverPrimitive.Portal>
15 + <PopoverPrimitive.Content
16 + ref={ref}
17 + align={align}
18 + sideOffset={sideOffset}
19 + className={cn(
20 + "z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
21 + className,
22 + )}
23 + {...props}
24 + />
25 + </PopoverPrimitive.Portal>
26 +));
27 +PopoverContent.displayName = PopoverPrimitive.Content.displayName;
28 +
29 +export { Popover, PopoverTrigger, PopoverContent };
src/components/ui/progress.tsx new
+23
@@ -0,0 +1,23 @@
1 +import * as React from "react";
2 +import * as ProgressPrimitive from "@radix-ui/react-progress";
3 +
4 +import { cn } from "@/lib/utils";
5 +
6 +const Progress = React.forwardRef<
7 + React.ElementRef<typeof ProgressPrimitive.Root>,
8 + React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>
9 +>(({ className, value, ...props }, ref) => (
10 + <ProgressPrimitive.Root
11 + ref={ref}
12 + className={cn("relative h-4 w-full overflow-hidden rounded-full bg-secondary", className)}
13 + {...props}
14 + >
15 + <ProgressPrimitive.Indicator
16 + className="h-full w-full flex-1 bg-primary transition-all"
17 + style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
18 + />
19 + </ProgressPrimitive.Root>
20 +));
21 +Progress.displayName = ProgressPrimitive.Root.displayName;
22 +
23 +export { Progress };
src/components/ui/radio-group.tsx new
+36
@@ -0,0 +1,36 @@
1 +import * as React from "react";
2 +import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
3 +import { Circle } from "lucide-react";
4 +
5 +import { cn } from "@/lib/utils";
6 +
7 +const RadioGroup = React.forwardRef<
8 + React.ElementRef<typeof RadioGroupPrimitive.Root>,
9 + React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>
10 +>(({ className, ...props }, ref) => {
11 + return <RadioGroupPrimitive.Root className={cn("grid gap-2", className)} {...props} ref={ref} />;
12 +});
13 +RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
14 +
15 +const RadioGroupItem = React.forwardRef<
16 + React.ElementRef<typeof RadioGroupPrimitive.Item>,
17 + React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>
18 +>(({ className, ...props }, ref) => {
19 + return (
20 + <RadioGroupPrimitive.Item
21 + ref={ref}
22 + className={cn(
23 + "aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
24 + className,
25 + )}
26 + {...props}
27 + >
28 + <RadioGroupPrimitive.Indicator className="flex items-center justify-center">
29 + <Circle className="h-2.5 w-2.5 fill-current text-current" />
30 + </RadioGroupPrimitive.Indicator>
31 + </RadioGroupPrimitive.Item>
32 + );
33 +});
34 +RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;
35 +
36 +export { RadioGroup, RadioGroupItem };
src/components/ui/resizable.tsx new
+37
@@ -0,0 +1,37 @@
1 +import { GripVertical } from "lucide-react";
2 +import * as ResizablePrimitive from "react-resizable-panels";
3 +
4 +import { cn } from "@/lib/utils";
5 +
6 +const ResizablePanelGroup = ({ className, ...props }: React.ComponentProps<typeof ResizablePrimitive.PanelGroup>) => (
7 + <ResizablePrimitive.PanelGroup
8 + className={cn("flex h-full w-full data-[panel-group-direction=vertical]:flex-col", className)}
9 + {...props}
10 + />
11 +);
12 +
13 +const ResizablePanel = ResizablePrimitive.Panel;
14 +
15 +const ResizableHandle = ({
16 + withHandle,
17 + className,
18 + ...props
19 +}: React.ComponentProps<typeof ResizablePrimitive.PanelResizeHandle> & {
20 + withHandle?: boolean;
21 +}) => (
22 + <ResizablePrimitive.PanelResizeHandle
23 + className={cn(
24 + "relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 [&[data-panel-group-direction=vertical]>div]:rotate-90",
25 + className,
26 + )}
27 + {...props}
28 + >
29 + {withHandle && (
30 + <div className="z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border">
31 + <GripVertical className="h-2.5 w-2.5" />
32 + </div>
33 + )}
34 + </ResizablePrimitive.PanelResizeHandle>
35 +);
36 +
37 +export { ResizablePanelGroup, ResizablePanel, ResizableHandle };
src/components/ui/scroll-area.tsx new
+38
@@ -0,0 +1,38 @@
1 +import * as React from "react";
2 +import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
3 +
4 +import { cn } from "@/lib/utils";
5 +
6 +const ScrollArea = React.forwardRef<
7 + React.ElementRef<typeof ScrollAreaPrimitive.Root>,
8 + React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>
9 +>(({ className, children, ...props }, ref) => (
10 + <ScrollAreaPrimitive.Root ref={ref} className={cn("relative overflow-hidden", className)} {...props}>
11 + <ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit]">{children}</ScrollAreaPrimitive.Viewport>
12 + <ScrollBar />
13 + <ScrollAreaPrimitive.Corner />
14 + </ScrollAreaPrimitive.Root>
15 +));
16 +ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
17 +
18 +const ScrollBar = React.forwardRef<
19 + React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,
20 + React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>
21 +>(({ className, orientation = "vertical", ...props }, ref) => (
22 + <ScrollAreaPrimitive.ScrollAreaScrollbar
23 + ref={ref}
24 + orientation={orientation}
25 + className={cn(
26 + "flex touch-none select-none transition-colors",
27 + orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent p-[1px]",
28 + orientation === "horizontal" && "h-2.5 flex-col border-t border-t-transparent p-[1px]",
29 + className,
30 + )}
31 + {...props}
32 + >
33 + <ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-border" />
34 + </ScrollAreaPrimitive.ScrollAreaScrollbar>
35 +));
36 +ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
37 +
38 +export { ScrollArea, ScrollBar };
src/components/ui/select.tsx new
+143
@@ -0,0 +1,143 @@
1 +import * as React from "react";
2 +import * as SelectPrimitive from "@radix-ui/react-select";
3 +import { Check, ChevronDown, ChevronUp } from "lucide-react";
4 +
5 +import { cn } from "@/lib/utils";
6 +
7 +const Select = SelectPrimitive.Root;
8 +
9 +const SelectGroup = SelectPrimitive.Group;
10 +
11 +const SelectValue = SelectPrimitive.Value;
12 +
13 +const SelectTrigger = React.forwardRef<
14 + React.ElementRef<typeof SelectPrimitive.Trigger>,
15 + React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
16 +>(({ className, children, ...props }, ref) => (
17 + <SelectPrimitive.Trigger
18 + ref={ref}
19 + className={cn(
20 + "flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
21 + className,
22 + )}
23 + {...props}
24 + >
25 + {children}
26 + <SelectPrimitive.Icon asChild>
27 + <ChevronDown className="h-4 w-4 opacity-50" />
28 + </SelectPrimitive.Icon>
29 + </SelectPrimitive.Trigger>
30 +));
31 +SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
32 +
33 +const SelectScrollUpButton = React.forwardRef<
34 + React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
35 + React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
36 +>(({ className, ...props }, ref) => (
37 + <SelectPrimitive.ScrollUpButton
38 + ref={ref}
39 + className={cn("flex cursor-default items-center justify-center py-1", className)}
40 + {...props}
41 + >
42 + <ChevronUp className="h-4 w-4" />
43 + </SelectPrimitive.ScrollUpButton>
44 +));
45 +SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
46 +
47 +const SelectScrollDownButton = React.forwardRef<
48 + React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
49 + React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
50 +>(({ className, ...props }, ref) => (
51 + <SelectPrimitive.ScrollDownButton
52 + ref={ref}
53 + className={cn("flex cursor-default items-center justify-center py-1", className)}
54 + {...props}
55 + >
56 + <ChevronDown className="h-4 w-4" />
57 + </SelectPrimitive.ScrollDownButton>
58 +));
59 +SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
60 +
61 +const SelectContent = React.forwardRef<
62 + React.ElementRef<typeof SelectPrimitive.Content>,
63 + React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
64 +>(({ className, children, position = "popper", ...props }, ref) => (
65 + <SelectPrimitive.Portal>
66 + <SelectPrimitive.Content
67 + ref={ref}
68 + className={cn(
69 + "relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
70 + position === "popper" &&
71 + "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
72 + className,
73 + )}
74 + position={position}
75 + {...props}
76 + >
77 + <SelectScrollUpButton />
78 + <SelectPrimitive.Viewport
79 + className={cn(
80 + "p-1",
81 + position === "popper" &&
82 + "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]",
83 + )}
84 + >
85 + {children}
86 + </SelectPrimitive.Viewport>
87 + <SelectScrollDownButton />
88 + </SelectPrimitive.Content>
89 + </SelectPrimitive.Portal>
90 +));
91 +SelectContent.displayName = SelectPrimitive.Content.displayName;
92 +
93 +const SelectLabel = React.forwardRef<
94 + React.ElementRef<typeof SelectPrimitive.Label>,
95 + React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
96 +>(({ className, ...props }, ref) => (
97 + <SelectPrimitive.Label ref={ref} className={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)} {...props} />
98 +));
99 +SelectLabel.displayName = SelectPrimitive.Label.displayName;
100 +
101 +const SelectItem = React.forwardRef<
102 + React.ElementRef<typeof SelectPrimitive.Item>,
103 + React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
104 +>(({ className, children, ...props }, ref) => (
105 + <SelectPrimitive.Item
106 + ref={ref}
107 + className={cn(
108 + "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-accent focus:text-accent-foreground",
109 + className,
110 + )}
111 + {...props}
112 + >
113 + <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
114 + <SelectPrimitive.ItemIndicator>
115 + <Check className="h-4 w-4" />
116 + </SelectPrimitive.ItemIndicator>
117 + </span>
118 +
119 + <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
120 + </SelectPrimitive.Item>
121 +));
122 +SelectItem.displayName = SelectPrimitive.Item.displayName;
123 +
124 +const SelectSeparator = React.forwardRef<
125 + React.ElementRef<typeof SelectPrimitive.Separator>,
126 + React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
127 +>(({ className, ...props }, ref) => (
128 + <SelectPrimitive.Separator ref={ref} className={cn("-mx-1 my-1 h-px bg-muted", className)} {...props} />
129 +));
130 +SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
131 +
132 +export {
133 + Select,
134 + SelectGroup,
135 + SelectValue,
136 + SelectTrigger,
137 + SelectContent,
138 + SelectLabel,
139 + SelectItem,
140 + SelectSeparator,
141 + SelectScrollUpButton,
142 + SelectScrollDownButton,
143 +};
src/components/ui/separator.tsx new
+20
@@ -0,0 +1,20 @@
1 +import * as React from "react";
2 +import * as SeparatorPrimitive from "@radix-ui/react-separator";
3 +
4 +import { cn } from "@/lib/utils";
5 +
6 +const Separator = React.forwardRef<
7 + React.ElementRef<typeof SeparatorPrimitive.Root>,
8 + React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>
9 +>(({ className, orientation = "horizontal", decorative = true, ...props }, ref) => (
10 + <SeparatorPrimitive.Root
11 + ref={ref}
12 + decorative={decorative}
13 + orientation={orientation}
14 + className={cn("shrink-0 bg-border", orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]", className)}
15 + {...props}
16 + />
17 +));
18 +Separator.displayName = SeparatorPrimitive.Root.displayName;
19 +
20 +export { Separator };
src/components/ui/sheet.tsx new
+107
@@ -0,0 +1,107 @@
1 +import * as SheetPrimitive from "@radix-ui/react-dialog";
2 +import { cva, type VariantProps } from "class-variance-authority";
3 +import { X } from "lucide-react";
4 +import * as React from "react";
5 +
6 +import { cn } from "@/lib/utils";
7 +
8 +const Sheet = SheetPrimitive.Root;
9 +
10 +const SheetTrigger = SheetPrimitive.Trigger;
11 +
12 +const SheetClose = SheetPrimitive.Close;
13 +
14 +const SheetPortal = SheetPrimitive.Portal;
15 +
16 +const SheetOverlay = React.forwardRef<
17 + React.ElementRef<typeof SheetPrimitive.Overlay>,
18 + React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
19 +>(({ className, ...props }, ref) => (
20 + <SheetPrimitive.Overlay
21 + className={cn(
22 + "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
23 + className,
24 + )}
25 + {...props}
26 + ref={ref}
27 + />
28 +));
29 +SheetOverlay.displayName = SheetPrimitive.Overlay.displayName;
30 +
31 +const sheetVariants = cva(
32 + "fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
33 + {
34 + variants: {
35 + side: {
36 + top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
37 + bottom:
38 + "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
39 + left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
40 + right:
41 + "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
42 + },
43 + },
44 + defaultVariants: {
45 + side: "right",
46 + },
47 + },
48 +);
49 +
50 +interface SheetContentProps
51 + extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
52 + VariantProps<typeof sheetVariants> {}
53 +
54 +const SheetContent = React.forwardRef<React.ElementRef<typeof SheetPrimitive.Content>, SheetContentProps>(
55 + ({ side = "right", className, children, ...props }, ref) => (
56 + <SheetPortal>
57 + <SheetOverlay />
58 + <SheetPrimitive.Content ref={ref} className={cn(sheetVariants({ side }), className)} {...props}>
59 + {children}
60 + <SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity data-[state=open]:bg-secondary hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none">
61 + <X className="h-4 w-4" />
62 + <span className="sr-only">Close</span>
63 + </SheetPrimitive.Close>
64 + </SheetPrimitive.Content>
65 + </SheetPortal>
66 + ),
67 +);
68 +SheetContent.displayName = SheetPrimitive.Content.displayName;
69 +
70 +const SheetHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
71 + <div className={cn("flex flex-col space-y-2 text-center sm:text-left", className)} {...props} />
72 +);
73 +SheetHeader.displayName = "SheetHeader";
74 +
75 +const SheetFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
76 + <div className={cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className)} {...props} />
77 +);
78 +SheetFooter.displayName = "SheetFooter";
79 +
80 +const SheetTitle = React.forwardRef<
81 + React.ElementRef<typeof SheetPrimitive.Title>,
82 + React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
83 +>(({ className, ...props }, ref) => (
84 + <SheetPrimitive.Title ref={ref} className={cn("text-lg font-semibold text-foreground", className)} {...props} />
85 +));
86 +SheetTitle.displayName = SheetPrimitive.Title.displayName;
87 +
88 +const SheetDescription = React.forwardRef<
89 + React.ElementRef<typeof SheetPrimitive.Description>,
90 + React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
91 +>(({ className, ...props }, ref) => (
92 + <SheetPrimitive.Description ref={ref} className={cn("text-sm text-muted-foreground", className)} {...props} />
93 +));
94 +SheetDescription.displayName = SheetPrimitive.Description.displayName;
95 +
96 +export {
97 + Sheet,
98 + SheetClose,
99 + SheetContent,
100 + SheetDescription,
101 + SheetFooter,
102 + SheetHeader,
103 + SheetOverlay,
104 + SheetPortal,
105 + SheetTitle,
106 + SheetTrigger,
107 +};
src/components/ui/sidebar.tsx new
+637
@@ -0,0 +1,637 @@
1 +import * as React from "react";
2 +import { Slot } from "@radix-ui/react-slot";
3 +import { VariantProps, cva } from "class-variance-authority";
4 +import { PanelLeft } from "lucide-react";
5 +
6 +import { useIsMobile } from "@/hooks/use-mobile";
7 +import { cn } from "@/lib/utils";
8 +import { Button } from "@/components/ui/button";
9 +import { Input } from "@/components/ui/input";
10 +import { Separator } from "@/components/ui/separator";
11 +import { Sheet, SheetContent } from "@/components/ui/sheet";
12 +import { Skeleton } from "@/components/ui/skeleton";
13 +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
14 +
15 +const SIDEBAR_COOKIE_NAME = "sidebar:state";
16 +const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
17 +const SIDEBAR_WIDTH = "16rem";
18 +const SIDEBAR_WIDTH_MOBILE = "18rem";
19 +const SIDEBAR_WIDTH_ICON = "3rem";
20 +const SIDEBAR_KEYBOARD_SHORTCUT = "b";
21 +
22 +type SidebarContext = {
23 + state: "expanded" | "collapsed";
24 + open: boolean;
25 + setOpen: (open: boolean) => void;
26 + openMobile: boolean;
27 + setOpenMobile: (open: boolean) => void;
28 + isMobile: boolean;
29 + toggleSidebar: () => void;
30 +};
31 +
32 +const SidebarContext = React.createContext<SidebarContext | null>(null);
33 +
34 +function useSidebar() {
35 + const context = React.useContext(SidebarContext);
36 + if (!context) {
37 + throw new Error("useSidebar must be used within a SidebarProvider.");
38 + }
39 +
40 + return context;
41 +}
42 +
43 +const SidebarProvider = React.forwardRef<
44 + HTMLDivElement,
45 + React.ComponentProps<"div"> & {
46 + defaultOpen?: boolean;
47 + open?: boolean;
48 + onOpenChange?: (open: boolean) => void;
49 + }
50 +>(({ defaultOpen = true, open: openProp, onOpenChange: setOpenProp, className, style, children, ...props }, ref) => {
51 + const isMobile = useIsMobile();
52 + const [openMobile, setOpenMobile] = React.useState(false);
53 +
54 + // This is the internal state of the sidebar.
55 + // We use openProp and setOpenProp for control from outside the component.
56 + const [_open, _setOpen] = React.useState(defaultOpen);
57 + const open = openProp ?? _open;
58 + const setOpen = React.useCallback(
59 + (value: boolean | ((value: boolean) => boolean)) => {
60 + const openState = typeof value === "function" ? value(open) : value;
61 + if (setOpenProp) {
62 + setOpenProp(openState);
63 + } else {
64 + _setOpen(openState);
65 + }
66 +
67 + // This sets the cookie to keep the sidebar state.
68 + document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
69 + },
70 + [setOpenProp, open],
71 + );
72 +
73 + // Helper to toggle the sidebar.
74 + const toggleSidebar = React.useCallback(() => {
75 + return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open);
76 + }, [isMobile, setOpen, setOpenMobile]);
77 +
78 + // Adds a keyboard shortcut to toggle the sidebar.
79 + React.useEffect(() => {
80 + const handleKeyDown = (event: KeyboardEvent) => {
81 + if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
82 + event.preventDefault();
83 + toggleSidebar();
84 + }
85 + };
86 +
87 + window.addEventListener("keydown", handleKeyDown);
88 + return () => window.removeEventListener("keydown", handleKeyDown);
89 + }, [toggleSidebar]);
90 +
91 + // We add a state so that we can do data-state="expanded" or "collapsed".
92 + // This makes it easier to style the sidebar with Tailwind classes.
93 + const state = open ? "expanded" : "collapsed";
94 +
95 + const contextValue = React.useMemo<SidebarContext>(
96 + () => ({
97 + state,
98 + open,
99 + setOpen,
100 + isMobile,
101 + openMobile,
102 + setOpenMobile,
103 + toggleSidebar,
104 + }),
105 + [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar],
106 + );
107 +
108 + return (
109 + <SidebarContext.Provider value={contextValue}>
110 + <TooltipProvider delayDuration={0}>
111 + <div
112 + style={
113 + {
114 + "--sidebar-width": SIDEBAR_WIDTH,
115 + "--sidebar-width-icon": SIDEBAR_WIDTH_ICON,
116 + ...style,
117 + } as React.CSSProperties
118 + }
119 + className={cn("group/sidebar-wrapper flex min-h-svh w-full has-[[data-variant=inset]]:bg-sidebar", className)}
120 + ref={ref}
121 + {...props}
122 + >
123 + {children}
124 + </div>
125 + </TooltipProvider>
126 + </SidebarContext.Provider>
127 + );
128 +});
129 +SidebarProvider.displayName = "SidebarProvider";
130 +
131 +const Sidebar = React.forwardRef<
132 + HTMLDivElement,
133 + React.ComponentProps<"div"> & {
134 + side?: "left" | "right";
135 + variant?: "sidebar" | "floating" | "inset";
136 + collapsible?: "offcanvas" | "icon" | "none";
137 + }
138 +>(({ side = "left", variant = "sidebar", collapsible = "offcanvas", className, children, ...props }, ref) => {
139 + const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
140 +
141 + if (collapsible === "none") {
142 + return (
143 + <div
144 + className={cn("flex h-full w-[--sidebar-width] flex-col bg-sidebar text-sidebar-foreground", className)}
145 + ref={ref}
146 + {...props}
147 + >
148 + {children}
149 + </div>
150 + );
151 + }
152 +
153 + if (isMobile) {
154 + return (
155 + <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>
156 + <SheetContent
157 + data-sidebar="sidebar"
158 + data-mobile="true"
159 + className="w-[--sidebar-width] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden"
160 + style={
161 + {
162 + "--sidebar-width": SIDEBAR_WIDTH_MOBILE,
163 + } as React.CSSProperties
164 + }
165 + side={side}
166 + >
167 + <div className="flex h-full w-full flex-col">{children}</div>
168 + </SheetContent>
169 + </Sheet>
170 + );
171 + }
172 +
173 + return (
174 + <div
175 + ref={ref}
176 + className="group peer hidden text-sidebar-foreground md:block"
177 + data-state={state}
178 + data-collapsible={state === "collapsed" ? collapsible : ""}
179 + data-variant={variant}
180 + data-side={side}
181 + >
182 + {/* This is what handles the sidebar gap on desktop */}
183 + <div
184 + className={cn(
185 + "relative h-svh w-[--sidebar-width] bg-transparent transition-[width] duration-200 ease-linear",
186 + "group-data-[collapsible=offcanvas]:w-0",
187 + "group-data-[side=right]:rotate-180",
188 + variant === "floating" || variant === "inset"
189 + ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4))]"
190 + : "group-data-[collapsible=icon]:w-[--sidebar-width-icon]",
191 + )}
192 + />
193 + <div
194 + className={cn(
195 + "fixed inset-y-0 z-10 hidden h-svh w-[--sidebar-width] transition-[left,right,width] duration-200 ease-linear md:flex",
196 + side === "left"
197 + ? "left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]"
198 + : "right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]",
199 + // Adjust the padding for floating and inset variants.
200 + variant === "floating" || variant === "inset"
201 + ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4)_+2px)]"
202 + : "group-data-[collapsible=icon]:w-[--sidebar-width-icon] group-data-[side=left]:border-r group-data-[side=right]:border-l",
203 + className,
204 + )}
205 + {...props}
206 + >
207 + <div
208 + data-sidebar="sidebar"
209 + className="flex h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow"
210 + >
211 + {children}
212 + </div>
213 + </div>
214 + </div>
215 + );
216 +});
217 +Sidebar.displayName = "Sidebar";
218 +
219 +const SidebarTrigger = React.forwardRef<React.ElementRef<typeof Button>, React.ComponentProps<typeof Button>>(
220 + ({ className, onClick, ...props }, ref) => {
221 + const { toggleSidebar } = useSidebar();
222 +
223 + return (
224 + <Button
225 + ref={ref}
226 + data-sidebar="trigger"
227 + variant="ghost"
228 + size="icon"
229 + className={cn("h-7 w-7", className)}
230 + onClick={(event) => {
231 + onClick?.(event);
232 + toggleSidebar();
233 + }}
234 + {...props}
235 + >
236 + <PanelLeft />
237 + <span className="sr-only">Toggle Sidebar</span>
238 + </Button>
239 + );
240 + },
241 +);
242 +SidebarTrigger.displayName = "SidebarTrigger";
243 +
244 +const SidebarRail = React.forwardRef<HTMLButtonElement, React.ComponentProps<"button">>(
245 + ({ className, ...props }, ref) => {
246 + const { toggleSidebar } = useSidebar();
247 +
248 + return (
249 + <button
250 + ref={ref}
251 + data-sidebar="rail"
252 + aria-label="Toggle Sidebar"
253 + tabIndex={-1}
254 + onClick={toggleSidebar}
255 + title="Toggle Sidebar"
256 + className={cn(
257 + "absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] group-data-[side=left]:-right-4 group-data-[side=right]:left-0 hover:after:bg-sidebar-border sm:flex",
258 + "[[data-side=left]_&]:cursor-w-resize [[data-side=right]_&]:cursor-e-resize",
259 + "[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize",
260 + "group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full group-data-[collapsible=offcanvas]:hover:bg-sidebar",
261 + "[[data-side=left][data-collapsible=offcanvas]_&]:-right-2",
262 + "[[data-side=right][data-collapsible=offcanvas]_&]:-left-2",
263 + className,
264 + )}
265 + {...props}
266 + />
267 + );
268 + },
269 +);
270 +SidebarRail.displayName = "SidebarRail";
271 +
272 +const SidebarInset = React.forwardRef<HTMLDivElement, React.ComponentProps<"main">>(({ className, ...props }, ref) => {
273 + return (
274 + <main
275 + ref={ref}
276 + className={cn(
277 + "relative flex min-h-svh flex-1 flex-col bg-background",
278 + "peer-data-[variant=inset]:min-h-[calc(100svh-theme(spacing.4))] md:peer-data-[variant=inset]:m-2 md:peer-data-[state=collapsed]:peer-data-[variant=inset]:ml-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow",
279 + className,
280 + )}
281 + {...props}
282 + />
283 + );
284 +});
285 +SidebarInset.displayName = "SidebarInset";
286 +
287 +const SidebarInput = React.forwardRef<React.ElementRef<typeof Input>, React.ComponentProps<typeof Input>>(
288 + ({ className, ...props }, ref) => {
289 + return (
290 + <Input
291 + ref={ref}
292 + data-sidebar="input"
293 + className={cn(
294 + "h-8 w-full bg-background shadow-none focus-visible:ring-2 focus-visible:ring-sidebar-ring",
295 + className,
296 + )}
297 + {...props}
298 + />
299 + );
300 + },
301 +);
302 +SidebarInput.displayName = "SidebarInput";
303 +
304 +const SidebarHeader = React.forwardRef<HTMLDivElement, React.ComponentProps<"div">>(({ className, ...props }, ref) => {
305 + return <div ref={ref} data-sidebar="header" className={cn("flex flex-col gap-2 p-2", className)} {...props} />;
306 +});
307 +SidebarHeader.displayName = "SidebarHeader";
308 +
309 +const SidebarFooter = React.forwardRef<HTMLDivElement, React.ComponentProps<"div">>(({ className, ...props }, ref) => {
310 + return <div ref={ref} data-sidebar="footer" className={cn("flex flex-col gap-2 p-2", className)} {...props} />;
311 +});
312 +SidebarFooter.displayName = "SidebarFooter";
313 +
314 +const SidebarSeparator = React.forwardRef<React.ElementRef<typeof Separator>, React.ComponentProps<typeof Separator>>(
315 + ({ className, ...props }, ref) => {
316 + return (
317 + <Separator
318 + ref={ref}
319 + data-sidebar="separator"
320 + className={cn("mx-2 w-auto bg-sidebar-border", className)}
321 + {...props}
322 + />
323 + );
324 + },
325 +);
326 +SidebarSeparator.displayName = "SidebarSeparator";
327 +
328 +const SidebarContent = React.forwardRef<HTMLDivElement, React.ComponentProps<"div">>(({ className, ...props }, ref) => {
329 + return (
330 + <div
331 + ref={ref}
332 + data-sidebar="content"
333 + className={cn(
334 + "flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden",
335 + className,
336 + )}
337 + {...props}
338 + />
339 + );
340 +});
341 +SidebarContent.displayName = "SidebarContent";
342 +
343 +const SidebarGroup = React.forwardRef<HTMLDivElement, React.ComponentProps<"div">>(({ className, ...props }, ref) => {
344 + return (
345 + <div
346 + ref={ref}
347 + data-sidebar="group"
348 + className={cn("relative flex w-full min-w-0 flex-col p-2", className)}
349 + {...props}
350 + />
351 + );
352 +});
353 +SidebarGroup.displayName = "SidebarGroup";
354 +
355 +const SidebarGroupLabel = React.forwardRef<HTMLDivElement, React.ComponentProps<"div"> & { asChild?: boolean }>(
356 + ({ className, asChild = false, ...props }, ref) => {
357 + const Comp = asChild ? Slot : "div";
358 +
359 + return (
360 + <Comp
361 + ref={ref}
362 + data-sidebar="group-label"
363 + className={cn(
364 + "flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 outline-none ring-sidebar-ring transition-[margin,opa] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
365 + "group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0",
366 + className,
367 + )}
368 + {...props}
369 + />
370 + );
371 + },
372 +);
373 +SidebarGroupLabel.displayName = "SidebarGroupLabel";
374 +
375 +const SidebarGroupAction = React.forwardRef<HTMLButtonElement, React.ComponentProps<"button"> & { asChild?: boolean }>(
376 + ({ className, asChild = false, ...props }, ref) => {
377 + const Comp = asChild ? Slot : "button";
378 +
379 + return (
380 + <Comp
381 + ref={ref}
382 + data-sidebar="group-action"
383 + className={cn(
384 + "absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
385 + // Increases the hit area of the button on mobile.
386 + "after:absolute after:-inset-2 after:md:hidden",
387 + "group-data-[collapsible=icon]:hidden",
388 + className,
389 + )}
390 + {...props}
391 + />
392 + );
393 + },
394 +);
395 +SidebarGroupAction.displayName = "SidebarGroupAction";
396 +
397 +const SidebarGroupContent = React.forwardRef<HTMLDivElement, React.ComponentProps<"div">>(
398 + ({ className, ...props }, ref) => (
399 + <div ref={ref} data-sidebar="group-content" className={cn("w-full text-sm", className)} {...props} />
400 + ),
401 +);
402 +SidebarGroupContent.displayName = "SidebarGroupContent";
403 +
404 +const SidebarMenu = React.forwardRef<HTMLUListElement, React.ComponentProps<"ul">>(({ className, ...props }, ref) => (
405 + <ul ref={ref} data-sidebar="menu" className={cn("flex w-full min-w-0 flex-col gap-1", className)} {...props} />
406 +));
407 +SidebarMenu.displayName = "SidebarMenu";
408 +
409 +const SidebarMenuItem = React.forwardRef<HTMLLIElement, React.ComponentProps<"li">>(({ className, ...props }, ref) => (
410 + <li ref={ref} data-sidebar="menu-item" className={cn("group/menu-item relative", className)} {...props} />
411 +));
412 +SidebarMenuItem.displayName = "SidebarMenuItem";
413 +
414 +const sidebarMenuButtonVariants = cva(
415 + "peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-none ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-[[data-sidebar=menu-action]]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:!size-8 group-data-[collapsible=icon]:!p-2 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
416 + {
417 + variants: {
418 + variant: {
419 + default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
420 + outline:
421 + "bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]",
422 + },
423 + size: {
424 + default: "h-8 text-sm",
425 + sm: "h-7 text-xs",
426 + lg: "h-12 text-sm group-data-[collapsible=icon]:!p-0",
427 + },
428 + },
429 + defaultVariants: {
430 + variant: "default",
431 + size: "default",
432 + },
433 + },
434 +);
435 +
436 +const SidebarMenuButton = React.forwardRef<
437 + HTMLButtonElement,
438 + React.ComponentProps<"button"> & {
439 + asChild?: boolean;
440 + isActive?: boolean;
441 + tooltip?: string | React.ComponentProps<typeof TooltipContent>;
442 + } & VariantProps<typeof sidebarMenuButtonVariants>
443 +>(({ asChild = false, isActive = false, variant = "default", size = "default", tooltip, className, ...props }, ref) => {
444 + const Comp = asChild ? Slot : "button";
445 + const { isMobile, state } = useSidebar();
446 +
447 + const button = (
448 + <Comp
449 + ref={ref}
450 + data-sidebar="menu-button"
451 + data-size={size}
452 + data-active={isActive}
453 + className={cn(sidebarMenuButtonVariants({ variant, size }), className)}
454 + {...props}
455 + />
456 + );
457 +
458 + if (!tooltip) {
459 + return button;
460 + }
461 +
462 + if (typeof tooltip === "string") {
463 + tooltip = {
464 + children: tooltip,
465 + };
466 + }
467 +
468 + return (
469 + <Tooltip>
470 + <TooltipTrigger asChild>{button}</TooltipTrigger>
471 + <TooltipContent side="right" align="center" hidden={state !== "collapsed" || isMobile} {...tooltip} />
472 + </Tooltip>
473 + );
474 +});
475 +SidebarMenuButton.displayName = "SidebarMenuButton";
476 +
477 +const SidebarMenuAction = React.forwardRef<
478 + HTMLButtonElement,
479 + React.ComponentProps<"button"> & {
480 + asChild?: boolean;
481 + showOnHover?: boolean;
482 + }
483 +>(({ className, asChild = false, showOnHover = false, ...props }, ref) => {
484 + const Comp = asChild ? Slot : "button";
485 +
486 + return (
487 + <Comp
488 + ref={ref}
489 + data-sidebar="menu-action"
490 + className={cn(
491 + "absolute right-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform peer-hover/menu-button:text-sidebar-accent-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
492 + // Increases the hit area of the button on mobile.
493 + "after:absolute after:-inset-2 after:md:hidden",
494 + "peer-data-[size=sm]/menu-button:top-1",
495 + "peer-data-[size=default]/menu-button:top-1.5",
496 + "peer-data-[size=lg]/menu-button:top-2.5",
497 + "group-data-[collapsible=icon]:hidden",
498 + showOnHover &&
499 + "group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground md:opacity-0",
500 + className,
501 + )}
502 + {...props}
503 + />
504 + );
505 +});
506 +SidebarMenuAction.displayName = "SidebarMenuAction";
507 +
508 +const SidebarMenuBadge = React.forwardRef<HTMLDivElement, React.ComponentProps<"div">>(
509 + ({ className, ...props }, ref) => (
510 + <div
511 + ref={ref}
512 + data-sidebar="menu-badge"
513 + className={cn(
514 + "pointer-events-none absolute right-1 flex h-5 min-w-5 select-none items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums text-sidebar-foreground",
515 + "peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground",
516 + "peer-data-[size=sm]/menu-button:top-1",
517 + "peer-data-[size=default]/menu-button:top-1.5",
518 + "peer-data-[size=lg]/menu-button:top-2.5",
519 + "group-data-[collapsible=icon]:hidden",
520 + className,
521 + )}
522 + {...props}
523 + />
524 + ),
525 +);
526 +SidebarMenuBadge.displayName = "SidebarMenuBadge";
527 +
528 +const SidebarMenuSkeleton = React.forwardRef<
529 + HTMLDivElement,
530 + React.ComponentProps<"div"> & {
531 + showIcon?: boolean;
532 + }
533 +>(({ className, showIcon = false, ...props }, ref) => {
534 + // Random width between 50 to 90%.
535 + const width = React.useMemo(() => {
536 + return `${Math.floor(Math.random() * 40) + 50}%`;
537 + }, []);
538 +
539 + return (
540 + <div
541 + ref={ref}
542 + data-sidebar="menu-skeleton"
543 + className={cn("flex h-8 items-center gap-2 rounded-md px-2", className)}
544 + {...props}
545 + >
546 + {showIcon && <Skeleton className="size-4 rounded-md" data-sidebar="menu-skeleton-icon" />}
547 + <Skeleton
548 + className="h-4 max-w-[--skeleton-width] flex-1"
549 + data-sidebar="menu-skeleton-text"
550 + style={
551 + {
552 + "--skeleton-width": width,
553 + } as React.CSSProperties
554 + }
555 + />
556 + </div>
557 + );
558 +});
559 +SidebarMenuSkeleton.displayName = "SidebarMenuSkeleton";
560 +
561 +const SidebarMenuSub = React.forwardRef<HTMLUListElement, React.ComponentProps<"ul">>(
562 + ({ className, ...props }, ref) => (
563 + <ul
564 + ref={ref}
565 + data-sidebar="menu-sub"
566 + className={cn(
567 + "mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5",
568 + "group-data-[collapsible=icon]:hidden",
569 + className,
570 + )}
571 + {...props}
572 + />
573 + ),
574 +);
575 +SidebarMenuSub.displayName = "SidebarMenuSub";
576 +
577 +const SidebarMenuSubItem = React.forwardRef<HTMLLIElement, React.ComponentProps<"li">>(({ ...props }, ref) => (
578 + <li ref={ref} {...props} />
579 +));
580 +SidebarMenuSubItem.displayName = "SidebarMenuSubItem";
581 +
582 +const SidebarMenuSubButton = React.forwardRef<
583 + HTMLAnchorElement,
584 + React.ComponentProps<"a"> & {
585 + asChild?: boolean;
586 + size?: "sm" | "md";
587 + isActive?: boolean;
588 + }
589 +>(({ asChild = false, size = "md", isActive, className, ...props }, ref) => {
590 + const Comp = asChild ? Slot : "a";
591 +
592 + return (
593 + <Comp
594 + ref={ref}
595 + data-sidebar="menu-sub-button"
596 + data-size={size}
597 + data-active={isActive}
598 + className={cn(
599 + "flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground outline-none ring-sidebar-ring aria-disabled:pointer-events-none aria-disabled:opacity-50 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground",
600 + "data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground",
601 + size === "sm" && "text-xs",
602 + size === "md" && "text-sm",
603 + "group-data-[collapsible=icon]:hidden",
604 + className,
605 + )}
606 + {...props}
607 + />
608 + );
609 +});
610 +SidebarMenuSubButton.displayName = "SidebarMenuSubButton";
611 +
612 +export {
613 + Sidebar,
614 + SidebarContent,
615 + SidebarFooter,
616 + SidebarGroup,
617 + SidebarGroupAction,
618 + SidebarGroupContent,
619 + SidebarGroupLabel,
620 + SidebarHeader,
621 + SidebarInput,
622 + SidebarInset,
623 + SidebarMenu,
624 + SidebarMenuAction,
625 + SidebarMenuBadge,
626 + SidebarMenuButton,
627 + SidebarMenuItem,
628 + SidebarMenuSkeleton,
629 + SidebarMenuSub,
630 + SidebarMenuSubButton,
631 + SidebarMenuSubItem,
632 + SidebarProvider,
633 + SidebarRail,
634 + SidebarSeparator,
635 + SidebarTrigger,
636 + useSidebar,
637 +};
src/components/ui/skeleton.tsx new
+7
@@ -0,0 +1,7 @@
1 +import { cn } from "@/lib/utils";
2 +
3 +function Skeleton({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
4 + return <div className={cn("animate-pulse rounded-md bg-muted", className)} {...props} />;
5 +}
6 +
7 +export { Skeleton };
src/components/ui/slider.tsx new
+23
@@ -0,0 +1,23 @@
1 +import * as React from "react";
2 +import * as SliderPrimitive from "@radix-ui/react-slider";
3 +
4 +import { cn } from "@/lib/utils";
5 +
6 +const Slider = React.forwardRef<
7 + React.ElementRef<typeof SliderPrimitive.Root>,
8 + React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root>
9 +>(({ className, ...props }, ref) => (
10 + <SliderPrimitive.Root
11 + ref={ref}
12 + className={cn("relative flex w-full touch-none select-none items-center", className)}
13 + {...props}
14 + >
15 + <SliderPrimitive.Track className="relative h-2 w-full grow overflow-hidden rounded-full bg-secondary">
16 + <SliderPrimitive.Range className="absolute h-full bg-primary" />
17 + </SliderPrimitive.Track>
18 + <SliderPrimitive.Thumb className="block h-5 w-5 rounded-full border-2 border-primary bg-background 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" />
19 + </SliderPrimitive.Root>
20 +));
21 +Slider.displayName = SliderPrimitive.Root.displayName;
22 +
23 +export { Slider };
src/components/ui/sonner.tsx new
+27
@@ -0,0 +1,27 @@
1 +import { useTheme } from "next-themes";
2 +import { Toaster as Sonner, toast } from "sonner";
3 +
4 +type ToasterProps = React.ComponentProps<typeof Sonner>;
5 +
6 +const Toaster = ({ ...props }: ToasterProps) => {
7 + const { theme = "system" } = useTheme();
8 +
9 + return (
10 + <Sonner
11 + theme={theme as ToasterProps["theme"]}
12 + className="toaster group"
13 + toastOptions={{
14 + classNames: {
15 + toast:
16 + "group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg",
17 + description: "group-[.toast]:text-muted-foreground",
18 + actionButton: "group-[.toast]:bg-primary group-[.toast]:text-primary-foreground",
19 + cancelButton: "group-[.toast]:bg-muted group-[.toast]:text-muted-foreground",
20 + },
21 + }}
22 + {...props}
23 + />
24 + );
25 +};
26 +
27 +export { Toaster, toast };
src/components/ui/switch.tsx new
+27
@@ -0,0 +1,27 @@
1 +import * as React from "react";
2 +import * as SwitchPrimitives from "@radix-ui/react-switch";
3 +
4 +import { cn } from "@/lib/utils";
5 +
6 +const Switch = React.forwardRef<
7 + React.ElementRef<typeof SwitchPrimitives.Root>,
8 + React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>
9 +>(({ className, ...props }, ref) => (
10 + <SwitchPrimitives.Root
11 + className={cn(
12 + "peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors data-[state=checked]:bg-primary data-[state=unchecked]:bg-input focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50",
13 + className,
14 + )}
15 + {...props}
16 + ref={ref}
17 + >
18 + <SwitchPrimitives.Thumb
19 + className={cn(
20 + "pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0",
21 + )}
22 + />
23 + </SwitchPrimitives.Root>
24 +));
25 +Switch.displayName = SwitchPrimitives.Root.displayName;
26 +
27 +export { Switch };
src/components/ui/table.tsx new
+72
@@ -0,0 +1,72 @@
1 +import * as React from "react";
2 +
3 +import { cn } from "@/lib/utils";
4 +
5 +const Table = React.forwardRef<HTMLTableElement, React.HTMLAttributes<HTMLTableElement>>(
6 + ({ className, ...props }, ref) => (
7 + <div className="relative w-full overflow-auto">
8 + <table ref={ref} className={cn("w-full caption-bottom text-sm", className)} {...props} />
9 + </div>
10 + ),
11 +);
12 +Table.displayName = "Table";
13 +
14 +const TableHeader = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(
15 + ({ className, ...props }, ref) => <thead ref={ref} className={cn("[&_tr]:border-b", className)} {...props} />,
16 +);
17 +TableHeader.displayName = "TableHeader";
18 +
19 +const TableBody = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(
20 + ({ className, ...props }, ref) => (
21 + <tbody ref={ref} className={cn("[&_tr:last-child]:border-0", className)} {...props} />
22 + ),
23 +);
24 +TableBody.displayName = "TableBody";
25 +
26 +const TableFooter = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(
27 + ({ className, ...props }, ref) => (
28 + <tfoot ref={ref} className={cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", className)} {...props} />
29 + ),
30 +);
31 +TableFooter.displayName = "TableFooter";
32 +
33 +const TableRow = React.forwardRef<HTMLTableRowElement, React.HTMLAttributes<HTMLTableRowElement>>(
34 + ({ className, ...props }, ref) => (
35 + <tr
36 + ref={ref}
37 + className={cn("border-b transition-colors data-[state=selected]:bg-muted hover:bg-muted/50", className)}
38 + {...props}
39 + />
40 + ),
41 +);
42 +TableRow.displayName = "TableRow";
43 +
44 +const TableHead = React.forwardRef<HTMLTableCellElement, React.ThHTMLAttributes<HTMLTableCellElement>>(
45 + ({ className, ...props }, ref) => (
46 + <th
47 + ref={ref}
48 + className={cn(
49 + "h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",
50 + className,
51 + )}
52 + {...props}
53 + />
54 + ),
55 +);
56 +TableHead.displayName = "TableHead";
57 +
58 +const TableCell = React.forwardRef<HTMLTableCellElement, React.TdHTMLAttributes<HTMLTableCellElement>>(
59 + ({ className, ...props }, ref) => (
60 + <td ref={ref} className={cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className)} {...props} />
61 + ),
62 +);
63 +TableCell.displayName = "TableCell";
64 +
65 +const TableCaption = React.forwardRef<HTMLTableCaptionElement, React.HTMLAttributes<HTMLTableCaptionElement>>(
66 + ({ className, ...props }, ref) => (
67 + <caption ref={ref} className={cn("mt-4 text-sm text-muted-foreground", className)} {...props} />
68 + ),
69 +);
70 +TableCaption.displayName = "TableCaption";
71 +
72 +export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption };
src/components/ui/tabs.tsx new
+53
@@ -0,0 +1,53 @@
1 +import * as React from "react";
2 +import * as TabsPrimitive from "@radix-ui/react-tabs";
3 +
4 +import { cn } from "@/lib/utils";
5 +
6 +const Tabs = TabsPrimitive.Root;
7 +
8 +const TabsList = React.forwardRef<
9 + React.ElementRef<typeof TabsPrimitive.List>,
10 + React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
11 +>(({ className, ...props }, ref) => (
12 + <TabsPrimitive.List
13 + ref={ref}
14 + className={cn(
15 + "inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
16 + className,
17 + )}
18 + {...props}
19 + />
20 +));
21 +TabsList.displayName = TabsPrimitive.List.displayName;
22 +
23 +const TabsTrigger = React.forwardRef<
24 + React.ElementRef<typeof TabsPrimitive.Trigger>,
25 + React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
26 +>(({ className, ...props }, ref) => (
27 + <TabsPrimitive.Trigger
28 + ref={ref}
29 + className={cn(
30 + "inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
31 + className,
32 + )}
33 + {...props}
34 + />
35 +));
36 +TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
37 +
38 +const TabsContent = React.forwardRef<
39 + React.ElementRef<typeof TabsPrimitive.Content>,
40 + React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
41 +>(({ className, ...props }, ref) => (
42 + <TabsPrimitive.Content
43 + ref={ref}
44 + className={cn(
45 + "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
46 + className,
47 + )}
48 + {...props}
49 + />
50 +));
51 +TabsContent.displayName = TabsPrimitive.Content.displayName;
52 +
53 +export { Tabs, TabsList, TabsTrigger, TabsContent };
src/components/ui/textarea.tsx new
+21
@@ -0,0 +1,21 @@
1 +import * as React from "react";
2 +
3 +import { cn } from "@/lib/utils";
4 +
5 +export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
6 +
7 +const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(({ className, ...props }, ref) => {
8 + return (
9 + <textarea
10 + className={cn(
11 + "flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
12 + className,
13 + )}
14 + ref={ref}
15 + {...props}
16 + />
17 + );
18 +});
19 +Textarea.displayName = "Textarea";
20 +
21 +export { Textarea };
src/components/ui/toast.tsx new
+111
@@ -0,0 +1,111 @@
1 +import * as React from "react";
2 +import * as ToastPrimitives from "@radix-ui/react-toast";
3 +import { cva, type VariantProps } from "class-variance-authority";
4 +import { X } from "lucide-react";
5 +
6 +import { cn } from "@/lib/utils";
7 +
8 +const ToastProvider = ToastPrimitives.Provider;
9 +
10 +const ToastViewport = React.forwardRef<
11 + React.ElementRef<typeof ToastPrimitives.Viewport>,
12 + React.ComponentPropsWithoutRef<typeof ToastPrimitives.Viewport>
13 +>(({ className, ...props }, ref) => (
14 + <ToastPrimitives.Viewport
15 + ref={ref}
16 + className={cn(
17 + "fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]",
18 + className,
19 + )}
20 + {...props}
21 + />
22 +));
23 +ToastViewport.displayName = ToastPrimitives.Viewport.displayName;
24 +
25 +const toastVariants = cva(
26 + "group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full",
27 + {
28 + variants: {
29 + variant: {
30 + default: "border bg-background text-foreground",
31 + destructive: "destructive group border-destructive bg-destructive text-destructive-foreground",
32 + },
33 + },
34 + defaultVariants: {
35 + variant: "default",
36 + },
37 + },
38 +);
39 +
40 +const Toast = React.forwardRef<
41 + React.ElementRef<typeof ToastPrimitives.Root>,
42 + React.ComponentPropsWithoutRef<typeof ToastPrimitives.Root> & VariantProps<typeof toastVariants>
43 +>(({ className, variant, ...props }, ref) => {
44 + return <ToastPrimitives.Root ref={ref} className={cn(toastVariants({ variant }), className)} {...props} />;
45 +});
46 +Toast.displayName = ToastPrimitives.Root.displayName;
47 +
48 +const ToastAction = React.forwardRef<
49 + React.ElementRef<typeof ToastPrimitives.Action>,
50 + React.ComponentPropsWithoutRef<typeof ToastPrimitives.Action>
51 +>(({ className, ...props }, ref) => (
52 + <ToastPrimitives.Action
53 + ref={ref}
54 + className={cn(
55 + "inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium ring-offset-background transition-colors group-[.destructive]:border-muted/40 hover:bg-secondary group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 group-[.destructive]:focus:ring-destructive disabled:pointer-events-none disabled:opacity-50",
56 + className,
57 + )}
58 + {...props}
59 + />
60 +));
61 +ToastAction.displayName = ToastPrimitives.Action.displayName;
62 +
63 +const ToastClose = React.forwardRef<
64 + React.ElementRef<typeof ToastPrimitives.Close>,
65 + React.ComponentPropsWithoutRef<typeof ToastPrimitives.Close>
66 +>(({ className, ...props }, ref) => (
67 + <ToastPrimitives.Close
68 + ref={ref}
69 + className={cn(
70 + "absolute right-2 top-2 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity group-hover:opacity-100 group-[.destructive]:text-red-300 hover:text-foreground group-[.destructive]:hover:text-red-50 focus:opacity-100 focus:outline-none focus:ring-2 group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600",
71 + className,
72 + )}
73 + toast-close=""
74 + {...props}
75 + >
76 + <X className="h-4 w-4" />
77 + </ToastPrimitives.Close>
78 +));
79 +ToastClose.displayName = ToastPrimitives.Close.displayName;
80 +
81 +const ToastTitle = React.forwardRef<
82 + React.ElementRef<typeof ToastPrimitives.Title>,
83 + React.ComponentPropsWithoutRef<typeof ToastPrimitives.Title>
84 +>(({ className, ...props }, ref) => (
85 + <ToastPrimitives.Title ref={ref} className={cn("text-sm font-semibold", className)} {...props} />
86 +));
87 +ToastTitle.displayName = ToastPrimitives.Title.displayName;
88 +
89 +const ToastDescription = React.forwardRef<
90 + React.ElementRef<typeof ToastPrimitives.Description>,
91 + React.ComponentPropsWithoutRef<typeof ToastPrimitives.Description>
92 +>(({ className, ...props }, ref) => (
93 + <ToastPrimitives.Description ref={ref} className={cn("text-sm opacity-90", className)} {...props} />
94 +));
95 +ToastDescription.displayName = ToastPrimitives.Description.displayName;
96 +
97 +type ToastProps = React.ComponentPropsWithoutRef<typeof Toast>;
98 +
99 +type ToastActionElement = React.ReactElement<typeof ToastAction>;
100 +
101 +export {
102 + type ToastProps,
103 + type ToastActionElement,
104 + ToastProvider,
105 + ToastViewport,
106 + Toast,
107 + ToastTitle,
108 + ToastDescription,
109 + ToastClose,
110 + ToastAction,
111 +};
src/components/ui/toaster.tsx new
+24
@@ -0,0 +1,24 @@
1 +import { useToast } from "@/hooks/use-toast";
2 +import { Toast, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport } from "@/components/ui/toast";
3 +
4 +export function Toaster() {
5 + const { toasts } = useToast();
6 +
7 + return (
8 + <ToastProvider>
9 + {toasts.map(function ({ id, title, description, action, ...props }) {
10 + return (
11 + <Toast key={id} {...props}>
12 + <div className="grid gap-1">
13 + {title && <ToastTitle>{title}</ToastTitle>}
14 + {description && <ToastDescription>{description}</ToastDescription>}
15 + </div>
16 + {action}
17 + <ToastClose />
18 + </Toast>
19 + );
20 + })}
21 + <ToastViewport />
22 + </ToastProvider>
23 + );
24 +}
src/components/ui/toggle-group.tsx new
+49
@@ -0,0 +1,49 @@
1 +import * as React from "react";
2 +import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group";
3 +import { type VariantProps } from "class-variance-authority";
4 +
5 +import { cn } from "@/lib/utils";
6 +import { toggleVariants } from "@/components/ui/toggle";
7 +
8 +const ToggleGroupContext = React.createContext<VariantProps<typeof toggleVariants>>({
9 + size: "default",
10 + variant: "default",
11 +});
12 +
13 +const ToggleGroup = React.forwardRef<
14 + React.ElementRef<typeof ToggleGroupPrimitive.Root>,
15 + React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Root> & VariantProps<typeof toggleVariants>
16 +>(({ className, variant, size, children, ...props }, ref) => (
17 + <ToggleGroupPrimitive.Root ref={ref} className={cn("flex items-center justify-center gap-1", className)} {...props}>
18 + <ToggleGroupContext.Provider value={{ variant, size }}>{children}</ToggleGroupContext.Provider>
19 + </ToggleGroupPrimitive.Root>
20 +));
21 +
22 +ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName;
23 +
24 +const ToggleGroupItem = React.forwardRef<
25 + React.ElementRef<typeof ToggleGroupPrimitive.Item>,
26 + React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Item> & VariantProps<typeof toggleVariants>
27 +>(({ className, children, variant, size, ...props }, ref) => {
28 + const context = React.useContext(ToggleGroupContext);
29 +
30 + return (
31 + <ToggleGroupPrimitive.Item
32 + ref={ref}
33 + className={cn(
34 + toggleVariants({
35 + variant: context.variant || variant,
36 + size: context.size || size,
37 + }),
38 + className,
39 + )}
40 + {...props}
41 + >
42 + {children}
43 + </ToggleGroupPrimitive.Item>
44 + );
45 +});
46 +
47 +ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;
48 +
49 +export { ToggleGroup, ToggleGroupItem };
src/components/ui/toggle.tsx new
+37
@@ -0,0 +1,37 @@
1 +import * as React from "react";
2 +import * as TogglePrimitive from "@radix-ui/react-toggle";
3 +import { cva, type VariantProps } from "class-variance-authority";
4 +
5 +import { cn } from "@/lib/utils";
6 +
7 +const toggleVariants = cva(
8 + "inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground",
9 + {
10 + variants: {
11 + variant: {
12 + default: "bg-transparent",
13 + outline: "border border-input bg-transparent hover:bg-accent hover:text-accent-foreground",
14 + },
15 + size: {
16 + default: "h-10 px-3",
17 + sm: "h-9 px-2.5",
18 + lg: "h-11 px-5",
19 + },
20 + },
21 + defaultVariants: {
22 + variant: "default",
23 + size: "default",
24 + },
25 + },
26 +);
27 +
28 +const Toggle = React.forwardRef<
29 + React.ElementRef<typeof TogglePrimitive.Root>,
30 + React.ComponentPropsWithoutRef<typeof TogglePrimitive.Root> & VariantProps<typeof toggleVariants>
31 +>(({ className, variant, size, ...props }, ref) => (
32 + <TogglePrimitive.Root ref={ref} className={cn(toggleVariants({ variant, size, className }))} {...props} />
33 +));
34 +
35 +Toggle.displayName = TogglePrimitive.Root.displayName;
36 +
37 +export { Toggle, toggleVariants };
src/components/ui/tooltip.tsx new
+28
@@ -0,0 +1,28 @@
1 +import * as React from "react";
2 +import * as TooltipPrimitive from "@radix-ui/react-tooltip";
3 +
4 +import { cn } from "@/lib/utils";
5 +
6 +const TooltipProvider = TooltipPrimitive.Provider;
7 +
8 +const Tooltip = TooltipPrimitive.Root;
9 +
10 +const TooltipTrigger = TooltipPrimitive.Trigger;
11 +
12 +const TooltipContent = React.forwardRef<
13 + React.ElementRef<typeof TooltipPrimitive.Content>,
14 + React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
15 +>(({ className, sideOffset = 4, ...props }, ref) => (
16 + <TooltipPrimitive.Content
17 + ref={ref}
18 + sideOffset={sideOffset}
19 + className={cn(
20 + "z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
21 + className,
22 + )}
23 + {...props}
24 + />
25 +));
26 +TooltipContent.displayName = TooltipPrimitive.Content.displayName;
27 +
28 +export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
src/components/ui/use-toast.ts new
+3
@@ -0,0 +1,3 @@
1 +import { useToast, toast } from "@/hooks/use-toast";
2 +
3 +export { useToast, toast };
src/hooks/use-mobile.tsx new
+19
@@ -0,0 +1,19 @@
1 +import * as React from "react";
2 +
3 +const MOBILE_BREAKPOINT = 768;
4 +
5 +export function useIsMobile() {
6 + const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined);
7 +
8 + React.useEffect(() => {
9 + const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
10 + const onChange = () => {
11 + setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
12 + };
13 + mql.addEventListener("change", onChange);
14 + setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
15 + return () => mql.removeEventListener("change", onChange);
16 + }, []);
17 +
18 + return !!isMobile;
19 +}
src/hooks/use-toast.ts new
+186
@@ -0,0 +1,186 @@
1 +import * as React from "react";
2 +
3 +import type { ToastActionElement, ToastProps } from "@/components/ui/toast";
4 +
5 +const TOAST_LIMIT = 1;
6 +const TOAST_REMOVE_DELAY = 1000000;
7 +
8 +type ToasterToast = ToastProps & {
9 + id: string;
10 + title?: React.ReactNode;
11 + description?: React.ReactNode;
12 + action?: ToastActionElement;
13 +};
14 +
15 +const actionTypes = {
16 + ADD_TOAST: "ADD_TOAST",
17 + UPDATE_TOAST: "UPDATE_TOAST",
18 + DISMISS_TOAST: "DISMISS_TOAST",
19 + REMOVE_TOAST: "REMOVE_TOAST",
20 +} as const;
21 +
22 +let count = 0;
23 +
24 +function genId() {
25 + count = (count + 1) % Number.MAX_SAFE_INTEGER;
26 + return count.toString();
27 +}
28 +
29 +type ActionType = typeof actionTypes;
30 +
31 +type Action =
32 + | {
33 + type: ActionType["ADD_TOAST"];
34 + toast: ToasterToast;
35 + }
36 + | {
37 + type: ActionType["UPDATE_TOAST"];
38 + toast: Partial<ToasterToast>;
39 + }
40 + | {
41 + type: ActionType["DISMISS_TOAST"];
42 + toastId?: ToasterToast["id"];
43 + }
44 + | {
45 + type: ActionType["REMOVE_TOAST"];
46 + toastId?: ToasterToast["id"];
47 + };
48 +
49 +interface State {
50 + toasts: ToasterToast[];
51 +}
52 +
53 +const toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>();
54 +
55 +const addToRemoveQueue = (toastId: string) => {
56 + if (toastTimeouts.has(toastId)) {
57 + return;
58 + }
59 +
60 + const timeout = setTimeout(() => {
61 + toastTimeouts.delete(toastId);
62 + dispatch({
63 + type: "REMOVE_TOAST",
64 + toastId: toastId,
65 + });
66 + }, TOAST_REMOVE_DELAY);
67 +
68 + toastTimeouts.set(toastId, timeout);
69 +};
70 +
71 +export const reducer = (state: State, action: Action): State => {
72 + switch (action.type) {
73 + case "ADD_TOAST":
74 + return {
75 + ...state,
76 + toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),
77 + };
78 +
79 + case "UPDATE_TOAST":
80 + return {
81 + ...state,
82 + toasts: state.toasts.map((t) => (t.id === action.toast.id ? { ...t, ...action.toast } : t)),
83 + };
84 +
85 + case "DISMISS_TOAST": {
86 + const { toastId } = action;
87 +
88 + // ! Side effects ! - This could be extracted into a dismissToast() action,
89 + // but I'll keep it here for simplicity
90 + if (toastId) {
91 + addToRemoveQueue(toastId);
92 + } else {
93 + state.toasts.forEach((toast) => {
94 + addToRemoveQueue(toast.id);
95 + });
96 + }
97 +
98 + return {
99 + ...state,
100 + toasts: state.toasts.map((t) =>
101 + t.id === toastId || toastId === undefined
102 + ? {
103 + ...t,
104 + open: false,
105 + }
106 + : t,
107 + ),
108 + };
109 + }
110 + case "REMOVE_TOAST":
111 + if (action.toastId === undefined) {
112 + return {
113 + ...state,
114 + toasts: [],
115 + };
116 + }
117 + return {
118 + ...state,
119 + toasts: state.toasts.filter((t) => t.id !== action.toastId),
120 + };
121 + }
122 +};
123 +
124 +const listeners: Array<(state: State) => void> = [];
125 +
126 +let memoryState: State = { toasts: [] };
127 +
128 +function dispatch(action: Action) {
129 + memoryState = reducer(memoryState, action);
130 + listeners.forEach((listener) => {
131 + listener(memoryState);
132 + });
133 +}
134 +
135 +type Toast = Omit<ToasterToast, "id">;
136 +
137 +function toast({ ...props }: Toast) {
138 + const id = genId();
139 +
140 + const update = (props: ToasterToast) =>
141 + dispatch({
142 + type: "UPDATE_TOAST",
143 + toast: { ...props, id },
144 + });
145 + const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id });
146 +
147 + dispatch({
148 + type: "ADD_TOAST",
149 + toast: {
150 + ...props,
151 + id,
152 + open: true,
153 + onOpenChange: (open) => {
154 + if (!open) dismiss();
155 + },
156 + },
157 + });
158 +
159 + return {
160 + id: id,
161 + dismiss,
162 + update,
163 + };
164 +}
165 +
166 +function useToast() {
167 + const [state, setState] = React.useState<State>(memoryState);
168 +
169 + React.useEffect(() => {
170 + listeners.push(setState);
171 + return () => {
172 + const index = listeners.indexOf(setState);
173 + if (index > -1) {
174 + listeners.splice(index, 1);
175 + }
176 + };
177 + }, [state]);
178 +
179 + return {
180 + ...state,
181 + toast,
182 + dismiss: (toastId?: string) => dispatch({ type: "DISMISS_TOAST", toastId }),
183 + };
184 +}
185 +
186 +export { useToast, toast };
src/index.css new
+105
@@ -0,0 +1,105 @@
1 +@tailwind base;
2 +@tailwind components;
3 +@tailwind utilities;
4 +
5 +/* Definition of the design system. All colors, gradients, fonts, etc should be defined here.
6 +All colors MUST be HSL.
7 +*/
8 +
9 +@layer base {
10 + :root {
11 + --background: 0 0% 100%;
12 + --foreground: 222.2 84% 4.9%;
13 +
14 + --card: 0 0% 100%;
15 + --card-foreground: 222.2 84% 4.9%;
16 +
17 + --popover: 0 0% 100%;
18 + --popover-foreground: 222.2 84% 4.9%;
19 +
20 + --primary: 222.2 47.4% 11.2%;
21 + --primary-foreground: 210 40% 98%;
22 +
23 + --secondary: 210 40% 96.1%;
24 + --secondary-foreground: 222.2 47.4% 11.2%;
25 +
26 + --muted: 210 40% 96.1%;
27 + --muted-foreground: 215.4 16.3% 46.9%;
28 +
29 + --accent: 210 40% 96.1%;
30 + --accent-foreground: 222.2 47.4% 11.2%;
31 +
32 + --destructive: 0 84.2% 60.2%;
33 + --destructive-foreground: 210 40% 98%;
34 +
35 + --border: 214.3 31.8% 91.4%;
36 + --input: 214.3 31.8% 91.4%;
37 + --ring: 222.2 84% 4.9%;
38 +
39 + --radius: 0.5rem;
40 +
41 + --sidebar-background: 0 0% 98%;
42 +
43 + --sidebar-foreground: 240 5.3% 26.1%;
44 +
45 + --sidebar-primary: 240 5.9% 10%;
46 +
47 + --sidebar-primary-foreground: 0 0% 98%;
48 +
49 + --sidebar-accent: 240 4.8% 95.9%;
50 +
51 + --sidebar-accent-foreground: 240 5.9% 10%;
52 +
53 + --sidebar-border: 220 13% 91%;
54 +
55 + --sidebar-ring: 217.2 91.2% 59.8%;
56 + }
57 +
58 + .dark {
59 + --background: 222.2 84% 4.9%;
60 + --foreground: 210 40% 98%;
61 +
62 + --card: 222.2 84% 4.9%;
63 + --card-foreground: 210 40% 98%;
64 +
65 + --popover: 222.2 84% 4.9%;
66 + --popover-foreground: 210 40% 98%;
67 +
68 + --primary: 210 40% 98%;
69 + --primary-foreground: 222.2 47.4% 11.2%;
70 +
71 + --secondary: 217.2 32.6% 17.5%;
72 + --secondary-foreground: 210 40% 98%;
73 +
74 + --muted: 217.2 32.6% 17.5%;
75 + --muted-foreground: 215 20.2% 65.1%;
76 +
77 + --accent: 217.2 32.6% 17.5%;
78 + --accent-foreground: 210 40% 98%;
79 +
80 + --destructive: 0 62.8% 30.6%;
81 + --destructive-foreground: 210 40% 98%;
82 +
83 + --border: 217.2 32.6% 17.5%;
84 + --input: 217.2 32.6% 17.5%;
85 + --ring: 212.7 26.8% 83.9%;
86 + --sidebar-background: 240 5.9% 10%;
87 + --sidebar-foreground: 240 4.8% 95.9%;
88 + --sidebar-primary: 224.3 76.3% 48%;
89 + --sidebar-primary-foreground: 0 0% 100%;
90 + --sidebar-accent: 240 3.7% 15.9%;
91 + --sidebar-accent-foreground: 240 4.8% 95.9%;
92 + --sidebar-border: 240 3.7% 15.9%;
93 + --sidebar-ring: 217.2 91.2% 59.8%;
94 + }
95 +}
96 +
97 +@layer base {
98 + * {
99 + @apply border-border;
100 + }
101 +
102 + body {
103 + @apply bg-background text-foreground;
104 + }
105 +}
src/lib/utils.ts new
+6
@@ -0,0 +1,6 @@
1 +import { clsx, type ClassValue } from "clsx";
2 +import { twMerge } from "tailwind-merge";
3 +
4 +export function cn(...inputs: ClassValue[]) {
5 + return twMerge(clsx(inputs));
6 +}
src/main.tsx new
+5
@@ -0,0 +1,5 @@
1 +import { createRoot } from "react-dom/client";
2 +import App from "./App.tsx";
3 +import "./index.css";
4 +
5 +createRoot(document.getElementById("root")!).render(<App />);
src/pages/Index.tsx new
+14
@@ -0,0 +1,14 @@
1 +// Update this page (the content is just a fallback if you fail to update the page)
2 +
3 +const Index = () => {
4 + return (
5 + <div className="flex min-h-screen items-center justify-center bg-background">
6 + <div className="text-center">
7 + <h1 className="mb-4 text-4xl font-bold">Welcome to Your Blank App</h1>
8 + <p className="text-xl text-muted-foreground">Start building your amazing project here!</p>
9 + </div>
10 + </div>
11 + );
12 +};
13 +
14 +export default Index;
src/pages/NotFound.tsx new
+24
@@ -0,0 +1,24 @@
1 +import { useLocation } from "react-router-dom";
2 +import { useEffect } from "react";
3 +
4 +const NotFound = () => {
5 + const location = useLocation();
6 +
7 + useEffect(() => {
8 + console.error("404 Error: User attempted to access non-existent route:", location.pathname);
9 + }, [location.pathname]);
10 +
11 + return (
12 + <div className="flex min-h-screen items-center justify-center bg-muted">
13 + <div className="text-center">
14 + <h1 className="mb-4 text-4xl font-bold">404</h1>
15 + <p className="mb-4 text-xl text-muted-foreground">Oops! Page not found</p>
16 + <a href="/" className="text-primary underline hover:text-primary/90">
17 + Return to Home
18 + </a>
19 + </div>
20 + </div>
21 + );
22 +};
23 +
24 +export default NotFound;
src/vite-env.d.ts new
+1
@@ -0,0 +1 @@
1 +/// <reference types="vite/client" />
tailwind.config.ts new
+91
@@ -0,0 +1,91 @@
1 +import type { Config } from "tailwindcss";
2 +
3 +export default {
4 + darkMode: ["class"],
5 + content: ["./pages/**/*.{ts,tsx}", "./components/**/*.{ts,tsx}", "./app/**/*.{ts,tsx}", "./src/**/*.{ts,tsx}"],
6 + prefix: "",
7 + theme: {
8 + container: {
9 + center: true,
10 + padding: "2rem",
11 + screens: {
12 + "2xl": "1400px",
13 + },
14 + },
15 + extend: {
16 + colors: {
17 + border: "hsl(var(--border))",
18 + input: "hsl(var(--input))",
19 + ring: "hsl(var(--ring))",
20 + background: "hsl(var(--background))",
21 + foreground: "hsl(var(--foreground))",
22 + primary: {
23 + DEFAULT: "hsl(var(--primary))",
24 + foreground: "hsl(var(--primary-foreground))",
25 + },
26 + secondary: {
27 + DEFAULT: "hsl(var(--secondary))",
28 + foreground: "hsl(var(--secondary-foreground))",
29 + },
30 + destructive: {
31 + DEFAULT: "hsl(var(--destructive))",
32 + foreground: "hsl(var(--destructive-foreground))",
33 + },
34 + muted: {
35 + DEFAULT: "hsl(var(--muted))",
36 + foreground: "hsl(var(--muted-foreground))",
37 + },
38 + accent: {
39 + DEFAULT: "hsl(var(--accent))",
40 + foreground: "hsl(var(--accent-foreground))",
41 + },
42 + popover: {
43 + DEFAULT: "hsl(var(--popover))",
44 + foreground: "hsl(var(--popover-foreground))",
45 + },
46 + card: {
47 + DEFAULT: "hsl(var(--card))",
48 + foreground: "hsl(var(--card-foreground))",
49 + },
50 + sidebar: {
51 + DEFAULT: "hsl(var(--sidebar-background))",
52 + foreground: "hsl(var(--sidebar-foreground))",
53 + primary: "hsl(var(--sidebar-primary))",
54 + "primary-foreground": "hsl(var(--sidebar-primary-foreground))",
55 + accent: "hsl(var(--sidebar-accent))",
56 + "accent-foreground": "hsl(var(--sidebar-accent-foreground))",
57 + border: "hsl(var(--sidebar-border))",
58 + ring: "hsl(var(--sidebar-ring))",
59 + },
60 + },
61 + borderRadius: {
62 + lg: "var(--radius)",
63 + md: "calc(var(--radius) - 2px)",
64 + sm: "calc(var(--radius) - 4px)",
65 + },
66 + keyframes: {
67 + "accordion-down": {
68 + from: {
69 + height: "0",
70 + },
71 + to: {
72 + height: "var(--radix-accordion-content-height)",
73 + },
74 + },
75 + "accordion-up": {
76 + from: {
77 + height: "var(--radix-accordion-content-height)",
78 + },
79 + to: {
80 + height: "0",
81 + },
82 + },
83 + },
84 + animation: {
85 + "accordion-down": "accordion-down 0.2s ease-out",
86 + "accordion-up": "accordion-up 0.2s ease-out",
87 + },
88 + },
89 + },
90 + plugins: [require("tailwindcss-animate")],
91 +} satisfies Config;
tsconfig.app.json new
+30
@@ -0,0 +1,30 @@
1 +{
2 + "compilerOptions": {
3 + "target": "ES2020",
4 + "useDefineForClassFields": true,
5 + "lib": ["ES2020", "DOM", "DOM.Iterable"],
6 + "module": "ESNext",
7 + "skipLibCheck": true,
8 +
9 + /* Bundler mode */
10 + "moduleResolution": "bundler",
11 + "allowImportingTsExtensions": true,
12 + "isolatedModules": true,
13 + "moduleDetection": "force",
14 + "noEmit": true,
15 + "jsx": "react-jsx",
16 +
17 + /* Linting */
18 + "strict": false,
19 + "noUnusedLocals": false,
20 + "noUnusedParameters": false,
21 + "noImplicitAny": false,
22 + "noFallthroughCasesInSwitch": false,
23 +
24 + "baseUrl": ".",
25 + "paths": {
26 + "@/*": ["./src/*"]
27 + }
28 + },
29 + "include": ["src"]
30 +}
tsconfig.json new
+16
@@ -0,0 +1,16 @@
1 +{
2 + "files": [],
3 + "references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }],
4 + "compilerOptions": {
5 + "baseUrl": ".",
6 + "paths": {
7 + "@/*": ["./src/*"]
8 + },
9 + "noImplicitAny": false,
10 + "noUnusedParameters": false,
11 + "skipLibCheck": true,
12 + "allowJs": true,
13 + "noUnusedLocals": false,
14 + "strictNullChecks": false
15 + }
16 +}
tsconfig.node.json new
+22
@@ -0,0 +1,22 @@
1 +{
2 + "compilerOptions": {
3 + "target": "ES2022",
4 + "lib": ["ES2023"],
5 + "module": "ESNext",
6 + "skipLibCheck": true,
7 +
8 + /* Bundler mode */
9 + "moduleResolution": "bundler",
10 + "allowImportingTsExtensions": true,
11 + "isolatedModules": true,
12 + "moduleDetection": "force",
13 + "noEmit": true,
14 +
15 + /* Linting */
16 + "strict": true,
17 + "noUnusedLocals": false,
18 + "noUnusedParameters": false,
19 + "noFallthroughCasesInSwitch": true
20 + },
21 + "include": ["vite.config.ts"]
22 +}
vite.config.ts new
+18
@@ -0,0 +1,18 @@
1 +import { defineConfig } from "vite";
2 +import react from "@vitejs/plugin-react-swc";
3 +import path from "path";
4 +import { componentTagger } from "lovable-tagger";
5 +
6 +// https://vitejs.dev/config/
7 +export default defineConfig(({ mode }) => ({
8 + server: {
9 + host: "::",
10 + port: 8080,
11 + },
12 + plugins: [react(), mode === "development" && componentTagger()].filter(Boolean),
13 + resolve: {
14 + alias: {
15 + "@": path.resolve(__dirname, "./src"),
16 + },
17 + },
18 +}));