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
+}));