├── .gitignore
├── README.md
├── eslint.config.js
├── index.html
├── package-lock.json
├── package.json
├── public
└── _redirects
├── src
├── components
│ ├── Footer.jsx
│ └── Navbar.jsx
├── context
│ └── FavoritesContext.jsx
├── images
│ └── IMG_9525-2-500x500.jpg
├── main.jsx
├── pages
│ ├── AddRecipe.jsx
│ ├── EditRecipe.jsx
│ ├── Home.jsx
│ ├── Login.jsx
│ ├── RecipeDetails.jsx
│ ├── RecipeList.jsx
│ ├── Signup.jsx
│ └── UserProfile.jsx
├── routes.jsx
└── styles.css
└── vite.config.js
/.gitignore:
--------------------------------------------------------------------------------
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?
25 |
26 | # Ignore environment files (important!)
27 | .env
28 | .env.local
29 | .env.*.local
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 🍲 Potluck App
2 |
3 | Welcome to the **Potluck App**, a full-stack recipe-sharing application built with the MERN stack (MongoDB, Express, React, Node.js). Users can browse, post, edit, delete, and save their favorite recipes. This app was developed as a capstone project for the CP 325.9 course.
4 |
5 | ---
6 |
7 | ## 🚀 Live Deployment
8 |
9 | 🔗 [Live Frontend App (Netlify)](https://potluck-app.netlify.app)
10 | 🌐 [Live Backend API (Render)](https://capstone-backend-zdhp.onrender.com)
11 |
12 |
13 | This site is fully connected to the backend API and supports real-time user authentication, recipe uploads, saving favorites, commenting, and more.
14 |
15 | ## 🛠 Environment Variables
16 |
17 | Make sure your `.env` file includes:
18 |
19 | VITE_API_URL=https://capstone-backend-zdhp.onrender.com
20 |
21 | ---
22 |
23 |
24 | ## 🔧 Technologies Used
25 | - **Frontend:** React, Vite, CSS
26 | - **Backend:** Node.js, Express
27 | - **Database:** MongoDB with Mongoose
28 | - **Authentication:** JWT (JSON Web Tokens)
29 | - **Other Libraries:** Axios, Multer
30 |
31 | ---
32 |
33 | ## 👥 User Features
34 | - Sign up and log in securely
35 | - Submit a recipe with image upload
36 | - Edit or delete your own recipes
37 | - Browse all recipes with search & category filter
38 | - View recipe details including ingredients and instructions
39 | - Comment on any recipe
40 | - Save recipes to your favorites
41 | - Profile page with created and favorite recipes
42 |
43 | ---
44 |
45 | ## 📂 Project Structure
46 |
47 | ```
48 | root
49 | ├── client/ # React Frontend
50 | │ ├── src/
51 | │ │ ├── pages/ # Main views (Home, Recipes, Details, Profile, etc.)
52 | │ │ ├── components/ # Reusable components (NavBar, Footer)
53 | │ │ ├── styles.css # Global styles
54 | │ │ └── main.jsx # Vite entry point
55 | │
56 | ├── server/ # Express Backend
57 | │ ├── routes/ # All route files (auth, recipes, users, etc.)
58 | │ ├── models/ # Mongoose schemas
59 | │ ├── middleware/ # Auth middleware
60 | │ └── server.js # Entry point
61 | ```
62 |
63 | ---
64 |
65 | ## 🚀 API Endpoints
66 |
67 | ### Authentication
68 | - `POST /api/auth/register` - Register new user
69 | - `POST /api/auth/login` - Login existing user
70 |
71 | ### Recipes
72 | - `GET /api/recipes` - Get all recipes (supports search & filter)
73 | - `GET /api/recipes/featured` - Get 6 random featured recipes
74 | - `GET /api/recipes/:id` - Get single recipe
75 | - `POST /api/recipes` - Create recipe (protected)
76 | - `PUT /api/recipes/:id` - Update recipe (protected)
77 | - `DELETE /api/recipes/:id` - Delete recipe (protected)
78 |
79 | ### Users & Favorites
80 | - `GET /api/users/:username/favorites` - Get user favorites
81 | - `POST /api/users/:username/favorites/:recipeId` - Add favorite
82 | - `DELETE /api/users/:username/favorites/:recipeId` - Remove favorite
83 |
84 | ### Comments
85 | - `POST /api/comments/:recipeId` - Add comment
86 | - `GET /api/comments/:recipeId` - Get comments for a recipe
87 |
88 | ---
89 |
90 | ## 🚑 Development & Deployment
91 | - Local development runs on `localhost:5173` for frontend and `localhost:5001` for backend
92 | - Images are uploaded to `/uploads` folder
93 | - CORS configured for local dev
94 |
95 | ---
96 |
97 | ## 🌈 Design & UI Highlights
98 | - Gradient hover effects on cards
99 | - Stylish pill-shaped ingredient tags
100 | - Badge-style comment bubbles
101 | - Avatar animation on profile
102 | - Smooth transitions, scaling, and pop hover effects
103 | - Responsive layout using CSS Grid and Flexbox
104 |
105 | ---
106 |
107 | ## 🎓 Developer Notes
108 | - Profile avatars were explored and removed for simplicity
109 | - All data is stored in MongoDB Atlas
110 | - Fully tested via Postman and browser for multiple users
111 |
112 | ---
113 |
114 | ## 🔹 Future Improvements
115 | - Dark mode
116 | - User avatars
117 | - Enhanced mobile gestures
118 |
119 | ---
120 |
121 | ## © 2025 Potluck App
122 | Made with ❤️ for the CP 325.9 Capstone Project
123 |
124 |
--------------------------------------------------------------------------------
/eslint.config.js:
--------------------------------------------------------------------------------
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 |
6 | export default [
7 | { ignores: ['dist'] },
8 | {
9 | files: ['**/*.{js,jsx}'],
10 | languageOptions: {
11 | ecmaVersion: 2020,
12 | globals: globals.browser,
13 | parserOptions: {
14 | ecmaVersion: 'latest',
15 | ecmaFeatures: { jsx: true },
16 | sourceType: 'module',
17 | },
18 | },
19 | plugins: {
20 | 'react-hooks': reactHooks,
21 | 'react-refresh': reactRefresh,
22 | },
23 | rules: {
24 | ...js.configs.recommended.rules,
25 | ...reactHooks.configs.recommended.rules,
26 | 'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
27 | 'react-refresh/only-export-components': [
28 | 'warn',
29 | { allowConstantExport: true },
30 | ],
31 | },
32 | },
33 | ]
34 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Potluck App
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "recipe-app",
3 | "version": "0.0.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "recipe-app",
9 | "version": "0.0.0",
10 | "dependencies": {
11 | "@reduxjs/toolkit": "^2.6.1",
12 | "axios": "^1.8.4",
13 | "react": "^19.0.0",
14 | "react-dom": "^19.0.0",
15 | "react-redux": "^9.2.0",
16 | "react-router-dom": "^7.4.0"
17 | },
18 | "devDependencies": {
19 | "@eslint/js": "^9.21.0",
20 | "@types/react": "^19.0.10",
21 | "@types/react-dom": "^19.0.4",
22 | "@vitejs/plugin-react": "^4.3.4",
23 | "eslint": "^9.21.0",
24 | "eslint-plugin-react-hooks": "^5.1.0",
25 | "eslint-plugin-react-refresh": "^0.4.19",
26 | "globals": "^15.15.0",
27 | "vite": "^6.2.0"
28 | }
29 | },
30 | "node_modules/@ampproject/remapping": {
31 | "version": "2.3.0",
32 | "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
33 | "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
34 | "dev": true,
35 | "license": "Apache-2.0",
36 | "dependencies": {
37 | "@jridgewell/gen-mapping": "^0.3.5",
38 | "@jridgewell/trace-mapping": "^0.3.24"
39 | },
40 | "engines": {
41 | "node": ">=6.0.0"
42 | }
43 | },
44 | "node_modules/@babel/code-frame": {
45 | "version": "7.26.2",
46 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
47 | "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
48 | "dev": true,
49 | "license": "MIT",
50 | "dependencies": {
51 | "@babel/helper-validator-identifier": "^7.25.9",
52 | "js-tokens": "^4.0.0",
53 | "picocolors": "^1.0.0"
54 | },
55 | "engines": {
56 | "node": ">=6.9.0"
57 | }
58 | },
59 | "node_modules/@babel/compat-data": {
60 | "version": "7.26.8",
61 | "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz",
62 | "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==",
63 | "dev": true,
64 | "license": "MIT",
65 | "engines": {
66 | "node": ">=6.9.0"
67 | }
68 | },
69 | "node_modules/@babel/core": {
70 | "version": "7.26.10",
71 | "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz",
72 | "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==",
73 | "dev": true,
74 | "license": "MIT",
75 | "dependencies": {
76 | "@ampproject/remapping": "^2.2.0",
77 | "@babel/code-frame": "^7.26.2",
78 | "@babel/generator": "^7.26.10",
79 | "@babel/helper-compilation-targets": "^7.26.5",
80 | "@babel/helper-module-transforms": "^7.26.0",
81 | "@babel/helpers": "^7.26.10",
82 | "@babel/parser": "^7.26.10",
83 | "@babel/template": "^7.26.9",
84 | "@babel/traverse": "^7.26.10",
85 | "@babel/types": "^7.26.10",
86 | "convert-source-map": "^2.0.0",
87 | "debug": "^4.1.0",
88 | "gensync": "^1.0.0-beta.2",
89 | "json5": "^2.2.3",
90 | "semver": "^6.3.1"
91 | },
92 | "engines": {
93 | "node": ">=6.9.0"
94 | },
95 | "funding": {
96 | "type": "opencollective",
97 | "url": "https://opencollective.com/babel"
98 | }
99 | },
100 | "node_modules/@babel/generator": {
101 | "version": "7.26.10",
102 | "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.10.tgz",
103 | "integrity": "sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang==",
104 | "dev": true,
105 | "license": "MIT",
106 | "dependencies": {
107 | "@babel/parser": "^7.26.10",
108 | "@babel/types": "^7.26.10",
109 | "@jridgewell/gen-mapping": "^0.3.5",
110 | "@jridgewell/trace-mapping": "^0.3.25",
111 | "jsesc": "^3.0.2"
112 | },
113 | "engines": {
114 | "node": ">=6.9.0"
115 | }
116 | },
117 | "node_modules/@babel/helper-compilation-targets": {
118 | "version": "7.26.5",
119 | "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz",
120 | "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==",
121 | "dev": true,
122 | "license": "MIT",
123 | "dependencies": {
124 | "@babel/compat-data": "^7.26.5",
125 | "@babel/helper-validator-option": "^7.25.9",
126 | "browserslist": "^4.24.0",
127 | "lru-cache": "^5.1.1",
128 | "semver": "^6.3.1"
129 | },
130 | "engines": {
131 | "node": ">=6.9.0"
132 | }
133 | },
134 | "node_modules/@babel/helper-module-imports": {
135 | "version": "7.25.9",
136 | "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz",
137 | "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==",
138 | "dev": true,
139 | "license": "MIT",
140 | "dependencies": {
141 | "@babel/traverse": "^7.25.9",
142 | "@babel/types": "^7.25.9"
143 | },
144 | "engines": {
145 | "node": ">=6.9.0"
146 | }
147 | },
148 | "node_modules/@babel/helper-module-transforms": {
149 | "version": "7.26.0",
150 | "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz",
151 | "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==",
152 | "dev": true,
153 | "license": "MIT",
154 | "dependencies": {
155 | "@babel/helper-module-imports": "^7.25.9",
156 | "@babel/helper-validator-identifier": "^7.25.9",
157 | "@babel/traverse": "^7.25.9"
158 | },
159 | "engines": {
160 | "node": ">=6.9.0"
161 | },
162 | "peerDependencies": {
163 | "@babel/core": "^7.0.0"
164 | }
165 | },
166 | "node_modules/@babel/helper-plugin-utils": {
167 | "version": "7.26.5",
168 | "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz",
169 | "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==",
170 | "dev": true,
171 | "license": "MIT",
172 | "engines": {
173 | "node": ">=6.9.0"
174 | }
175 | },
176 | "node_modules/@babel/helper-string-parser": {
177 | "version": "7.25.9",
178 | "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
179 | "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
180 | "dev": true,
181 | "license": "MIT",
182 | "engines": {
183 | "node": ">=6.9.0"
184 | }
185 | },
186 | "node_modules/@babel/helper-validator-identifier": {
187 | "version": "7.25.9",
188 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
189 | "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
190 | "dev": true,
191 | "license": "MIT",
192 | "engines": {
193 | "node": ">=6.9.0"
194 | }
195 | },
196 | "node_modules/@babel/helper-validator-option": {
197 | "version": "7.25.9",
198 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz",
199 | "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==",
200 | "dev": true,
201 | "license": "MIT",
202 | "engines": {
203 | "node": ">=6.9.0"
204 | }
205 | },
206 | "node_modules/@babel/helpers": {
207 | "version": "7.26.10",
208 | "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.10.tgz",
209 | "integrity": "sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==",
210 | "dev": true,
211 | "license": "MIT",
212 | "dependencies": {
213 | "@babel/template": "^7.26.9",
214 | "@babel/types": "^7.26.10"
215 | },
216 | "engines": {
217 | "node": ">=6.9.0"
218 | }
219 | },
220 | "node_modules/@babel/parser": {
221 | "version": "7.26.10",
222 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz",
223 | "integrity": "sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==",
224 | "dev": true,
225 | "license": "MIT",
226 | "dependencies": {
227 | "@babel/types": "^7.26.10"
228 | },
229 | "bin": {
230 | "parser": "bin/babel-parser.js"
231 | },
232 | "engines": {
233 | "node": ">=6.0.0"
234 | }
235 | },
236 | "node_modules/@babel/plugin-transform-react-jsx-self": {
237 | "version": "7.25.9",
238 | "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz",
239 | "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==",
240 | "dev": true,
241 | "license": "MIT",
242 | "dependencies": {
243 | "@babel/helper-plugin-utils": "^7.25.9"
244 | },
245 | "engines": {
246 | "node": ">=6.9.0"
247 | },
248 | "peerDependencies": {
249 | "@babel/core": "^7.0.0-0"
250 | }
251 | },
252 | "node_modules/@babel/plugin-transform-react-jsx-source": {
253 | "version": "7.25.9",
254 | "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz",
255 | "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==",
256 | "dev": true,
257 | "license": "MIT",
258 | "dependencies": {
259 | "@babel/helper-plugin-utils": "^7.25.9"
260 | },
261 | "engines": {
262 | "node": ">=6.9.0"
263 | },
264 | "peerDependencies": {
265 | "@babel/core": "^7.0.0-0"
266 | }
267 | },
268 | "node_modules/@babel/template": {
269 | "version": "7.26.9",
270 | "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz",
271 | "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==",
272 | "dev": true,
273 | "license": "MIT",
274 | "dependencies": {
275 | "@babel/code-frame": "^7.26.2",
276 | "@babel/parser": "^7.26.9",
277 | "@babel/types": "^7.26.9"
278 | },
279 | "engines": {
280 | "node": ">=6.9.0"
281 | }
282 | },
283 | "node_modules/@babel/traverse": {
284 | "version": "7.26.10",
285 | "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.10.tgz",
286 | "integrity": "sha512-k8NuDrxr0WrPH5Aupqb2LCVURP/S0vBEn5mK6iH+GIYob66U5EtoZvcdudR2jQ4cmTwhEwW1DLB+Yyas9zjF6A==",
287 | "dev": true,
288 | "license": "MIT",
289 | "dependencies": {
290 | "@babel/code-frame": "^7.26.2",
291 | "@babel/generator": "^7.26.10",
292 | "@babel/parser": "^7.26.10",
293 | "@babel/template": "^7.26.9",
294 | "@babel/types": "^7.26.10",
295 | "debug": "^4.3.1",
296 | "globals": "^11.1.0"
297 | },
298 | "engines": {
299 | "node": ">=6.9.0"
300 | }
301 | },
302 | "node_modules/@babel/traverse/node_modules/globals": {
303 | "version": "11.12.0",
304 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
305 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
306 | "dev": true,
307 | "license": "MIT",
308 | "engines": {
309 | "node": ">=4"
310 | }
311 | },
312 | "node_modules/@babel/types": {
313 | "version": "7.26.10",
314 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.10.tgz",
315 | "integrity": "sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==",
316 | "dev": true,
317 | "license": "MIT",
318 | "dependencies": {
319 | "@babel/helper-string-parser": "^7.25.9",
320 | "@babel/helper-validator-identifier": "^7.25.9"
321 | },
322 | "engines": {
323 | "node": ">=6.9.0"
324 | }
325 | },
326 | "node_modules/@esbuild/aix-ppc64": {
327 | "version": "0.25.1",
328 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz",
329 | "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==",
330 | "cpu": [
331 | "ppc64"
332 | ],
333 | "dev": true,
334 | "license": "MIT",
335 | "optional": true,
336 | "os": [
337 | "aix"
338 | ],
339 | "engines": {
340 | "node": ">=18"
341 | }
342 | },
343 | "node_modules/@esbuild/android-arm": {
344 | "version": "0.25.1",
345 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.1.tgz",
346 | "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==",
347 | "cpu": [
348 | "arm"
349 | ],
350 | "dev": true,
351 | "license": "MIT",
352 | "optional": true,
353 | "os": [
354 | "android"
355 | ],
356 | "engines": {
357 | "node": ">=18"
358 | }
359 | },
360 | "node_modules/@esbuild/android-arm64": {
361 | "version": "0.25.1",
362 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz",
363 | "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==",
364 | "cpu": [
365 | "arm64"
366 | ],
367 | "dev": true,
368 | "license": "MIT",
369 | "optional": true,
370 | "os": [
371 | "android"
372 | ],
373 | "engines": {
374 | "node": ">=18"
375 | }
376 | },
377 | "node_modules/@esbuild/android-x64": {
378 | "version": "0.25.1",
379 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.1.tgz",
380 | "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==",
381 | "cpu": [
382 | "x64"
383 | ],
384 | "dev": true,
385 | "license": "MIT",
386 | "optional": true,
387 | "os": [
388 | "android"
389 | ],
390 | "engines": {
391 | "node": ">=18"
392 | }
393 | },
394 | "node_modules/@esbuild/darwin-arm64": {
395 | "version": "0.25.1",
396 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz",
397 | "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==",
398 | "cpu": [
399 | "arm64"
400 | ],
401 | "dev": true,
402 | "license": "MIT",
403 | "optional": true,
404 | "os": [
405 | "darwin"
406 | ],
407 | "engines": {
408 | "node": ">=18"
409 | }
410 | },
411 | "node_modules/@esbuild/darwin-x64": {
412 | "version": "0.25.1",
413 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz",
414 | "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==",
415 | "cpu": [
416 | "x64"
417 | ],
418 | "dev": true,
419 | "license": "MIT",
420 | "optional": true,
421 | "os": [
422 | "darwin"
423 | ],
424 | "engines": {
425 | "node": ">=18"
426 | }
427 | },
428 | "node_modules/@esbuild/freebsd-arm64": {
429 | "version": "0.25.1",
430 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz",
431 | "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==",
432 | "cpu": [
433 | "arm64"
434 | ],
435 | "dev": true,
436 | "license": "MIT",
437 | "optional": true,
438 | "os": [
439 | "freebsd"
440 | ],
441 | "engines": {
442 | "node": ">=18"
443 | }
444 | },
445 | "node_modules/@esbuild/freebsd-x64": {
446 | "version": "0.25.1",
447 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz",
448 | "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==",
449 | "cpu": [
450 | "x64"
451 | ],
452 | "dev": true,
453 | "license": "MIT",
454 | "optional": true,
455 | "os": [
456 | "freebsd"
457 | ],
458 | "engines": {
459 | "node": ">=18"
460 | }
461 | },
462 | "node_modules/@esbuild/linux-arm": {
463 | "version": "0.25.1",
464 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz",
465 | "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==",
466 | "cpu": [
467 | "arm"
468 | ],
469 | "dev": true,
470 | "license": "MIT",
471 | "optional": true,
472 | "os": [
473 | "linux"
474 | ],
475 | "engines": {
476 | "node": ">=18"
477 | }
478 | },
479 | "node_modules/@esbuild/linux-arm64": {
480 | "version": "0.25.1",
481 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz",
482 | "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==",
483 | "cpu": [
484 | "arm64"
485 | ],
486 | "dev": true,
487 | "license": "MIT",
488 | "optional": true,
489 | "os": [
490 | "linux"
491 | ],
492 | "engines": {
493 | "node": ">=18"
494 | }
495 | },
496 | "node_modules/@esbuild/linux-ia32": {
497 | "version": "0.25.1",
498 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz",
499 | "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==",
500 | "cpu": [
501 | "ia32"
502 | ],
503 | "dev": true,
504 | "license": "MIT",
505 | "optional": true,
506 | "os": [
507 | "linux"
508 | ],
509 | "engines": {
510 | "node": ">=18"
511 | }
512 | },
513 | "node_modules/@esbuild/linux-loong64": {
514 | "version": "0.25.1",
515 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz",
516 | "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==",
517 | "cpu": [
518 | "loong64"
519 | ],
520 | "dev": true,
521 | "license": "MIT",
522 | "optional": true,
523 | "os": [
524 | "linux"
525 | ],
526 | "engines": {
527 | "node": ">=18"
528 | }
529 | },
530 | "node_modules/@esbuild/linux-mips64el": {
531 | "version": "0.25.1",
532 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz",
533 | "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==",
534 | "cpu": [
535 | "mips64el"
536 | ],
537 | "dev": true,
538 | "license": "MIT",
539 | "optional": true,
540 | "os": [
541 | "linux"
542 | ],
543 | "engines": {
544 | "node": ">=18"
545 | }
546 | },
547 | "node_modules/@esbuild/linux-ppc64": {
548 | "version": "0.25.1",
549 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz",
550 | "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==",
551 | "cpu": [
552 | "ppc64"
553 | ],
554 | "dev": true,
555 | "license": "MIT",
556 | "optional": true,
557 | "os": [
558 | "linux"
559 | ],
560 | "engines": {
561 | "node": ">=18"
562 | }
563 | },
564 | "node_modules/@esbuild/linux-riscv64": {
565 | "version": "0.25.1",
566 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz",
567 | "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==",
568 | "cpu": [
569 | "riscv64"
570 | ],
571 | "dev": true,
572 | "license": "MIT",
573 | "optional": true,
574 | "os": [
575 | "linux"
576 | ],
577 | "engines": {
578 | "node": ">=18"
579 | }
580 | },
581 | "node_modules/@esbuild/linux-s390x": {
582 | "version": "0.25.1",
583 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz",
584 | "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==",
585 | "cpu": [
586 | "s390x"
587 | ],
588 | "dev": true,
589 | "license": "MIT",
590 | "optional": true,
591 | "os": [
592 | "linux"
593 | ],
594 | "engines": {
595 | "node": ">=18"
596 | }
597 | },
598 | "node_modules/@esbuild/linux-x64": {
599 | "version": "0.25.1",
600 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz",
601 | "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==",
602 | "cpu": [
603 | "x64"
604 | ],
605 | "dev": true,
606 | "license": "MIT",
607 | "optional": true,
608 | "os": [
609 | "linux"
610 | ],
611 | "engines": {
612 | "node": ">=18"
613 | }
614 | },
615 | "node_modules/@esbuild/netbsd-arm64": {
616 | "version": "0.25.1",
617 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz",
618 | "integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==",
619 | "cpu": [
620 | "arm64"
621 | ],
622 | "dev": true,
623 | "license": "MIT",
624 | "optional": true,
625 | "os": [
626 | "netbsd"
627 | ],
628 | "engines": {
629 | "node": ">=18"
630 | }
631 | },
632 | "node_modules/@esbuild/netbsd-x64": {
633 | "version": "0.25.1",
634 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz",
635 | "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==",
636 | "cpu": [
637 | "x64"
638 | ],
639 | "dev": true,
640 | "license": "MIT",
641 | "optional": true,
642 | "os": [
643 | "netbsd"
644 | ],
645 | "engines": {
646 | "node": ">=18"
647 | }
648 | },
649 | "node_modules/@esbuild/openbsd-arm64": {
650 | "version": "0.25.1",
651 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz",
652 | "integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==",
653 | "cpu": [
654 | "arm64"
655 | ],
656 | "dev": true,
657 | "license": "MIT",
658 | "optional": true,
659 | "os": [
660 | "openbsd"
661 | ],
662 | "engines": {
663 | "node": ">=18"
664 | }
665 | },
666 | "node_modules/@esbuild/openbsd-x64": {
667 | "version": "0.25.1",
668 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz",
669 | "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==",
670 | "cpu": [
671 | "x64"
672 | ],
673 | "dev": true,
674 | "license": "MIT",
675 | "optional": true,
676 | "os": [
677 | "openbsd"
678 | ],
679 | "engines": {
680 | "node": ">=18"
681 | }
682 | },
683 | "node_modules/@esbuild/sunos-x64": {
684 | "version": "0.25.1",
685 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz",
686 | "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==",
687 | "cpu": [
688 | "x64"
689 | ],
690 | "dev": true,
691 | "license": "MIT",
692 | "optional": true,
693 | "os": [
694 | "sunos"
695 | ],
696 | "engines": {
697 | "node": ">=18"
698 | }
699 | },
700 | "node_modules/@esbuild/win32-arm64": {
701 | "version": "0.25.1",
702 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz",
703 | "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==",
704 | "cpu": [
705 | "arm64"
706 | ],
707 | "dev": true,
708 | "license": "MIT",
709 | "optional": true,
710 | "os": [
711 | "win32"
712 | ],
713 | "engines": {
714 | "node": ">=18"
715 | }
716 | },
717 | "node_modules/@esbuild/win32-ia32": {
718 | "version": "0.25.1",
719 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz",
720 | "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==",
721 | "cpu": [
722 | "ia32"
723 | ],
724 | "dev": true,
725 | "license": "MIT",
726 | "optional": true,
727 | "os": [
728 | "win32"
729 | ],
730 | "engines": {
731 | "node": ">=18"
732 | }
733 | },
734 | "node_modules/@esbuild/win32-x64": {
735 | "version": "0.25.1",
736 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz",
737 | "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==",
738 | "cpu": [
739 | "x64"
740 | ],
741 | "dev": true,
742 | "license": "MIT",
743 | "optional": true,
744 | "os": [
745 | "win32"
746 | ],
747 | "engines": {
748 | "node": ">=18"
749 | }
750 | },
751 | "node_modules/@eslint-community/eslint-utils": {
752 | "version": "4.5.1",
753 | "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.5.1.tgz",
754 | "integrity": "sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==",
755 | "dev": true,
756 | "license": "MIT",
757 | "dependencies": {
758 | "eslint-visitor-keys": "^3.4.3"
759 | },
760 | "engines": {
761 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
762 | },
763 | "funding": {
764 | "url": "https://opencollective.com/eslint"
765 | },
766 | "peerDependencies": {
767 | "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
768 | }
769 | },
770 | "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
771 | "version": "3.4.3",
772 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
773 | "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
774 | "dev": true,
775 | "license": "Apache-2.0",
776 | "engines": {
777 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
778 | },
779 | "funding": {
780 | "url": "https://opencollective.com/eslint"
781 | }
782 | },
783 | "node_modules/@eslint-community/regexpp": {
784 | "version": "4.12.1",
785 | "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
786 | "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
787 | "dev": true,
788 | "license": "MIT",
789 | "engines": {
790 | "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
791 | }
792 | },
793 | "node_modules/@eslint/config-array": {
794 | "version": "0.19.2",
795 | "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz",
796 | "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==",
797 | "dev": true,
798 | "license": "Apache-2.0",
799 | "dependencies": {
800 | "@eslint/object-schema": "^2.1.6",
801 | "debug": "^4.3.1",
802 | "minimatch": "^3.1.2"
803 | },
804 | "engines": {
805 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
806 | }
807 | },
808 | "node_modules/@eslint/config-helpers": {
809 | "version": "0.1.0",
810 | "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.1.0.tgz",
811 | "integrity": "sha512-kLrdPDJE1ckPo94kmPPf9Hfd0DU0Jw6oKYrhe+pwSC0iTUInmTa+w6fw8sGgcfkFJGNdWOUeOaDM4quW4a7OkA==",
812 | "dev": true,
813 | "license": "Apache-2.0",
814 | "engines": {
815 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
816 | }
817 | },
818 | "node_modules/@eslint/core": {
819 | "version": "0.12.0",
820 | "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz",
821 | "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==",
822 | "dev": true,
823 | "license": "Apache-2.0",
824 | "dependencies": {
825 | "@types/json-schema": "^7.0.15"
826 | },
827 | "engines": {
828 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
829 | }
830 | },
831 | "node_modules/@eslint/eslintrc": {
832 | "version": "3.3.0",
833 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.0.tgz",
834 | "integrity": "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==",
835 | "dev": true,
836 | "license": "MIT",
837 | "dependencies": {
838 | "ajv": "^6.12.4",
839 | "debug": "^4.3.2",
840 | "espree": "^10.0.1",
841 | "globals": "^14.0.0",
842 | "ignore": "^5.2.0",
843 | "import-fresh": "^3.2.1",
844 | "js-yaml": "^4.1.0",
845 | "minimatch": "^3.1.2",
846 | "strip-json-comments": "^3.1.1"
847 | },
848 | "engines": {
849 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
850 | },
851 | "funding": {
852 | "url": "https://opencollective.com/eslint"
853 | }
854 | },
855 | "node_modules/@eslint/eslintrc/node_modules/globals": {
856 | "version": "14.0.0",
857 | "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
858 | "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
859 | "dev": true,
860 | "license": "MIT",
861 | "engines": {
862 | "node": ">=18"
863 | },
864 | "funding": {
865 | "url": "https://github.com/sponsors/sindresorhus"
866 | }
867 | },
868 | "node_modules/@eslint/js": {
869 | "version": "9.22.0",
870 | "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.22.0.tgz",
871 | "integrity": "sha512-vLFajx9o8d1/oL2ZkpMYbkLv8nDB6yaIwFNt7nI4+I80U/z03SxmfOMsLbvWr3p7C+Wnoh//aOu2pQW8cS0HCQ==",
872 | "dev": true,
873 | "license": "MIT",
874 | "engines": {
875 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
876 | }
877 | },
878 | "node_modules/@eslint/object-schema": {
879 | "version": "2.1.6",
880 | "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz",
881 | "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==",
882 | "dev": true,
883 | "license": "Apache-2.0",
884 | "engines": {
885 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
886 | }
887 | },
888 | "node_modules/@eslint/plugin-kit": {
889 | "version": "0.2.7",
890 | "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz",
891 | "integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==",
892 | "dev": true,
893 | "license": "Apache-2.0",
894 | "dependencies": {
895 | "@eslint/core": "^0.12.0",
896 | "levn": "^0.4.1"
897 | },
898 | "engines": {
899 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
900 | }
901 | },
902 | "node_modules/@humanfs/core": {
903 | "version": "0.19.1",
904 | "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
905 | "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
906 | "dev": true,
907 | "license": "Apache-2.0",
908 | "engines": {
909 | "node": ">=18.18.0"
910 | }
911 | },
912 | "node_modules/@humanfs/node": {
913 | "version": "0.16.6",
914 | "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz",
915 | "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==",
916 | "dev": true,
917 | "license": "Apache-2.0",
918 | "dependencies": {
919 | "@humanfs/core": "^0.19.1",
920 | "@humanwhocodes/retry": "^0.3.0"
921 | },
922 | "engines": {
923 | "node": ">=18.18.0"
924 | }
925 | },
926 | "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": {
927 | "version": "0.3.1",
928 | "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz",
929 | "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==",
930 | "dev": true,
931 | "license": "Apache-2.0",
932 | "engines": {
933 | "node": ">=18.18"
934 | },
935 | "funding": {
936 | "type": "github",
937 | "url": "https://github.com/sponsors/nzakas"
938 | }
939 | },
940 | "node_modules/@humanwhocodes/module-importer": {
941 | "version": "1.0.1",
942 | "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
943 | "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
944 | "dev": true,
945 | "license": "Apache-2.0",
946 | "engines": {
947 | "node": ">=12.22"
948 | },
949 | "funding": {
950 | "type": "github",
951 | "url": "https://github.com/sponsors/nzakas"
952 | }
953 | },
954 | "node_modules/@humanwhocodes/retry": {
955 | "version": "0.4.2",
956 | "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz",
957 | "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==",
958 | "dev": true,
959 | "license": "Apache-2.0",
960 | "engines": {
961 | "node": ">=18.18"
962 | },
963 | "funding": {
964 | "type": "github",
965 | "url": "https://github.com/sponsors/nzakas"
966 | }
967 | },
968 | "node_modules/@jridgewell/gen-mapping": {
969 | "version": "0.3.8",
970 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
971 | "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
972 | "dev": true,
973 | "license": "MIT",
974 | "dependencies": {
975 | "@jridgewell/set-array": "^1.2.1",
976 | "@jridgewell/sourcemap-codec": "^1.4.10",
977 | "@jridgewell/trace-mapping": "^0.3.24"
978 | },
979 | "engines": {
980 | "node": ">=6.0.0"
981 | }
982 | },
983 | "node_modules/@jridgewell/resolve-uri": {
984 | "version": "3.1.2",
985 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
986 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
987 | "dev": true,
988 | "license": "MIT",
989 | "engines": {
990 | "node": ">=6.0.0"
991 | }
992 | },
993 | "node_modules/@jridgewell/set-array": {
994 | "version": "1.2.1",
995 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
996 | "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
997 | "dev": true,
998 | "license": "MIT",
999 | "engines": {
1000 | "node": ">=6.0.0"
1001 | }
1002 | },
1003 | "node_modules/@jridgewell/sourcemap-codec": {
1004 | "version": "1.5.0",
1005 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
1006 | "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
1007 | "dev": true,
1008 | "license": "MIT"
1009 | },
1010 | "node_modules/@jridgewell/trace-mapping": {
1011 | "version": "0.3.25",
1012 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
1013 | "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
1014 | "dev": true,
1015 | "license": "MIT",
1016 | "dependencies": {
1017 | "@jridgewell/resolve-uri": "^3.1.0",
1018 | "@jridgewell/sourcemap-codec": "^1.4.14"
1019 | }
1020 | },
1021 | "node_modules/@reduxjs/toolkit": {
1022 | "version": "2.6.1",
1023 | "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.6.1.tgz",
1024 | "integrity": "sha512-SSlIqZNYhqm/oMkXbtofwZSt9lrncblzo6YcZ9zoX+zLngRBrCOjK4lNLdkNucJF58RHOWrD9txT3bT3piH7Zw==",
1025 | "license": "MIT",
1026 | "dependencies": {
1027 | "immer": "^10.0.3",
1028 | "redux": "^5.0.1",
1029 | "redux-thunk": "^3.1.0",
1030 | "reselect": "^5.1.0"
1031 | },
1032 | "peerDependencies": {
1033 | "react": "^16.9.0 || ^17.0.0 || ^18 || ^19",
1034 | "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0"
1035 | },
1036 | "peerDependenciesMeta": {
1037 | "react": {
1038 | "optional": true
1039 | },
1040 | "react-redux": {
1041 | "optional": true
1042 | }
1043 | }
1044 | },
1045 | "node_modules/@rollup/rollup-android-arm-eabi": {
1046 | "version": "4.36.0",
1047 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.36.0.tgz",
1048 | "integrity": "sha512-jgrXjjcEwN6XpZXL0HUeOVGfjXhPyxAbbhD0BlXUB+abTOpbPiN5Wb3kOT7yb+uEtATNYF5x5gIfwutmuBA26w==",
1049 | "cpu": [
1050 | "arm"
1051 | ],
1052 | "dev": true,
1053 | "license": "MIT",
1054 | "optional": true,
1055 | "os": [
1056 | "android"
1057 | ]
1058 | },
1059 | "node_modules/@rollup/rollup-android-arm64": {
1060 | "version": "4.36.0",
1061 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.36.0.tgz",
1062 | "integrity": "sha512-NyfuLvdPdNUfUNeYKUwPwKsE5SXa2J6bCt2LdB/N+AxShnkpiczi3tcLJrm5mA+eqpy0HmaIY9F6XCa32N5yzg==",
1063 | "cpu": [
1064 | "arm64"
1065 | ],
1066 | "dev": true,
1067 | "license": "MIT",
1068 | "optional": true,
1069 | "os": [
1070 | "android"
1071 | ]
1072 | },
1073 | "node_modules/@rollup/rollup-darwin-arm64": {
1074 | "version": "4.36.0",
1075 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.36.0.tgz",
1076 | "integrity": "sha512-JQ1Jk5G4bGrD4pWJQzWsD8I1n1mgPXq33+/vP4sk8j/z/C2siRuxZtaUA7yMTf71TCZTZl/4e1bfzwUmFb3+rw==",
1077 | "cpu": [
1078 | "arm64"
1079 | ],
1080 | "dev": true,
1081 | "license": "MIT",
1082 | "optional": true,
1083 | "os": [
1084 | "darwin"
1085 | ]
1086 | },
1087 | "node_modules/@rollup/rollup-darwin-x64": {
1088 | "version": "4.36.0",
1089 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.36.0.tgz",
1090 | "integrity": "sha512-6c6wMZa1lrtiRsbDziCmjE53YbTkxMYhhnWnSW8R/yqsM7a6mSJ3uAVT0t8Y/DGt7gxUWYuFM4bwWk9XCJrFKA==",
1091 | "cpu": [
1092 | "x64"
1093 | ],
1094 | "dev": true,
1095 | "license": "MIT",
1096 | "optional": true,
1097 | "os": [
1098 | "darwin"
1099 | ]
1100 | },
1101 | "node_modules/@rollup/rollup-freebsd-arm64": {
1102 | "version": "4.36.0",
1103 | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.36.0.tgz",
1104 | "integrity": "sha512-KXVsijKeJXOl8QzXTsA+sHVDsFOmMCdBRgFmBb+mfEb/7geR7+C8ypAml4fquUt14ZyVXaw2o1FWhqAfOvA4sg==",
1105 | "cpu": [
1106 | "arm64"
1107 | ],
1108 | "dev": true,
1109 | "license": "MIT",
1110 | "optional": true,
1111 | "os": [
1112 | "freebsd"
1113 | ]
1114 | },
1115 | "node_modules/@rollup/rollup-freebsd-x64": {
1116 | "version": "4.36.0",
1117 | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.36.0.tgz",
1118 | "integrity": "sha512-dVeWq1ebbvByI+ndz4IJcD4a09RJgRYmLccwlQ8bPd4olz3Y213uf1iwvc7ZaxNn2ab7bjc08PrtBgMu6nb4pQ==",
1119 | "cpu": [
1120 | "x64"
1121 | ],
1122 | "dev": true,
1123 | "license": "MIT",
1124 | "optional": true,
1125 | "os": [
1126 | "freebsd"
1127 | ]
1128 | },
1129 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
1130 | "version": "4.36.0",
1131 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.36.0.tgz",
1132 | "integrity": "sha512-bvXVU42mOVcF4le6XSjscdXjqx8okv4n5vmwgzcmtvFdifQ5U4dXFYaCB87namDRKlUL9ybVtLQ9ztnawaSzvg==",
1133 | "cpu": [
1134 | "arm"
1135 | ],
1136 | "dev": true,
1137 | "license": "MIT",
1138 | "optional": true,
1139 | "os": [
1140 | "linux"
1141 | ]
1142 | },
1143 | "node_modules/@rollup/rollup-linux-arm-musleabihf": {
1144 | "version": "4.36.0",
1145 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.36.0.tgz",
1146 | "integrity": "sha512-JFIQrDJYrxOnyDQGYkqnNBtjDwTgbasdbUiQvcU8JmGDfValfH1lNpng+4FWlhaVIR4KPkeddYjsVVbmJYvDcg==",
1147 | "cpu": [
1148 | "arm"
1149 | ],
1150 | "dev": true,
1151 | "license": "MIT",
1152 | "optional": true,
1153 | "os": [
1154 | "linux"
1155 | ]
1156 | },
1157 | "node_modules/@rollup/rollup-linux-arm64-gnu": {
1158 | "version": "4.36.0",
1159 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.36.0.tgz",
1160 | "integrity": "sha512-KqjYVh3oM1bj//5X7k79PSCZ6CvaVzb7Qs7VMWS+SlWB5M8p3FqufLP9VNp4CazJ0CsPDLwVD9r3vX7Ci4J56A==",
1161 | "cpu": [
1162 | "arm64"
1163 | ],
1164 | "dev": true,
1165 | "license": "MIT",
1166 | "optional": true,
1167 | "os": [
1168 | "linux"
1169 | ]
1170 | },
1171 | "node_modules/@rollup/rollup-linux-arm64-musl": {
1172 | "version": "4.36.0",
1173 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.36.0.tgz",
1174 | "integrity": "sha512-QiGnhScND+mAAtfHqeT+cB1S9yFnNQ/EwCg5yE3MzoaZZnIV0RV9O5alJAoJKX/sBONVKeZdMfO8QSaWEygMhw==",
1175 | "cpu": [
1176 | "arm64"
1177 | ],
1178 | "dev": true,
1179 | "license": "MIT",
1180 | "optional": true,
1181 | "os": [
1182 | "linux"
1183 | ]
1184 | },
1185 | "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
1186 | "version": "4.36.0",
1187 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.36.0.tgz",
1188 | "integrity": "sha512-1ZPyEDWF8phd4FQtTzMh8FQwqzvIjLsl6/84gzUxnMNFBtExBtpL51H67mV9xipuxl1AEAerRBgBwFNpkw8+Lg==",
1189 | "cpu": [
1190 | "loong64"
1191 | ],
1192 | "dev": true,
1193 | "license": "MIT",
1194 | "optional": true,
1195 | "os": [
1196 | "linux"
1197 | ]
1198 | },
1199 | "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
1200 | "version": "4.36.0",
1201 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.36.0.tgz",
1202 | "integrity": "sha512-VMPMEIUpPFKpPI9GZMhJrtu8rxnp6mJR3ZzQPykq4xc2GmdHj3Q4cA+7avMyegXy4n1v+Qynr9fR88BmyO74tg==",
1203 | "cpu": [
1204 | "ppc64"
1205 | ],
1206 | "dev": true,
1207 | "license": "MIT",
1208 | "optional": true,
1209 | "os": [
1210 | "linux"
1211 | ]
1212 | },
1213 | "node_modules/@rollup/rollup-linux-riscv64-gnu": {
1214 | "version": "4.36.0",
1215 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.36.0.tgz",
1216 | "integrity": "sha512-ttE6ayb/kHwNRJGYLpuAvB7SMtOeQnVXEIpMtAvx3kepFQeowVED0n1K9nAdraHUPJ5hydEMxBpIR7o4nrm8uA==",
1217 | "cpu": [
1218 | "riscv64"
1219 | ],
1220 | "dev": true,
1221 | "license": "MIT",
1222 | "optional": true,
1223 | "os": [
1224 | "linux"
1225 | ]
1226 | },
1227 | "node_modules/@rollup/rollup-linux-s390x-gnu": {
1228 | "version": "4.36.0",
1229 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.36.0.tgz",
1230 | "integrity": "sha512-4a5gf2jpS0AIe7uBjxDeUMNcFmaRTbNv7NxI5xOCs4lhzsVyGR/0qBXduPnoWf6dGC365saTiwag8hP1imTgag==",
1231 | "cpu": [
1232 | "s390x"
1233 | ],
1234 | "dev": true,
1235 | "license": "MIT",
1236 | "optional": true,
1237 | "os": [
1238 | "linux"
1239 | ]
1240 | },
1241 | "node_modules/@rollup/rollup-linux-x64-gnu": {
1242 | "version": "4.36.0",
1243 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.36.0.tgz",
1244 | "integrity": "sha512-5KtoW8UWmwFKQ96aQL3LlRXX16IMwyzMq/jSSVIIyAANiE1doaQsx/KRyhAvpHlPjPiSU/AYX/8m+lQ9VToxFQ==",
1245 | "cpu": [
1246 | "x64"
1247 | ],
1248 | "dev": true,
1249 | "license": "MIT",
1250 | "optional": true,
1251 | "os": [
1252 | "linux"
1253 | ]
1254 | },
1255 | "node_modules/@rollup/rollup-linux-x64-musl": {
1256 | "version": "4.36.0",
1257 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.36.0.tgz",
1258 | "integrity": "sha512-sycrYZPrv2ag4OCvaN5js+f01eoZ2U+RmT5as8vhxiFz+kxwlHrsxOwKPSA8WyS+Wc6Epid9QeI/IkQ9NkgYyQ==",
1259 | "cpu": [
1260 | "x64"
1261 | ],
1262 | "dev": true,
1263 | "license": "MIT",
1264 | "optional": true,
1265 | "os": [
1266 | "linux"
1267 | ]
1268 | },
1269 | "node_modules/@rollup/rollup-win32-arm64-msvc": {
1270 | "version": "4.36.0",
1271 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.36.0.tgz",
1272 | "integrity": "sha512-qbqt4N7tokFwwSVlWDsjfoHgviS3n/vZ8LK0h1uLG9TYIRuUTJC88E1xb3LM2iqZ/WTqNQjYrtmtGmrmmawB6A==",
1273 | "cpu": [
1274 | "arm64"
1275 | ],
1276 | "dev": true,
1277 | "license": "MIT",
1278 | "optional": true,
1279 | "os": [
1280 | "win32"
1281 | ]
1282 | },
1283 | "node_modules/@rollup/rollup-win32-ia32-msvc": {
1284 | "version": "4.36.0",
1285 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.36.0.tgz",
1286 | "integrity": "sha512-t+RY0JuRamIocMuQcfwYSOkmdX9dtkr1PbhKW42AMvaDQa+jOdpUYysroTF/nuPpAaQMWp7ye+ndlmmthieJrQ==",
1287 | "cpu": [
1288 | "ia32"
1289 | ],
1290 | "dev": true,
1291 | "license": "MIT",
1292 | "optional": true,
1293 | "os": [
1294 | "win32"
1295 | ]
1296 | },
1297 | "node_modules/@rollup/rollup-win32-x64-msvc": {
1298 | "version": "4.36.0",
1299 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.36.0.tgz",
1300 | "integrity": "sha512-aRXd7tRZkWLqGbChgcMMDEHjOKudo1kChb1Jt1IfR8cY/KIpgNviLeJy5FUb9IpSuQj8dU2fAYNMPW/hLKOSTw==",
1301 | "cpu": [
1302 | "x64"
1303 | ],
1304 | "dev": true,
1305 | "license": "MIT",
1306 | "optional": true,
1307 | "os": [
1308 | "win32"
1309 | ]
1310 | },
1311 | "node_modules/@types/babel__core": {
1312 | "version": "7.20.5",
1313 | "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
1314 | "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
1315 | "dev": true,
1316 | "license": "MIT",
1317 | "dependencies": {
1318 | "@babel/parser": "^7.20.7",
1319 | "@babel/types": "^7.20.7",
1320 | "@types/babel__generator": "*",
1321 | "@types/babel__template": "*",
1322 | "@types/babel__traverse": "*"
1323 | }
1324 | },
1325 | "node_modules/@types/babel__generator": {
1326 | "version": "7.6.8",
1327 | "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz",
1328 | "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==",
1329 | "dev": true,
1330 | "license": "MIT",
1331 | "dependencies": {
1332 | "@babel/types": "^7.0.0"
1333 | }
1334 | },
1335 | "node_modules/@types/babel__template": {
1336 | "version": "7.4.4",
1337 | "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
1338 | "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
1339 | "dev": true,
1340 | "license": "MIT",
1341 | "dependencies": {
1342 | "@babel/parser": "^7.1.0",
1343 | "@babel/types": "^7.0.0"
1344 | }
1345 | },
1346 | "node_modules/@types/babel__traverse": {
1347 | "version": "7.20.6",
1348 | "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz",
1349 | "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==",
1350 | "dev": true,
1351 | "license": "MIT",
1352 | "dependencies": {
1353 | "@babel/types": "^7.20.7"
1354 | }
1355 | },
1356 | "node_modules/@types/cookie": {
1357 | "version": "0.6.0",
1358 | "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
1359 | "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==",
1360 | "license": "MIT"
1361 | },
1362 | "node_modules/@types/estree": {
1363 | "version": "1.0.6",
1364 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
1365 | "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
1366 | "dev": true,
1367 | "license": "MIT"
1368 | },
1369 | "node_modules/@types/json-schema": {
1370 | "version": "7.0.15",
1371 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
1372 | "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
1373 | "dev": true,
1374 | "license": "MIT"
1375 | },
1376 | "node_modules/@types/react": {
1377 | "version": "19.0.12",
1378 | "resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.12.tgz",
1379 | "integrity": "sha512-V6Ar115dBDrjbtXSrS+/Oruobc+qVbbUxDFC1RSbRqLt5SYvxxyIDrSC85RWml54g+jfNeEMZhEj7wW07ONQhA==",
1380 | "devOptional": true,
1381 | "license": "MIT",
1382 | "dependencies": {
1383 | "csstype": "^3.0.2"
1384 | }
1385 | },
1386 | "node_modules/@types/react-dom": {
1387 | "version": "19.0.4",
1388 | "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.0.4.tgz",
1389 | "integrity": "sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg==",
1390 | "dev": true,
1391 | "license": "MIT",
1392 | "peerDependencies": {
1393 | "@types/react": "^19.0.0"
1394 | }
1395 | },
1396 | "node_modules/@types/use-sync-external-store": {
1397 | "version": "0.0.6",
1398 | "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz",
1399 | "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==",
1400 | "license": "MIT"
1401 | },
1402 | "node_modules/@vitejs/plugin-react": {
1403 | "version": "4.3.4",
1404 | "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz",
1405 | "integrity": "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==",
1406 | "dev": true,
1407 | "license": "MIT",
1408 | "dependencies": {
1409 | "@babel/core": "^7.26.0",
1410 | "@babel/plugin-transform-react-jsx-self": "^7.25.9",
1411 | "@babel/plugin-transform-react-jsx-source": "^7.25.9",
1412 | "@types/babel__core": "^7.20.5",
1413 | "react-refresh": "^0.14.2"
1414 | },
1415 | "engines": {
1416 | "node": "^14.18.0 || >=16.0.0"
1417 | },
1418 | "peerDependencies": {
1419 | "vite": "^4.2.0 || ^5.0.0 || ^6.0.0"
1420 | }
1421 | },
1422 | "node_modules/acorn": {
1423 | "version": "8.14.1",
1424 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
1425 | "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
1426 | "dev": true,
1427 | "license": "MIT",
1428 | "bin": {
1429 | "acorn": "bin/acorn"
1430 | },
1431 | "engines": {
1432 | "node": ">=0.4.0"
1433 | }
1434 | },
1435 | "node_modules/acorn-jsx": {
1436 | "version": "5.3.2",
1437 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
1438 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
1439 | "dev": true,
1440 | "license": "MIT",
1441 | "peerDependencies": {
1442 | "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
1443 | }
1444 | },
1445 | "node_modules/ajv": {
1446 | "version": "6.12.6",
1447 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
1448 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
1449 | "dev": true,
1450 | "license": "MIT",
1451 | "dependencies": {
1452 | "fast-deep-equal": "^3.1.1",
1453 | "fast-json-stable-stringify": "^2.0.0",
1454 | "json-schema-traverse": "^0.4.1",
1455 | "uri-js": "^4.2.2"
1456 | },
1457 | "funding": {
1458 | "type": "github",
1459 | "url": "https://github.com/sponsors/epoberezkin"
1460 | }
1461 | },
1462 | "node_modules/ansi-styles": {
1463 | "version": "4.3.0",
1464 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
1465 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
1466 | "dev": true,
1467 | "license": "MIT",
1468 | "dependencies": {
1469 | "color-convert": "^2.0.1"
1470 | },
1471 | "engines": {
1472 | "node": ">=8"
1473 | },
1474 | "funding": {
1475 | "url": "https://github.com/chalk/ansi-styles?sponsor=1"
1476 | }
1477 | },
1478 | "node_modules/argparse": {
1479 | "version": "2.0.1",
1480 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
1481 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
1482 | "dev": true,
1483 | "license": "Python-2.0"
1484 | },
1485 | "node_modules/asynckit": {
1486 | "version": "0.4.0",
1487 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
1488 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
1489 | "license": "MIT"
1490 | },
1491 | "node_modules/axios": {
1492 | "version": "1.8.4",
1493 | "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz",
1494 | "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==",
1495 | "license": "MIT",
1496 | "dependencies": {
1497 | "follow-redirects": "^1.15.6",
1498 | "form-data": "^4.0.0",
1499 | "proxy-from-env": "^1.1.0"
1500 | }
1501 | },
1502 | "node_modules/balanced-match": {
1503 | "version": "1.0.2",
1504 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
1505 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
1506 | "dev": true,
1507 | "license": "MIT"
1508 | },
1509 | "node_modules/brace-expansion": {
1510 | "version": "1.1.11",
1511 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
1512 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
1513 | "dev": true,
1514 | "license": "MIT",
1515 | "dependencies": {
1516 | "balanced-match": "^1.0.0",
1517 | "concat-map": "0.0.1"
1518 | }
1519 | },
1520 | "node_modules/browserslist": {
1521 | "version": "4.24.4",
1522 | "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz",
1523 | "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==",
1524 | "dev": true,
1525 | "funding": [
1526 | {
1527 | "type": "opencollective",
1528 | "url": "https://opencollective.com/browserslist"
1529 | },
1530 | {
1531 | "type": "tidelift",
1532 | "url": "https://tidelift.com/funding/github/npm/browserslist"
1533 | },
1534 | {
1535 | "type": "github",
1536 | "url": "https://github.com/sponsors/ai"
1537 | }
1538 | ],
1539 | "license": "MIT",
1540 | "dependencies": {
1541 | "caniuse-lite": "^1.0.30001688",
1542 | "electron-to-chromium": "^1.5.73",
1543 | "node-releases": "^2.0.19",
1544 | "update-browserslist-db": "^1.1.1"
1545 | },
1546 | "bin": {
1547 | "browserslist": "cli.js"
1548 | },
1549 | "engines": {
1550 | "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
1551 | }
1552 | },
1553 | "node_modules/call-bind-apply-helpers": {
1554 | "version": "1.0.2",
1555 | "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
1556 | "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
1557 | "license": "MIT",
1558 | "dependencies": {
1559 | "es-errors": "^1.3.0",
1560 | "function-bind": "^1.1.2"
1561 | },
1562 | "engines": {
1563 | "node": ">= 0.4"
1564 | }
1565 | },
1566 | "node_modules/callsites": {
1567 | "version": "3.1.0",
1568 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
1569 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
1570 | "dev": true,
1571 | "license": "MIT",
1572 | "engines": {
1573 | "node": ">=6"
1574 | }
1575 | },
1576 | "node_modules/caniuse-lite": {
1577 | "version": "1.0.30001706",
1578 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001706.tgz",
1579 | "integrity": "sha512-3ZczoTApMAZwPKYWmwVbQMFpXBDds3/0VciVoUwPUbldlYyVLmRVuRs/PcUZtHpbLRpzzDvrvnFuREsGt6lUug==",
1580 | "dev": true,
1581 | "funding": [
1582 | {
1583 | "type": "opencollective",
1584 | "url": "https://opencollective.com/browserslist"
1585 | },
1586 | {
1587 | "type": "tidelift",
1588 | "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
1589 | },
1590 | {
1591 | "type": "github",
1592 | "url": "https://github.com/sponsors/ai"
1593 | }
1594 | ],
1595 | "license": "CC-BY-4.0"
1596 | },
1597 | "node_modules/chalk": {
1598 | "version": "4.1.2",
1599 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
1600 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
1601 | "dev": true,
1602 | "license": "MIT",
1603 | "dependencies": {
1604 | "ansi-styles": "^4.1.0",
1605 | "supports-color": "^7.1.0"
1606 | },
1607 | "engines": {
1608 | "node": ">=10"
1609 | },
1610 | "funding": {
1611 | "url": "https://github.com/chalk/chalk?sponsor=1"
1612 | }
1613 | },
1614 | "node_modules/color-convert": {
1615 | "version": "2.0.1",
1616 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
1617 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
1618 | "dev": true,
1619 | "license": "MIT",
1620 | "dependencies": {
1621 | "color-name": "~1.1.4"
1622 | },
1623 | "engines": {
1624 | "node": ">=7.0.0"
1625 | }
1626 | },
1627 | "node_modules/color-name": {
1628 | "version": "1.1.4",
1629 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
1630 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
1631 | "dev": true,
1632 | "license": "MIT"
1633 | },
1634 | "node_modules/combined-stream": {
1635 | "version": "1.0.8",
1636 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
1637 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
1638 | "license": "MIT",
1639 | "dependencies": {
1640 | "delayed-stream": "~1.0.0"
1641 | },
1642 | "engines": {
1643 | "node": ">= 0.8"
1644 | }
1645 | },
1646 | "node_modules/concat-map": {
1647 | "version": "0.0.1",
1648 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
1649 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
1650 | "dev": true,
1651 | "license": "MIT"
1652 | },
1653 | "node_modules/convert-source-map": {
1654 | "version": "2.0.0",
1655 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
1656 | "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
1657 | "dev": true,
1658 | "license": "MIT"
1659 | },
1660 | "node_modules/cookie": {
1661 | "version": "1.0.2",
1662 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz",
1663 | "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==",
1664 | "license": "MIT",
1665 | "engines": {
1666 | "node": ">=18"
1667 | }
1668 | },
1669 | "node_modules/cross-spawn": {
1670 | "version": "7.0.6",
1671 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
1672 | "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
1673 | "dev": true,
1674 | "license": "MIT",
1675 | "dependencies": {
1676 | "path-key": "^3.1.0",
1677 | "shebang-command": "^2.0.0",
1678 | "which": "^2.0.1"
1679 | },
1680 | "engines": {
1681 | "node": ">= 8"
1682 | }
1683 | },
1684 | "node_modules/csstype": {
1685 | "version": "3.1.3",
1686 | "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
1687 | "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
1688 | "devOptional": true,
1689 | "license": "MIT"
1690 | },
1691 | "node_modules/debug": {
1692 | "version": "4.4.0",
1693 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
1694 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
1695 | "dev": true,
1696 | "license": "MIT",
1697 | "dependencies": {
1698 | "ms": "^2.1.3"
1699 | },
1700 | "engines": {
1701 | "node": ">=6.0"
1702 | },
1703 | "peerDependenciesMeta": {
1704 | "supports-color": {
1705 | "optional": true
1706 | }
1707 | }
1708 | },
1709 | "node_modules/deep-is": {
1710 | "version": "0.1.4",
1711 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
1712 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
1713 | "dev": true,
1714 | "license": "MIT"
1715 | },
1716 | "node_modules/delayed-stream": {
1717 | "version": "1.0.0",
1718 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
1719 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
1720 | "license": "MIT",
1721 | "engines": {
1722 | "node": ">=0.4.0"
1723 | }
1724 | },
1725 | "node_modules/dunder-proto": {
1726 | "version": "1.0.1",
1727 | "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
1728 | "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
1729 | "license": "MIT",
1730 | "dependencies": {
1731 | "call-bind-apply-helpers": "^1.0.1",
1732 | "es-errors": "^1.3.0",
1733 | "gopd": "^1.2.0"
1734 | },
1735 | "engines": {
1736 | "node": ">= 0.4"
1737 | }
1738 | },
1739 | "node_modules/electron-to-chromium": {
1740 | "version": "1.5.123",
1741 | "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.123.tgz",
1742 | "integrity": "sha512-refir3NlutEZqlKaBLK0tzlVLe5P2wDKS7UQt/3SpibizgsRAPOsqQC3ffw1nlv3ze5gjRQZYHoPymgVZkplFA==",
1743 | "dev": true,
1744 | "license": "ISC"
1745 | },
1746 | "node_modules/es-define-property": {
1747 | "version": "1.0.1",
1748 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
1749 | "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
1750 | "license": "MIT",
1751 | "engines": {
1752 | "node": ">= 0.4"
1753 | }
1754 | },
1755 | "node_modules/es-errors": {
1756 | "version": "1.3.0",
1757 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
1758 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
1759 | "license": "MIT",
1760 | "engines": {
1761 | "node": ">= 0.4"
1762 | }
1763 | },
1764 | "node_modules/es-object-atoms": {
1765 | "version": "1.1.1",
1766 | "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
1767 | "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
1768 | "license": "MIT",
1769 | "dependencies": {
1770 | "es-errors": "^1.3.0"
1771 | },
1772 | "engines": {
1773 | "node": ">= 0.4"
1774 | }
1775 | },
1776 | "node_modules/es-set-tostringtag": {
1777 | "version": "2.1.0",
1778 | "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
1779 | "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
1780 | "license": "MIT",
1781 | "dependencies": {
1782 | "es-errors": "^1.3.0",
1783 | "get-intrinsic": "^1.2.6",
1784 | "has-tostringtag": "^1.0.2",
1785 | "hasown": "^2.0.2"
1786 | },
1787 | "engines": {
1788 | "node": ">= 0.4"
1789 | }
1790 | },
1791 | "node_modules/esbuild": {
1792 | "version": "0.25.1",
1793 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz",
1794 | "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==",
1795 | "dev": true,
1796 | "hasInstallScript": true,
1797 | "license": "MIT",
1798 | "bin": {
1799 | "esbuild": "bin/esbuild"
1800 | },
1801 | "engines": {
1802 | "node": ">=18"
1803 | },
1804 | "optionalDependencies": {
1805 | "@esbuild/aix-ppc64": "0.25.1",
1806 | "@esbuild/android-arm": "0.25.1",
1807 | "@esbuild/android-arm64": "0.25.1",
1808 | "@esbuild/android-x64": "0.25.1",
1809 | "@esbuild/darwin-arm64": "0.25.1",
1810 | "@esbuild/darwin-x64": "0.25.1",
1811 | "@esbuild/freebsd-arm64": "0.25.1",
1812 | "@esbuild/freebsd-x64": "0.25.1",
1813 | "@esbuild/linux-arm": "0.25.1",
1814 | "@esbuild/linux-arm64": "0.25.1",
1815 | "@esbuild/linux-ia32": "0.25.1",
1816 | "@esbuild/linux-loong64": "0.25.1",
1817 | "@esbuild/linux-mips64el": "0.25.1",
1818 | "@esbuild/linux-ppc64": "0.25.1",
1819 | "@esbuild/linux-riscv64": "0.25.1",
1820 | "@esbuild/linux-s390x": "0.25.1",
1821 | "@esbuild/linux-x64": "0.25.1",
1822 | "@esbuild/netbsd-arm64": "0.25.1",
1823 | "@esbuild/netbsd-x64": "0.25.1",
1824 | "@esbuild/openbsd-arm64": "0.25.1",
1825 | "@esbuild/openbsd-x64": "0.25.1",
1826 | "@esbuild/sunos-x64": "0.25.1",
1827 | "@esbuild/win32-arm64": "0.25.1",
1828 | "@esbuild/win32-ia32": "0.25.1",
1829 | "@esbuild/win32-x64": "0.25.1"
1830 | }
1831 | },
1832 | "node_modules/escalade": {
1833 | "version": "3.2.0",
1834 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
1835 | "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
1836 | "dev": true,
1837 | "license": "MIT",
1838 | "engines": {
1839 | "node": ">=6"
1840 | }
1841 | },
1842 | "node_modules/escape-string-regexp": {
1843 | "version": "4.0.0",
1844 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
1845 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
1846 | "dev": true,
1847 | "license": "MIT",
1848 | "engines": {
1849 | "node": ">=10"
1850 | },
1851 | "funding": {
1852 | "url": "https://github.com/sponsors/sindresorhus"
1853 | }
1854 | },
1855 | "node_modules/eslint": {
1856 | "version": "9.22.0",
1857 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.22.0.tgz",
1858 | "integrity": "sha512-9V/QURhsRN40xuHXWjV64yvrzMjcz7ZyNoF2jJFmy9j/SLk0u1OLSZgXi28MrXjymnjEGSR80WCdab3RGMDveQ==",
1859 | "dev": true,
1860 | "license": "MIT",
1861 | "dependencies": {
1862 | "@eslint-community/eslint-utils": "^4.2.0",
1863 | "@eslint-community/regexpp": "^4.12.1",
1864 | "@eslint/config-array": "^0.19.2",
1865 | "@eslint/config-helpers": "^0.1.0",
1866 | "@eslint/core": "^0.12.0",
1867 | "@eslint/eslintrc": "^3.3.0",
1868 | "@eslint/js": "9.22.0",
1869 | "@eslint/plugin-kit": "^0.2.7",
1870 | "@humanfs/node": "^0.16.6",
1871 | "@humanwhocodes/module-importer": "^1.0.1",
1872 | "@humanwhocodes/retry": "^0.4.2",
1873 | "@types/estree": "^1.0.6",
1874 | "@types/json-schema": "^7.0.15",
1875 | "ajv": "^6.12.4",
1876 | "chalk": "^4.0.0",
1877 | "cross-spawn": "^7.0.6",
1878 | "debug": "^4.3.2",
1879 | "escape-string-regexp": "^4.0.0",
1880 | "eslint-scope": "^8.3.0",
1881 | "eslint-visitor-keys": "^4.2.0",
1882 | "espree": "^10.3.0",
1883 | "esquery": "^1.5.0",
1884 | "esutils": "^2.0.2",
1885 | "fast-deep-equal": "^3.1.3",
1886 | "file-entry-cache": "^8.0.0",
1887 | "find-up": "^5.0.0",
1888 | "glob-parent": "^6.0.2",
1889 | "ignore": "^5.2.0",
1890 | "imurmurhash": "^0.1.4",
1891 | "is-glob": "^4.0.0",
1892 | "json-stable-stringify-without-jsonify": "^1.0.1",
1893 | "lodash.merge": "^4.6.2",
1894 | "minimatch": "^3.1.2",
1895 | "natural-compare": "^1.4.0",
1896 | "optionator": "^0.9.3"
1897 | },
1898 | "bin": {
1899 | "eslint": "bin/eslint.js"
1900 | },
1901 | "engines": {
1902 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
1903 | },
1904 | "funding": {
1905 | "url": "https://eslint.org/donate"
1906 | },
1907 | "peerDependencies": {
1908 | "jiti": "*"
1909 | },
1910 | "peerDependenciesMeta": {
1911 | "jiti": {
1912 | "optional": true
1913 | }
1914 | }
1915 | },
1916 | "node_modules/eslint-plugin-react-hooks": {
1917 | "version": "5.2.0",
1918 | "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz",
1919 | "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==",
1920 | "dev": true,
1921 | "license": "MIT",
1922 | "engines": {
1923 | "node": ">=10"
1924 | },
1925 | "peerDependencies": {
1926 | "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0"
1927 | }
1928 | },
1929 | "node_modules/eslint-plugin-react-refresh": {
1930 | "version": "0.4.19",
1931 | "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.19.tgz",
1932 | "integrity": "sha512-eyy8pcr/YxSYjBoqIFSrlbn9i/xvxUFa8CjzAYo9cFjgGXqq1hyjihcpZvxRLalpaWmueWR81xn7vuKmAFijDQ==",
1933 | "dev": true,
1934 | "license": "MIT",
1935 | "peerDependencies": {
1936 | "eslint": ">=8.40"
1937 | }
1938 | },
1939 | "node_modules/eslint-scope": {
1940 | "version": "8.3.0",
1941 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz",
1942 | "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==",
1943 | "dev": true,
1944 | "license": "BSD-2-Clause",
1945 | "dependencies": {
1946 | "esrecurse": "^4.3.0",
1947 | "estraverse": "^5.2.0"
1948 | },
1949 | "engines": {
1950 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
1951 | },
1952 | "funding": {
1953 | "url": "https://opencollective.com/eslint"
1954 | }
1955 | },
1956 | "node_modules/eslint-visitor-keys": {
1957 | "version": "4.2.0",
1958 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
1959 | "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
1960 | "dev": true,
1961 | "license": "Apache-2.0",
1962 | "engines": {
1963 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
1964 | },
1965 | "funding": {
1966 | "url": "https://opencollective.com/eslint"
1967 | }
1968 | },
1969 | "node_modules/espree": {
1970 | "version": "10.3.0",
1971 | "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz",
1972 | "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==",
1973 | "dev": true,
1974 | "license": "BSD-2-Clause",
1975 | "dependencies": {
1976 | "acorn": "^8.14.0",
1977 | "acorn-jsx": "^5.3.2",
1978 | "eslint-visitor-keys": "^4.2.0"
1979 | },
1980 | "engines": {
1981 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
1982 | },
1983 | "funding": {
1984 | "url": "https://opencollective.com/eslint"
1985 | }
1986 | },
1987 | "node_modules/esquery": {
1988 | "version": "1.6.0",
1989 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
1990 | "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
1991 | "dev": true,
1992 | "license": "BSD-3-Clause",
1993 | "dependencies": {
1994 | "estraverse": "^5.1.0"
1995 | },
1996 | "engines": {
1997 | "node": ">=0.10"
1998 | }
1999 | },
2000 | "node_modules/esrecurse": {
2001 | "version": "4.3.0",
2002 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
2003 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
2004 | "dev": true,
2005 | "license": "BSD-2-Clause",
2006 | "dependencies": {
2007 | "estraverse": "^5.2.0"
2008 | },
2009 | "engines": {
2010 | "node": ">=4.0"
2011 | }
2012 | },
2013 | "node_modules/estraverse": {
2014 | "version": "5.3.0",
2015 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
2016 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
2017 | "dev": true,
2018 | "license": "BSD-2-Clause",
2019 | "engines": {
2020 | "node": ">=4.0"
2021 | }
2022 | },
2023 | "node_modules/esutils": {
2024 | "version": "2.0.3",
2025 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
2026 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
2027 | "dev": true,
2028 | "license": "BSD-2-Clause",
2029 | "engines": {
2030 | "node": ">=0.10.0"
2031 | }
2032 | },
2033 | "node_modules/fast-deep-equal": {
2034 | "version": "3.1.3",
2035 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
2036 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
2037 | "dev": true,
2038 | "license": "MIT"
2039 | },
2040 | "node_modules/fast-json-stable-stringify": {
2041 | "version": "2.1.0",
2042 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
2043 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
2044 | "dev": true,
2045 | "license": "MIT"
2046 | },
2047 | "node_modules/fast-levenshtein": {
2048 | "version": "2.0.6",
2049 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
2050 | "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
2051 | "dev": true,
2052 | "license": "MIT"
2053 | },
2054 | "node_modules/file-entry-cache": {
2055 | "version": "8.0.0",
2056 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
2057 | "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
2058 | "dev": true,
2059 | "license": "MIT",
2060 | "dependencies": {
2061 | "flat-cache": "^4.0.0"
2062 | },
2063 | "engines": {
2064 | "node": ">=16.0.0"
2065 | }
2066 | },
2067 | "node_modules/find-up": {
2068 | "version": "5.0.0",
2069 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
2070 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
2071 | "dev": true,
2072 | "license": "MIT",
2073 | "dependencies": {
2074 | "locate-path": "^6.0.0",
2075 | "path-exists": "^4.0.0"
2076 | },
2077 | "engines": {
2078 | "node": ">=10"
2079 | },
2080 | "funding": {
2081 | "url": "https://github.com/sponsors/sindresorhus"
2082 | }
2083 | },
2084 | "node_modules/flat-cache": {
2085 | "version": "4.0.1",
2086 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
2087 | "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
2088 | "dev": true,
2089 | "license": "MIT",
2090 | "dependencies": {
2091 | "flatted": "^3.2.9",
2092 | "keyv": "^4.5.4"
2093 | },
2094 | "engines": {
2095 | "node": ">=16"
2096 | }
2097 | },
2098 | "node_modules/flatted": {
2099 | "version": "3.3.3",
2100 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
2101 | "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
2102 | "dev": true,
2103 | "license": "ISC"
2104 | },
2105 | "node_modules/follow-redirects": {
2106 | "version": "1.15.9",
2107 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
2108 | "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
2109 | "funding": [
2110 | {
2111 | "type": "individual",
2112 | "url": "https://github.com/sponsors/RubenVerborgh"
2113 | }
2114 | ],
2115 | "license": "MIT",
2116 | "engines": {
2117 | "node": ">=4.0"
2118 | },
2119 | "peerDependenciesMeta": {
2120 | "debug": {
2121 | "optional": true
2122 | }
2123 | }
2124 | },
2125 | "node_modules/form-data": {
2126 | "version": "4.0.2",
2127 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz",
2128 | "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==",
2129 | "license": "MIT",
2130 | "dependencies": {
2131 | "asynckit": "^0.4.0",
2132 | "combined-stream": "^1.0.8",
2133 | "es-set-tostringtag": "^2.1.0",
2134 | "mime-types": "^2.1.12"
2135 | },
2136 | "engines": {
2137 | "node": ">= 6"
2138 | }
2139 | },
2140 | "node_modules/fsevents": {
2141 | "version": "2.3.3",
2142 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
2143 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
2144 | "dev": true,
2145 | "hasInstallScript": true,
2146 | "license": "MIT",
2147 | "optional": true,
2148 | "os": [
2149 | "darwin"
2150 | ],
2151 | "engines": {
2152 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
2153 | }
2154 | },
2155 | "node_modules/function-bind": {
2156 | "version": "1.1.2",
2157 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
2158 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
2159 | "license": "MIT",
2160 | "funding": {
2161 | "url": "https://github.com/sponsors/ljharb"
2162 | }
2163 | },
2164 | "node_modules/gensync": {
2165 | "version": "1.0.0-beta.2",
2166 | "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
2167 | "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
2168 | "dev": true,
2169 | "license": "MIT",
2170 | "engines": {
2171 | "node": ">=6.9.0"
2172 | }
2173 | },
2174 | "node_modules/get-intrinsic": {
2175 | "version": "1.3.0",
2176 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
2177 | "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
2178 | "license": "MIT",
2179 | "dependencies": {
2180 | "call-bind-apply-helpers": "^1.0.2",
2181 | "es-define-property": "^1.0.1",
2182 | "es-errors": "^1.3.0",
2183 | "es-object-atoms": "^1.1.1",
2184 | "function-bind": "^1.1.2",
2185 | "get-proto": "^1.0.1",
2186 | "gopd": "^1.2.0",
2187 | "has-symbols": "^1.1.0",
2188 | "hasown": "^2.0.2",
2189 | "math-intrinsics": "^1.1.0"
2190 | },
2191 | "engines": {
2192 | "node": ">= 0.4"
2193 | },
2194 | "funding": {
2195 | "url": "https://github.com/sponsors/ljharb"
2196 | }
2197 | },
2198 | "node_modules/get-proto": {
2199 | "version": "1.0.1",
2200 | "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
2201 | "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
2202 | "license": "MIT",
2203 | "dependencies": {
2204 | "dunder-proto": "^1.0.1",
2205 | "es-object-atoms": "^1.0.0"
2206 | },
2207 | "engines": {
2208 | "node": ">= 0.4"
2209 | }
2210 | },
2211 | "node_modules/glob-parent": {
2212 | "version": "6.0.2",
2213 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
2214 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
2215 | "dev": true,
2216 | "license": "ISC",
2217 | "dependencies": {
2218 | "is-glob": "^4.0.3"
2219 | },
2220 | "engines": {
2221 | "node": ">=10.13.0"
2222 | }
2223 | },
2224 | "node_modules/globals": {
2225 | "version": "15.15.0",
2226 | "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz",
2227 | "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==",
2228 | "dev": true,
2229 | "license": "MIT",
2230 | "engines": {
2231 | "node": ">=18"
2232 | },
2233 | "funding": {
2234 | "url": "https://github.com/sponsors/sindresorhus"
2235 | }
2236 | },
2237 | "node_modules/gopd": {
2238 | "version": "1.2.0",
2239 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
2240 | "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
2241 | "license": "MIT",
2242 | "engines": {
2243 | "node": ">= 0.4"
2244 | },
2245 | "funding": {
2246 | "url": "https://github.com/sponsors/ljharb"
2247 | }
2248 | },
2249 | "node_modules/has-flag": {
2250 | "version": "4.0.0",
2251 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
2252 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
2253 | "dev": true,
2254 | "license": "MIT",
2255 | "engines": {
2256 | "node": ">=8"
2257 | }
2258 | },
2259 | "node_modules/has-symbols": {
2260 | "version": "1.1.0",
2261 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
2262 | "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
2263 | "license": "MIT",
2264 | "engines": {
2265 | "node": ">= 0.4"
2266 | },
2267 | "funding": {
2268 | "url": "https://github.com/sponsors/ljharb"
2269 | }
2270 | },
2271 | "node_modules/has-tostringtag": {
2272 | "version": "1.0.2",
2273 | "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
2274 | "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
2275 | "license": "MIT",
2276 | "dependencies": {
2277 | "has-symbols": "^1.0.3"
2278 | },
2279 | "engines": {
2280 | "node": ">= 0.4"
2281 | },
2282 | "funding": {
2283 | "url": "https://github.com/sponsors/ljharb"
2284 | }
2285 | },
2286 | "node_modules/hasown": {
2287 | "version": "2.0.2",
2288 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
2289 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
2290 | "license": "MIT",
2291 | "dependencies": {
2292 | "function-bind": "^1.1.2"
2293 | },
2294 | "engines": {
2295 | "node": ">= 0.4"
2296 | }
2297 | },
2298 | "node_modules/ignore": {
2299 | "version": "5.3.2",
2300 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
2301 | "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
2302 | "dev": true,
2303 | "license": "MIT",
2304 | "engines": {
2305 | "node": ">= 4"
2306 | }
2307 | },
2308 | "node_modules/immer": {
2309 | "version": "10.1.1",
2310 | "resolved": "https://registry.npmjs.org/immer/-/immer-10.1.1.tgz",
2311 | "integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==",
2312 | "license": "MIT",
2313 | "funding": {
2314 | "type": "opencollective",
2315 | "url": "https://opencollective.com/immer"
2316 | }
2317 | },
2318 | "node_modules/import-fresh": {
2319 | "version": "3.3.1",
2320 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
2321 | "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
2322 | "dev": true,
2323 | "license": "MIT",
2324 | "dependencies": {
2325 | "parent-module": "^1.0.0",
2326 | "resolve-from": "^4.0.0"
2327 | },
2328 | "engines": {
2329 | "node": ">=6"
2330 | },
2331 | "funding": {
2332 | "url": "https://github.com/sponsors/sindresorhus"
2333 | }
2334 | },
2335 | "node_modules/imurmurhash": {
2336 | "version": "0.1.4",
2337 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
2338 | "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
2339 | "dev": true,
2340 | "license": "MIT",
2341 | "engines": {
2342 | "node": ">=0.8.19"
2343 | }
2344 | },
2345 | "node_modules/is-extglob": {
2346 | "version": "2.1.1",
2347 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
2348 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
2349 | "dev": true,
2350 | "license": "MIT",
2351 | "engines": {
2352 | "node": ">=0.10.0"
2353 | }
2354 | },
2355 | "node_modules/is-glob": {
2356 | "version": "4.0.3",
2357 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
2358 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
2359 | "dev": true,
2360 | "license": "MIT",
2361 | "dependencies": {
2362 | "is-extglob": "^2.1.1"
2363 | },
2364 | "engines": {
2365 | "node": ">=0.10.0"
2366 | }
2367 | },
2368 | "node_modules/isexe": {
2369 | "version": "2.0.0",
2370 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
2371 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
2372 | "dev": true,
2373 | "license": "ISC"
2374 | },
2375 | "node_modules/js-tokens": {
2376 | "version": "4.0.0",
2377 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
2378 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
2379 | "dev": true,
2380 | "license": "MIT"
2381 | },
2382 | "node_modules/js-yaml": {
2383 | "version": "4.1.0",
2384 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
2385 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
2386 | "dev": true,
2387 | "license": "MIT",
2388 | "dependencies": {
2389 | "argparse": "^2.0.1"
2390 | },
2391 | "bin": {
2392 | "js-yaml": "bin/js-yaml.js"
2393 | }
2394 | },
2395 | "node_modules/jsesc": {
2396 | "version": "3.1.0",
2397 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
2398 | "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
2399 | "dev": true,
2400 | "license": "MIT",
2401 | "bin": {
2402 | "jsesc": "bin/jsesc"
2403 | },
2404 | "engines": {
2405 | "node": ">=6"
2406 | }
2407 | },
2408 | "node_modules/json-buffer": {
2409 | "version": "3.0.1",
2410 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
2411 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
2412 | "dev": true,
2413 | "license": "MIT"
2414 | },
2415 | "node_modules/json-schema-traverse": {
2416 | "version": "0.4.1",
2417 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
2418 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
2419 | "dev": true,
2420 | "license": "MIT"
2421 | },
2422 | "node_modules/json-stable-stringify-without-jsonify": {
2423 | "version": "1.0.1",
2424 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
2425 | "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
2426 | "dev": true,
2427 | "license": "MIT"
2428 | },
2429 | "node_modules/json5": {
2430 | "version": "2.2.3",
2431 | "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
2432 | "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
2433 | "dev": true,
2434 | "license": "MIT",
2435 | "bin": {
2436 | "json5": "lib/cli.js"
2437 | },
2438 | "engines": {
2439 | "node": ">=6"
2440 | }
2441 | },
2442 | "node_modules/keyv": {
2443 | "version": "4.5.4",
2444 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
2445 | "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
2446 | "dev": true,
2447 | "license": "MIT",
2448 | "dependencies": {
2449 | "json-buffer": "3.0.1"
2450 | }
2451 | },
2452 | "node_modules/levn": {
2453 | "version": "0.4.1",
2454 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
2455 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
2456 | "dev": true,
2457 | "license": "MIT",
2458 | "dependencies": {
2459 | "prelude-ls": "^1.2.1",
2460 | "type-check": "~0.4.0"
2461 | },
2462 | "engines": {
2463 | "node": ">= 0.8.0"
2464 | }
2465 | },
2466 | "node_modules/locate-path": {
2467 | "version": "6.0.0",
2468 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
2469 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
2470 | "dev": true,
2471 | "license": "MIT",
2472 | "dependencies": {
2473 | "p-locate": "^5.0.0"
2474 | },
2475 | "engines": {
2476 | "node": ">=10"
2477 | },
2478 | "funding": {
2479 | "url": "https://github.com/sponsors/sindresorhus"
2480 | }
2481 | },
2482 | "node_modules/lodash.merge": {
2483 | "version": "4.6.2",
2484 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
2485 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
2486 | "dev": true,
2487 | "license": "MIT"
2488 | },
2489 | "node_modules/lru-cache": {
2490 | "version": "5.1.1",
2491 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
2492 | "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
2493 | "dev": true,
2494 | "license": "ISC",
2495 | "dependencies": {
2496 | "yallist": "^3.0.2"
2497 | }
2498 | },
2499 | "node_modules/math-intrinsics": {
2500 | "version": "1.1.0",
2501 | "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
2502 | "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
2503 | "license": "MIT",
2504 | "engines": {
2505 | "node": ">= 0.4"
2506 | }
2507 | },
2508 | "node_modules/mime-db": {
2509 | "version": "1.52.0",
2510 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
2511 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
2512 | "license": "MIT",
2513 | "engines": {
2514 | "node": ">= 0.6"
2515 | }
2516 | },
2517 | "node_modules/mime-types": {
2518 | "version": "2.1.35",
2519 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
2520 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
2521 | "license": "MIT",
2522 | "dependencies": {
2523 | "mime-db": "1.52.0"
2524 | },
2525 | "engines": {
2526 | "node": ">= 0.6"
2527 | }
2528 | },
2529 | "node_modules/minimatch": {
2530 | "version": "3.1.2",
2531 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
2532 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
2533 | "dev": true,
2534 | "license": "ISC",
2535 | "dependencies": {
2536 | "brace-expansion": "^1.1.7"
2537 | },
2538 | "engines": {
2539 | "node": "*"
2540 | }
2541 | },
2542 | "node_modules/ms": {
2543 | "version": "2.1.3",
2544 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
2545 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
2546 | "dev": true,
2547 | "license": "MIT"
2548 | },
2549 | "node_modules/nanoid": {
2550 | "version": "3.3.11",
2551 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
2552 | "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
2553 | "dev": true,
2554 | "funding": [
2555 | {
2556 | "type": "github",
2557 | "url": "https://github.com/sponsors/ai"
2558 | }
2559 | ],
2560 | "license": "MIT",
2561 | "bin": {
2562 | "nanoid": "bin/nanoid.cjs"
2563 | },
2564 | "engines": {
2565 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
2566 | }
2567 | },
2568 | "node_modules/natural-compare": {
2569 | "version": "1.4.0",
2570 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
2571 | "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
2572 | "dev": true,
2573 | "license": "MIT"
2574 | },
2575 | "node_modules/node-releases": {
2576 | "version": "2.0.19",
2577 | "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
2578 | "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
2579 | "dev": true,
2580 | "license": "MIT"
2581 | },
2582 | "node_modules/optionator": {
2583 | "version": "0.9.4",
2584 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
2585 | "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
2586 | "dev": true,
2587 | "license": "MIT",
2588 | "dependencies": {
2589 | "deep-is": "^0.1.3",
2590 | "fast-levenshtein": "^2.0.6",
2591 | "levn": "^0.4.1",
2592 | "prelude-ls": "^1.2.1",
2593 | "type-check": "^0.4.0",
2594 | "word-wrap": "^1.2.5"
2595 | },
2596 | "engines": {
2597 | "node": ">= 0.8.0"
2598 | }
2599 | },
2600 | "node_modules/p-limit": {
2601 | "version": "3.1.0",
2602 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
2603 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
2604 | "dev": true,
2605 | "license": "MIT",
2606 | "dependencies": {
2607 | "yocto-queue": "^0.1.0"
2608 | },
2609 | "engines": {
2610 | "node": ">=10"
2611 | },
2612 | "funding": {
2613 | "url": "https://github.com/sponsors/sindresorhus"
2614 | }
2615 | },
2616 | "node_modules/p-locate": {
2617 | "version": "5.0.0",
2618 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
2619 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
2620 | "dev": true,
2621 | "license": "MIT",
2622 | "dependencies": {
2623 | "p-limit": "^3.0.2"
2624 | },
2625 | "engines": {
2626 | "node": ">=10"
2627 | },
2628 | "funding": {
2629 | "url": "https://github.com/sponsors/sindresorhus"
2630 | }
2631 | },
2632 | "node_modules/parent-module": {
2633 | "version": "1.0.1",
2634 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
2635 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
2636 | "dev": true,
2637 | "license": "MIT",
2638 | "dependencies": {
2639 | "callsites": "^3.0.0"
2640 | },
2641 | "engines": {
2642 | "node": ">=6"
2643 | }
2644 | },
2645 | "node_modules/path-exists": {
2646 | "version": "4.0.0",
2647 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
2648 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
2649 | "dev": true,
2650 | "license": "MIT",
2651 | "engines": {
2652 | "node": ">=8"
2653 | }
2654 | },
2655 | "node_modules/path-key": {
2656 | "version": "3.1.1",
2657 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
2658 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
2659 | "dev": true,
2660 | "license": "MIT",
2661 | "engines": {
2662 | "node": ">=8"
2663 | }
2664 | },
2665 | "node_modules/picocolors": {
2666 | "version": "1.1.1",
2667 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
2668 | "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
2669 | "dev": true,
2670 | "license": "ISC"
2671 | },
2672 | "node_modules/postcss": {
2673 | "version": "8.5.3",
2674 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
2675 | "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
2676 | "dev": true,
2677 | "funding": [
2678 | {
2679 | "type": "opencollective",
2680 | "url": "https://opencollective.com/postcss/"
2681 | },
2682 | {
2683 | "type": "tidelift",
2684 | "url": "https://tidelift.com/funding/github/npm/postcss"
2685 | },
2686 | {
2687 | "type": "github",
2688 | "url": "https://github.com/sponsors/ai"
2689 | }
2690 | ],
2691 | "license": "MIT",
2692 | "dependencies": {
2693 | "nanoid": "^3.3.8",
2694 | "picocolors": "^1.1.1",
2695 | "source-map-js": "^1.2.1"
2696 | },
2697 | "engines": {
2698 | "node": "^10 || ^12 || >=14"
2699 | }
2700 | },
2701 | "node_modules/prelude-ls": {
2702 | "version": "1.2.1",
2703 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
2704 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
2705 | "dev": true,
2706 | "license": "MIT",
2707 | "engines": {
2708 | "node": ">= 0.8.0"
2709 | }
2710 | },
2711 | "node_modules/proxy-from-env": {
2712 | "version": "1.1.0",
2713 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
2714 | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
2715 | "license": "MIT"
2716 | },
2717 | "node_modules/punycode": {
2718 | "version": "2.3.1",
2719 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
2720 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
2721 | "dev": true,
2722 | "license": "MIT",
2723 | "engines": {
2724 | "node": ">=6"
2725 | }
2726 | },
2727 | "node_modules/react": {
2728 | "version": "19.0.0",
2729 | "resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz",
2730 | "integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==",
2731 | "license": "MIT",
2732 | "engines": {
2733 | "node": ">=0.10.0"
2734 | }
2735 | },
2736 | "node_modules/react-dom": {
2737 | "version": "19.0.0",
2738 | "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz",
2739 | "integrity": "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==",
2740 | "license": "MIT",
2741 | "dependencies": {
2742 | "scheduler": "^0.25.0"
2743 | },
2744 | "peerDependencies": {
2745 | "react": "^19.0.0"
2746 | }
2747 | },
2748 | "node_modules/react-redux": {
2749 | "version": "9.2.0",
2750 | "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz",
2751 | "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==",
2752 | "license": "MIT",
2753 | "dependencies": {
2754 | "@types/use-sync-external-store": "^0.0.6",
2755 | "use-sync-external-store": "^1.4.0"
2756 | },
2757 | "peerDependencies": {
2758 | "@types/react": "^18.2.25 || ^19",
2759 | "react": "^18.0 || ^19",
2760 | "redux": "^5.0.0"
2761 | },
2762 | "peerDependenciesMeta": {
2763 | "@types/react": {
2764 | "optional": true
2765 | },
2766 | "redux": {
2767 | "optional": true
2768 | }
2769 | }
2770 | },
2771 | "node_modules/react-refresh": {
2772 | "version": "0.14.2",
2773 | "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
2774 | "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==",
2775 | "dev": true,
2776 | "license": "MIT",
2777 | "engines": {
2778 | "node": ">=0.10.0"
2779 | }
2780 | },
2781 | "node_modules/react-router": {
2782 | "version": "7.4.0",
2783 | "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.4.0.tgz",
2784 | "integrity": "sha512-Y2g5ObjkvX3VFeVt+0CIPuYd9PpgqCslG7ASSIdN73LwA1nNWzcMLaoMRJfP3prZFI92svxFwbn7XkLJ+UPQ6A==",
2785 | "license": "MIT",
2786 | "dependencies": {
2787 | "@types/cookie": "^0.6.0",
2788 | "cookie": "^1.0.1",
2789 | "set-cookie-parser": "^2.6.0",
2790 | "turbo-stream": "2.4.0"
2791 | },
2792 | "engines": {
2793 | "node": ">=20.0.0"
2794 | },
2795 | "peerDependencies": {
2796 | "react": ">=18",
2797 | "react-dom": ">=18"
2798 | },
2799 | "peerDependenciesMeta": {
2800 | "react-dom": {
2801 | "optional": true
2802 | }
2803 | }
2804 | },
2805 | "node_modules/react-router-dom": {
2806 | "version": "7.4.0",
2807 | "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.4.0.tgz",
2808 | "integrity": "sha512-VlksBPf3n2bijPvnA7nkTsXxMAKOj+bWp4R9c3i+bnwlSOFAGOkJkKhzy/OsRkWaBMICqcAl1JDzh9ZSOze9CA==",
2809 | "license": "MIT",
2810 | "dependencies": {
2811 | "react-router": "7.4.0"
2812 | },
2813 | "engines": {
2814 | "node": ">=20.0.0"
2815 | },
2816 | "peerDependencies": {
2817 | "react": ">=18",
2818 | "react-dom": ">=18"
2819 | }
2820 | },
2821 | "node_modules/redux": {
2822 | "version": "5.0.1",
2823 | "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
2824 | "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
2825 | "license": "MIT"
2826 | },
2827 | "node_modules/redux-thunk": {
2828 | "version": "3.1.0",
2829 | "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz",
2830 | "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==",
2831 | "license": "MIT",
2832 | "peerDependencies": {
2833 | "redux": "^5.0.0"
2834 | }
2835 | },
2836 | "node_modules/reselect": {
2837 | "version": "5.1.1",
2838 | "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz",
2839 | "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==",
2840 | "license": "MIT"
2841 | },
2842 | "node_modules/resolve-from": {
2843 | "version": "4.0.0",
2844 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
2845 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
2846 | "dev": true,
2847 | "license": "MIT",
2848 | "engines": {
2849 | "node": ">=4"
2850 | }
2851 | },
2852 | "node_modules/rollup": {
2853 | "version": "4.36.0",
2854 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.36.0.tgz",
2855 | "integrity": "sha512-zwATAXNQxUcd40zgtQG0ZafcRK4g004WtEl7kbuhTWPvf07PsfohXl39jVUvPF7jvNAIkKPQ2XrsDlWuxBd++Q==",
2856 | "dev": true,
2857 | "license": "MIT",
2858 | "dependencies": {
2859 | "@types/estree": "1.0.6"
2860 | },
2861 | "bin": {
2862 | "rollup": "dist/bin/rollup"
2863 | },
2864 | "engines": {
2865 | "node": ">=18.0.0",
2866 | "npm": ">=8.0.0"
2867 | },
2868 | "optionalDependencies": {
2869 | "@rollup/rollup-android-arm-eabi": "4.36.0",
2870 | "@rollup/rollup-android-arm64": "4.36.0",
2871 | "@rollup/rollup-darwin-arm64": "4.36.0",
2872 | "@rollup/rollup-darwin-x64": "4.36.0",
2873 | "@rollup/rollup-freebsd-arm64": "4.36.0",
2874 | "@rollup/rollup-freebsd-x64": "4.36.0",
2875 | "@rollup/rollup-linux-arm-gnueabihf": "4.36.0",
2876 | "@rollup/rollup-linux-arm-musleabihf": "4.36.0",
2877 | "@rollup/rollup-linux-arm64-gnu": "4.36.0",
2878 | "@rollup/rollup-linux-arm64-musl": "4.36.0",
2879 | "@rollup/rollup-linux-loongarch64-gnu": "4.36.0",
2880 | "@rollup/rollup-linux-powerpc64le-gnu": "4.36.0",
2881 | "@rollup/rollup-linux-riscv64-gnu": "4.36.0",
2882 | "@rollup/rollup-linux-s390x-gnu": "4.36.0",
2883 | "@rollup/rollup-linux-x64-gnu": "4.36.0",
2884 | "@rollup/rollup-linux-x64-musl": "4.36.0",
2885 | "@rollup/rollup-win32-arm64-msvc": "4.36.0",
2886 | "@rollup/rollup-win32-ia32-msvc": "4.36.0",
2887 | "@rollup/rollup-win32-x64-msvc": "4.36.0",
2888 | "fsevents": "~2.3.2"
2889 | }
2890 | },
2891 | "node_modules/scheduler": {
2892 | "version": "0.25.0",
2893 | "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.25.0.tgz",
2894 | "integrity": "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==",
2895 | "license": "MIT"
2896 | },
2897 | "node_modules/semver": {
2898 | "version": "6.3.1",
2899 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
2900 | "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
2901 | "dev": true,
2902 | "license": "ISC",
2903 | "bin": {
2904 | "semver": "bin/semver.js"
2905 | }
2906 | },
2907 | "node_modules/set-cookie-parser": {
2908 | "version": "2.7.1",
2909 | "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
2910 | "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
2911 | "license": "MIT"
2912 | },
2913 | "node_modules/shebang-command": {
2914 | "version": "2.0.0",
2915 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
2916 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
2917 | "dev": true,
2918 | "license": "MIT",
2919 | "dependencies": {
2920 | "shebang-regex": "^3.0.0"
2921 | },
2922 | "engines": {
2923 | "node": ">=8"
2924 | }
2925 | },
2926 | "node_modules/shebang-regex": {
2927 | "version": "3.0.0",
2928 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
2929 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
2930 | "dev": true,
2931 | "license": "MIT",
2932 | "engines": {
2933 | "node": ">=8"
2934 | }
2935 | },
2936 | "node_modules/source-map-js": {
2937 | "version": "1.2.1",
2938 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
2939 | "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
2940 | "dev": true,
2941 | "license": "BSD-3-Clause",
2942 | "engines": {
2943 | "node": ">=0.10.0"
2944 | }
2945 | },
2946 | "node_modules/strip-json-comments": {
2947 | "version": "3.1.1",
2948 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
2949 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
2950 | "dev": true,
2951 | "license": "MIT",
2952 | "engines": {
2953 | "node": ">=8"
2954 | },
2955 | "funding": {
2956 | "url": "https://github.com/sponsors/sindresorhus"
2957 | }
2958 | },
2959 | "node_modules/supports-color": {
2960 | "version": "7.2.0",
2961 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
2962 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
2963 | "dev": true,
2964 | "license": "MIT",
2965 | "dependencies": {
2966 | "has-flag": "^4.0.0"
2967 | },
2968 | "engines": {
2969 | "node": ">=8"
2970 | }
2971 | },
2972 | "node_modules/turbo-stream": {
2973 | "version": "2.4.0",
2974 | "resolved": "https://registry.npmjs.org/turbo-stream/-/turbo-stream-2.4.0.tgz",
2975 | "integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==",
2976 | "license": "ISC"
2977 | },
2978 | "node_modules/type-check": {
2979 | "version": "0.4.0",
2980 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
2981 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
2982 | "dev": true,
2983 | "license": "MIT",
2984 | "dependencies": {
2985 | "prelude-ls": "^1.2.1"
2986 | },
2987 | "engines": {
2988 | "node": ">= 0.8.0"
2989 | }
2990 | },
2991 | "node_modules/update-browserslist-db": {
2992 | "version": "1.1.3",
2993 | "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
2994 | "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
2995 | "dev": true,
2996 | "funding": [
2997 | {
2998 | "type": "opencollective",
2999 | "url": "https://opencollective.com/browserslist"
3000 | },
3001 | {
3002 | "type": "tidelift",
3003 | "url": "https://tidelift.com/funding/github/npm/browserslist"
3004 | },
3005 | {
3006 | "type": "github",
3007 | "url": "https://github.com/sponsors/ai"
3008 | }
3009 | ],
3010 | "license": "MIT",
3011 | "dependencies": {
3012 | "escalade": "^3.2.0",
3013 | "picocolors": "^1.1.1"
3014 | },
3015 | "bin": {
3016 | "update-browserslist-db": "cli.js"
3017 | },
3018 | "peerDependencies": {
3019 | "browserslist": ">= 4.21.0"
3020 | }
3021 | },
3022 | "node_modules/uri-js": {
3023 | "version": "4.4.1",
3024 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
3025 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
3026 | "dev": true,
3027 | "license": "BSD-2-Clause",
3028 | "dependencies": {
3029 | "punycode": "^2.1.0"
3030 | }
3031 | },
3032 | "node_modules/use-sync-external-store": {
3033 | "version": "1.4.0",
3034 | "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz",
3035 | "integrity": "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==",
3036 | "license": "MIT",
3037 | "peerDependencies": {
3038 | "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
3039 | }
3040 | },
3041 | "node_modules/vite": {
3042 | "version": "6.2.2",
3043 | "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.2.tgz",
3044 | "integrity": "sha512-yW7PeMM+LkDzc7CgJuRLMW2Jz0FxMOsVJ8Lv3gpgW9WLcb9cTW+121UEr1hvmfR7w3SegR5ItvYyzVz1vxNJgQ==",
3045 | "dev": true,
3046 | "license": "MIT",
3047 | "dependencies": {
3048 | "esbuild": "^0.25.0",
3049 | "postcss": "^8.5.3",
3050 | "rollup": "^4.30.1"
3051 | },
3052 | "bin": {
3053 | "vite": "bin/vite.js"
3054 | },
3055 | "engines": {
3056 | "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
3057 | },
3058 | "funding": {
3059 | "url": "https://github.com/vitejs/vite?sponsor=1"
3060 | },
3061 | "optionalDependencies": {
3062 | "fsevents": "~2.3.3"
3063 | },
3064 | "peerDependencies": {
3065 | "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
3066 | "jiti": ">=1.21.0",
3067 | "less": "*",
3068 | "lightningcss": "^1.21.0",
3069 | "sass": "*",
3070 | "sass-embedded": "*",
3071 | "stylus": "*",
3072 | "sugarss": "*",
3073 | "terser": "^5.16.0",
3074 | "tsx": "^4.8.1",
3075 | "yaml": "^2.4.2"
3076 | },
3077 | "peerDependenciesMeta": {
3078 | "@types/node": {
3079 | "optional": true
3080 | },
3081 | "jiti": {
3082 | "optional": true
3083 | },
3084 | "less": {
3085 | "optional": true
3086 | },
3087 | "lightningcss": {
3088 | "optional": true
3089 | },
3090 | "sass": {
3091 | "optional": true
3092 | },
3093 | "sass-embedded": {
3094 | "optional": true
3095 | },
3096 | "stylus": {
3097 | "optional": true
3098 | },
3099 | "sugarss": {
3100 | "optional": true
3101 | },
3102 | "terser": {
3103 | "optional": true
3104 | },
3105 | "tsx": {
3106 | "optional": true
3107 | },
3108 | "yaml": {
3109 | "optional": true
3110 | }
3111 | }
3112 | },
3113 | "node_modules/which": {
3114 | "version": "2.0.2",
3115 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
3116 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
3117 | "dev": true,
3118 | "license": "ISC",
3119 | "dependencies": {
3120 | "isexe": "^2.0.0"
3121 | },
3122 | "bin": {
3123 | "node-which": "bin/node-which"
3124 | },
3125 | "engines": {
3126 | "node": ">= 8"
3127 | }
3128 | },
3129 | "node_modules/word-wrap": {
3130 | "version": "1.2.5",
3131 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
3132 | "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
3133 | "dev": true,
3134 | "license": "MIT",
3135 | "engines": {
3136 | "node": ">=0.10.0"
3137 | }
3138 | },
3139 | "node_modules/yallist": {
3140 | "version": "3.1.1",
3141 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
3142 | "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
3143 | "dev": true,
3144 | "license": "ISC"
3145 | },
3146 | "node_modules/yocto-queue": {
3147 | "version": "0.1.0",
3148 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
3149 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
3150 | "dev": true,
3151 | "license": "MIT",
3152 | "engines": {
3153 | "node": ">=10"
3154 | },
3155 | "funding": {
3156 | "url": "https://github.com/sponsors/sindresorhus"
3157 | }
3158 | }
3159 | }
3160 | }
3161 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "recipe-app",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "lint": "eslint .",
10 | "preview": "vite preview"
11 | },
12 | "dependencies": {
13 | "@reduxjs/toolkit": "^2.6.1",
14 | "axios": "^1.8.4",
15 | "react": "^19.0.0",
16 | "react-dom": "^19.0.0",
17 | "react-redux": "^9.2.0",
18 | "react-router-dom": "^7.4.0"
19 | },
20 | "devDependencies": {
21 | "@eslint/js": "^9.21.0",
22 | "@types/react": "^19.0.10",
23 | "@types/react-dom": "^19.0.4",
24 | "@vitejs/plugin-react": "^4.3.4",
25 | "eslint": "^9.21.0",
26 | "eslint-plugin-react-hooks": "^5.1.0",
27 | "eslint-plugin-react-refresh": "^0.4.19",
28 | "globals": "^15.15.0",
29 | "vite": "^6.2.0"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/public/_redirects:
--------------------------------------------------------------------------------
1 | /* /index.html 200
--------------------------------------------------------------------------------
/src/components/Footer.jsx:
--------------------------------------------------------------------------------
1 | const Footer = () => {
2 | return (
3 |
6 | );
7 | };
8 |
9 | export default Footer;
10 |
--------------------------------------------------------------------------------
/src/components/Navbar.jsx:
--------------------------------------------------------------------------------
1 | import { NavLink } from "react-router-dom";
2 |
3 | const Navbar = () => {
4 | return (
5 |
58 | );
59 | };
60 |
61 | const styles = {
62 | navbar: {
63 | display: "flex",
64 | justifyContent: "space-between",
65 | alignItems: "center",
66 | padding: "15px 30px",
67 | backgroundColor: "#ff6347",
68 | color: "white",
69 | flexWrap: "wrap",
70 | },
71 | logo: {
72 | fontSize: "1.5rem",
73 | },
74 | navLinks: {
75 | listStyle: "none",
76 | display: "flex",
77 | gap: "15px",
78 | flexWrap: "wrap",
79 | },
80 | };
81 |
82 | export default Navbar;
83 |
--------------------------------------------------------------------------------
/src/context/FavoritesContext.jsx:
--------------------------------------------------------------------------------
1 | import { createContext, useState, useContext } from "react";
2 |
3 | // Create context
4 | const FavoritesContext = createContext();
5 |
6 | // Custom hook to use context
7 | export const useFavorites = () => {
8 | return useContext(FavoritesContext);
9 | };
10 |
11 | // Favorites provider component
12 | export const FavoritesProvider = ({ children }) => {
13 | const [favorites, setFavorites] = useState([]);
14 |
15 | // 🔹 Store all recipes in context
16 | const [recipes] = useState([
17 | { id: "1", name: "Spaghetti Carbonara", category: "Italian", image: "https://source.unsplash.com/200x150/?pasta" },
18 | { id: "2", name: "Chicken Tikka Masala", category: "Indian", image: "https://source.unsplash.com/200x150/?chicken" },
19 | { id: "3", name: "Vegetable Stir Fry", category: "Asian", image: "https://source.unsplash.com/200x150/?vegetables" },
20 | { id: "4", name: "Beef Tacos", category: "Mexican", image: "https://source.unsplash.com/200x150/?tacos" },
21 | ]);
22 |
23 | // Function to add a recipe to favorites
24 | const addToFavorites = (recipe) => {
25 | setFavorites((prevFavorites) => {
26 | if (!prevFavorites.some((fav) => fav.id === recipe.id)) {
27 | return [...prevFavorites, recipe];
28 | }
29 | return prevFavorites;
30 | });
31 | };
32 |
33 | return (
34 |
35 | {children}
36 |
37 | );
38 | };
39 |
--------------------------------------------------------------------------------
/src/images/IMG_9525-2-500x500.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itzxtito/capstone-frontend/2f15442d4abb30ddc6ed02233bdb03fce09d4a8e/src/images/IMG_9525-2-500x500.jpg
--------------------------------------------------------------------------------
/src/main.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom/client";
3 | import AppRoutes from "./routes";
4 | import "./styles.css";
5 | import { FavoritesProvider } from "./context/FavoritesContext"; // Import context provider
6 |
7 | ReactDOM.createRoot(document.getElementById("root")).render(
8 |
9 | {/* Wrap entire app with provider */}
10 |
11 |
12 |
13 | );
14 |
--------------------------------------------------------------------------------
/src/pages/AddRecipe.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import axios from "axios";
3 | import { useNavigate } from "react-router-dom";
4 |
5 | const AddRecipe = () => {
6 | const navigate = useNavigate();
7 | const [recipeData, setRecipeData] = useState({
8 | name: "",
9 | category: "",
10 | ingredients: "",
11 | instructions: "",
12 | image: null
13 | });
14 | const [error, setError] = useState("");
15 |
16 | // Get the logged-in username and token from localStorage
17 | const username = localStorage.getItem("username");
18 | const token = localStorage.getItem("token");
19 |
20 | const handleChange = (e) => {
21 | const { name, value, files } = e.target;
22 | if (name === "image") {
23 | setRecipeData({ ...recipeData, image: files[0] });
24 | } else {
25 | setRecipeData({ ...recipeData, [name]: value });
26 | }
27 | };
28 |
29 | const handleSubmit = async (e) => {
30 | e.preventDefault();
31 | setError("");
32 |
33 | const formData = new FormData();
34 | formData.append("name", recipeData.name);
35 | formData.append("category", recipeData.category);
36 | formData.append("ingredients", recipeData.ingredients);
37 | formData.append("instructions", recipeData.instructions);
38 | formData.append("image", recipeData.image);
39 | formData.append("author", username); // Automatically set the author to the logged-in username
40 |
41 | try {
42 | // Add token to the Authorization header
43 | const response = await axios.post(`${import.meta.env.VITE_API_URL}/api/recipes`, formData, {
44 | headers: {
45 | "Content-Type": "multipart/form-data",
46 | Authorization: `Bearer ${token}`, // Add JWT token here
47 | },
48 | });
49 |
50 | alert("Recipe Submitted Successfully");
51 | navigate("/recipes");
52 | } catch (err) {
53 | console.error("Error adding recipe:", err);
54 | setError("Failed to submit recipe. Please try again.");
55 | }
56 | };
57 |
58 | return (
59 |
60 |
61 |
62 |
63 |
Submit a New Recipe
64 | {error &&
{error}
}
65 |
73 |
74 |
75 |
76 |
77 | );
78 | };
79 |
80 | export default AddRecipe;
81 |
--------------------------------------------------------------------------------
/src/pages/EditRecipe.jsx:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from "react";
2 | import { useParams, useNavigate } from "react-router-dom";
3 | import axios from "axios";
4 |
5 | const EditRecipe = () => {
6 | const { id } = useParams();
7 | const navigate = useNavigate();
8 | const [formData, setFormData] = useState({
9 | name: "",
10 | category: "",
11 | ingredients: "",
12 | instructions: "",
13 | image: null,
14 | });
15 |
16 | useEffect(() => {
17 | const fetchRecipe = async () => {
18 | try {
19 | const response = await axios.get(`${import.meta.env.VITE_API_URL}/api/recipes/${id}`);
20 | setFormData({
21 | name: response.data.name,
22 | category: response.data.category,
23 | ingredients: response.data.ingredients.join(", "),
24 | instructions: response.data.instructions,
25 | image: null, // Don’t prefill file input
26 | });
27 | } catch (error) {
28 | console.error("Error fetching recipe:", error);
29 | }
30 | };
31 |
32 | fetchRecipe();
33 | }, [id]);
34 |
35 | const handleChange = (e) => {
36 | const { name, value } = e.target;
37 | setFormData({ ...formData, [name]: value });
38 | };
39 |
40 | const handleFileChange = (e) => {
41 | setFormData({ ...formData, image: e.target.files[0] });
42 | };
43 |
44 | const handleSubmit = async (e) => {
45 | e.preventDefault();
46 | const token = localStorage.getItem("token");
47 |
48 | const formDataToSend = new FormData();
49 | formDataToSend.append("name", formData.name);
50 | formDataToSend.append("category", formData.category);
51 | formDataToSend.append("ingredients", formData.ingredients);
52 | formDataToSend.append("instructions", formData.instructions);
53 | if (formData.image) {
54 | formDataToSend.append("image", formData.image);
55 | }
56 |
57 | try {
58 | await axios.put(`${import.meta.env.VITE_API_URL}/api/recipes/${id}`, formDataToSend, {
59 | headers: {
60 | Authorization: `Bearer ${token}`,
61 | "Content-Type": "multipart/form-data",
62 | },
63 | });
64 |
65 | alert("Recipe updated successfully!");
66 | navigate("/profile");
67 | } catch (error) {
68 | console.error("Error updating recipe:", error);
69 | alert("Failed to update recipe. Make sure you're logged in.");
70 | }
71 | };
72 |
73 | return (
74 |
116 | );
117 | };
118 |
119 | export default EditRecipe;
120 |
--------------------------------------------------------------------------------
/src/pages/Home.jsx:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from "react";
2 | import { Link } from "react-router-dom";
3 | import axios from "axios";
4 |
5 | const Home = () => {
6 | const [featuredRecipes, setFeaturedRecipes] = useState([]);
7 |
8 | useEffect(() => {
9 | const fetchFeaturedRecipes = async () => {
10 | try {
11 | const response = await axios.get(`${import.meta.env.VITE_API_URL}/api/recipes/featured`);
12 | setFeaturedRecipes(response.data);
13 | } catch (error) {
14 | console.error("Error fetching featured recipes:", error);
15 | }
16 | };
17 |
18 | fetchFeaturedRecipes();
19 | }, []);
20 |
21 | return (
22 |
23 |
24 |
25 |
🍽️ Welcome to the Potluck!
26 |
Discover delicious recipes from around the world or share your own!
27 |
28 |
29 |
30 | ✨ Featured Recipes
31 |
32 | {featuredRecipes.length > 0 ? (
33 | featuredRecipes.map((recipe) => (
34 |
35 |

36 |
{recipe.name}
37 |
By: {recipe.author}
38 |
39 | ))
40 | ) : (
41 |
No recipes available.
42 | )}
43 |
44 |
45 |
46 |
47 | );
48 | };
49 |
50 | export default Home;
51 |
--------------------------------------------------------------------------------
/src/pages/Login.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import axios from "axios";
3 | import { useNavigate } from "react-router-dom";
4 |
5 | const Login = () => {
6 | const [formData, setFormData] = useState({
7 | email: "",
8 | password: "",
9 | });
10 | const [error, setError] = useState("");
11 | const navigate = useNavigate();
12 |
13 | const handleChange = (e) => {
14 | setFormData({ ...formData, [e.target.name]: e.target.value });
15 | };
16 |
17 | const handleSubmit = async (e) => {
18 | e.preventDefault();
19 | setError("");
20 |
21 | try {
22 | const response = await axios.post(`${import.meta.env.VITE_API_URL}/api/auth/login`, formData);
23 |
24 | // ✅ Save token & username in localStorage
25 | localStorage.setItem("token", response.data.token);
26 | localStorage.setItem("username", response.data.username);
27 |
28 | alert("Login successful!");
29 | navigate("/profile"); // ✅ Redirect to profile page after login
30 | } catch (error) {
31 | setError(error.response?.data?.error || "Login failed");
32 | }
33 | };
34 |
35 | return (
36 |
37 |
38 |
39 |
40 |
Login
41 | {error &&
{error}
}
42 |
59 |
Don't have an account? Sign up
60 |
61 |
62 |
63 |
64 | );
65 | };
66 |
67 | export default Login;
68 |
--------------------------------------------------------------------------------
/src/pages/RecipeDetails.jsx:
--------------------------------------------------------------------------------
1 | import { useParams } from "react-router-dom";
2 | import { useState, useEffect } from "react";
3 | import axios from "axios";
4 |
5 | const RecipeDetails = () => {
6 | const { id } = useParams();
7 | const [recipe, setRecipe] = useState(null);
8 | const [comments, setComments] = useState([]);
9 | const [newComment, setNewComment] = useState("");
10 | const [commentSuccess, setCommentSuccess] = useState(false);
11 |
12 | const [username, setUsername] = useState(localStorage.getItem("username")); // Get the logged-in username from localStorage
13 |
14 | useEffect(() => {
15 | const fetchRecipe = async () => {
16 | try {
17 | const response = await axios.get(`${import.meta.env.VITE_API_URL}/api/recipes/${id}`);
18 | setRecipe(response.data);
19 | } catch (error) {
20 | console.error("Error fetching recipe:", error);
21 | }
22 | };
23 |
24 | const fetchComments = async () => {
25 | try {
26 | const response = await axios.get(`${import.meta.env.VITE_API_URL}/api/comments/${id}`);
27 | setComments(response.data);
28 | } catch (error) {
29 | console.error("Error fetching comments:", error);
30 | }
31 | };
32 |
33 | fetchRecipe();
34 | fetchComments();
35 | }, [id]);
36 |
37 | const handleAddToFavorites = async () => {
38 | const username = localStorage.getItem("username"); // Get the username from localStorage
39 |
40 | try {
41 | await axios.post(`${import.meta.env.VITE_API_URL}/api/users/${username}/favorites`, {
42 | recipeId: recipe._id,
43 | }, {
44 | headers: {
45 | Authorization: `Bearer ${localStorage.getItem("token")}`,
46 | },
47 | });
48 |
49 | alert("Recipe added to favorites!");
50 | } catch (error) {
51 | console.error("Error adding to favorites:", error);
52 | alert("Failed to add to favorites.");
53 | }
54 | };
55 |
56 | const handleCommentSubmit = async (e) => {
57 | e.preventDefault();
58 | if (!newComment.trim()) return;
59 |
60 | try {
61 | const response = await axios.post(`${import.meta.env.VITE_API_URL}/api/comments/${id}`, {
62 | username: localStorage.getItem("username"),
63 | text: newComment,
64 | });
65 |
66 | setComments([...comments, response.data]);
67 | setNewComment("");
68 | setCommentSuccess(true);
69 |
70 | // Hide success message after 2 seconds
71 | setTimeout(() => setCommentSuccess(false), 2000);
72 | } catch (error) {
73 | console.error("Error adding comment:", error);
74 | }
75 | };
76 |
77 |
78 | if (!recipe) return Recipe not found!
;
79 |
80 | return (
81 |
82 |
83 |
{recipe.name}
84 |
Posted by: {recipe.author}
85 |

86 |
87 | Ingredients:
88 |
89 | {recipe.ingredients.map((ingredient, index) => (
90 | - {ingredient}
91 | ))}
92 |
93 |
94 |
95 |
96 | Instructions:
97 |
98 | {recipe.instructions}
99 |
100 |
101 |
102 | {/* ✅ Restore "Add to Favorites" button */}
103 |
104 |
107 |
108 |
109 |
110 | {/* ✅ Comments Section */}
111 |
112 | Comments
113 |
114 | {comments.length > 0 ? (
115 | comments.map((comment, index) => (
116 |
117 | {comment.username}
118 | “{comment.text}”
119 |
120 | ))
121 | ) : (
122 |
No comments yet. Be the first to comment!
123 | )}
124 |
125 |
126 |
127 |
128 | {/* ✅ Add Comment Form (No "Your Name" field, username is taken from localStorage) */}
129 |
140 | {commentSuccess && (
141 |
✅ Comment posted!
142 | )}
143 |
144 |
145 |
146 | );
147 | };
148 |
149 | export default RecipeDetails;
150 |
--------------------------------------------------------------------------------
/src/pages/RecipeList.jsx:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from "react";
2 | import { Link } from "react-router-dom";
3 | import axios from "axios";
4 |
5 | const RecipeList = () => {
6 | const [recipes, setRecipes] = useState([]);
7 | const [searchTerm, setSearchTerm] = useState("");
8 | const [category, setCategory] = useState("All");
9 | const [loading, setLoading] = useState(true);
10 |
11 | useEffect(() => {
12 | const fetchRecipes = async () => {
13 | try {
14 | const response = await axios.get(`https://capstone-backend-zdhp.onrender.com/api/recipes`, {
15 | params: {
16 | search: searchTerm,
17 | category: category !== "All" ? category : undefined,
18 | },
19 | });
20 | setRecipes(response.data);
21 | } catch (error) {
22 | console.error("Error fetching recipes:", error);
23 | } finally {
24 | setLoading(false);
25 | }
26 | };
27 |
28 | fetchRecipes();
29 | }, [searchTerm, category]);
30 |
31 | if (loading) return Loading recipes...
;
32 |
33 | return (
34 |
35 |
36 |
37 |
Browse Recipes
38 |
39 | {/* Search Bar */}
40 |
setSearchTerm(e.target.value)}
45 | className="search-bar"
46 | />
47 |
48 | {/* Filter Dropdown */}
49 |
50 |
82 |
83 |
84 |
85 | {/* Recipe Grid */}
86 |
87 | {recipes.length > 0 ? (
88 | recipes.map((recipe) => (
89 |
93 |
94 |

98 |
{recipe.name}
99 |
100 |
101 |
102 | ))
103 | ) : (
104 |
No recipes found.
105 | )}
106 |
107 |
108 |
109 |
110 | );
111 | };
112 |
113 | export default RecipeList;
114 |
--------------------------------------------------------------------------------
/src/pages/Signup.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import axios from "axios";
3 | import { useNavigate } from "react-router-dom";
4 |
5 | const Signup = () => {
6 | const [formData, setFormData] = useState({
7 | username: "",
8 | email: "",
9 | password: "",
10 | });
11 | const [error, setError] = useState("");
12 | const navigate = useNavigate();
13 |
14 | const handleChange = (e) => {
15 | setFormData({ ...formData, [e.target.name]: e.target.value });
16 | };
17 |
18 | const handleSubmit = async (e) => {
19 | e.preventDefault();
20 | setError("");
21 |
22 | try {
23 | const response = await axios.post(`${import.meta.env.VITE_API_URL}/api/auth/register`, formData);
24 | alert(response.data.message);
25 | navigate("/login"); // ✅ Redirect to login page after successful signup
26 | } catch (error) {
27 | setError(error.response?.data?.error || "Registration failed");
28 | }
29 | };
30 |
31 | return (
32 |
49 | );
50 | };
51 |
52 | export default Signup;
53 |
--------------------------------------------------------------------------------
/src/pages/UserProfile.jsx:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from "react";
2 | import { Link, useNavigate } from "react-router-dom";
3 | import axios from "axios";
4 |
5 | const UserProfile = () => {
6 | const navigate = useNavigate();
7 | const username = localStorage.getItem("username");
8 | const [createdRecipes, setCreatedRecipes] = useState([]);
9 | const [favoriteRecipes, setFavoriteRecipes] = useState([]);
10 | const [error, setError] = useState("");
11 |
12 | useEffect(() => {
13 | const token = localStorage.getItem("token");
14 |
15 | if (!token || !username) {
16 | navigate("/login");
17 | } else {
18 | const fetchRecipes = async () => {
19 | try {
20 | const createdRes = await axios.get(`${import.meta.env.VITE_API_URL}/api/recipes?author=${username}`);
21 | const favoriteRes = await axios.get(`${import.meta.env.VITE_API_URL}/api/users/${username}/favorites`);
22 |
23 | setCreatedRecipes(createdRes.data);
24 | setFavoriteRecipes(favoriteRes.data);
25 | } catch (error) {
26 | console.error("Error fetching user recipes:", error);
27 | setError("Failed to load recipes.");
28 | }
29 | };
30 |
31 | fetchRecipes();
32 | }
33 | }, [navigate, username]);
34 |
35 | const handleDelete = async (recipeId, recipeAuthor) => {
36 | console.log(`🛠 Attempting to delete: Recipe ID ${recipeId} by ${recipeAuthor}`);
37 |
38 | try {
39 | await axios.delete(`${import.meta.env.VITE_API_URL}/api/recipes/${recipeId}`, {
40 | data: { author: recipeAuthor },
41 | headers: {
42 | Authorization: `Bearer ${localStorage.getItem("token")}`,
43 | },
44 | });
45 |
46 | setCreatedRecipes(createdRecipes.filter(recipe => recipe._id !== recipeId));
47 | alert("Recipe deleted successfully!");
48 | } catch (error) {
49 | console.error("❌ Error deleting recipe:", error.response?.data || error);
50 | alert("Failed to delete recipe.");
51 | }
52 | };
53 |
54 | const handleRemoveFavorite = async (recipeId) => {
55 | try {
56 | await axios.delete(`${import.meta.env.VITE_API_URL}/api/users/${username}/favorites/${recipeId}`);
57 | setFavoriteRecipes(favoriteRecipes.filter(recipe => recipe._id !== recipeId));
58 | alert("Removed from favorites!");
59 | } catch (error) {
60 | console.error("Error removing favorite:", error);
61 | alert("Failed to remove from favorites.");
62 | }
63 | };
64 |
65 | const handleLogout = () => {
66 | localStorage.removeItem("token");
67 | localStorage.removeItem("username");
68 | window.location.href = "/login";
69 | };
70 |
71 | return (
72 |
73 |
74 |
75 |

80 |
Welcome, {username}!
81 |
82 |
83 |
84 | {error &&
{error}
}
85 |
86 |
🍽️ Created Recipes
87 | {createdRecipes.length > 0 ? (
88 |
89 | {createdRecipes.map((recipe) => (
90 |
91 |
92 |

93 |
{recipe.name}
94 |
95 |
96 |
99 | Edit
100 |
101 |
102 | ))}
103 |
104 | ) : (
105 |
You haven't created any recipes yet.
106 | )}
107 |
108 |
⭐ Favorite Recipes
109 | {favoriteRecipes.length > 0 ? (
110 |
111 | {favoriteRecipes.map((recipe) => (
112 |
113 |
114 |

115 |
{recipe.name}
116 |
117 |
123 |
124 | ))}
125 |
126 | ) : (
127 |
You haven't saved any favorite recipes yet.
128 | )}
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 | );
138 | };
139 |
140 | const styles = {
141 | logoutButton: {
142 | backgroundColor: "#ff6347",
143 | border: "none",
144 | color: "white",
145 | padding: "10px 15px",
146 | cursor: "pointer",
147 | marginBottom: "20px",
148 | },
149 | };
150 |
151 | export default UserProfile;
152 |
--------------------------------------------------------------------------------
/src/routes.jsx:
--------------------------------------------------------------------------------
1 | import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
2 | import Navbar from "./components/Navbar";
3 | import Home from "./pages/Home";
4 | import RecipeList from "./pages/RecipeList";
5 | import RecipeDetails from "./pages/RecipeDetails";
6 | import UserProfile from "./pages/UserProfile";
7 | import AddRecipe from "./pages/AddRecipe";
8 | import EditRecipe from "./pages/EditRecipe";
9 | import Signup from "./pages/Signup";
10 | import Login from "./pages/Login"; // ✅ Import login page
11 | import Footer from "./components/Footer";
12 |
13 | function AppRoutes() {
14 | return (
15 |
16 |
17 |
18 |
19 | } />
20 | } />
21 | } />
22 | } />
23 | } />
24 | } />
25 | } /> {/* ✅ Added Signup Route */}
26 | } /> ✅ Added Login Route
27 |
28 |
29 |
30 |
31 |
32 | );
33 | }
34 |
35 | export default AppRoutes;
36 |
--------------------------------------------------------------------------------
/src/styles.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Fredoka:wght@500;700&family=Nunito:wght@400;600&display=swap');
2 | body {
3 | font-family: 'Nunito', sans-serif;
4 | font-weight: 2;
5 | }
6 |
7 | h1, h2, h3, .recipe-card h3, .featured-card h3 {
8 | font-family: 'Fredoka', sans-serif;
9 | font-weight: 500;
10 | color: white;
11 | }
12 |
13 |
14 |
15 |
16 |
17 | /* Global Styles */
18 | * {
19 | margin: 0;
20 | padding: 0;
21 | box-sizing: border-box;
22 |
23 | }
24 |
25 | body {
26 | background-color: #faf3e0;
27 | color: #333;
28 | line-height: 1.6;
29 | }
30 |
31 | .container {
32 | width: 90%;
33 | max-width: 1100px;
34 | margin: auto;
35 | padding: 20px;
36 | }
37 |
38 | .container h2,
39 | .container h3 {
40 | margin-bottom: 20px;
41 | color: #333;
42 | }
43 |
44 | /* Global Inputs and Textareas */
45 | input[type="text"],
46 | input[type="email"],
47 | input[type="password"],
48 | input[type="file"],
49 | textarea {
50 | width: 100%;
51 | padding: 10px;
52 | margin-bottom: 15px;
53 | border: 1px solid #ccc;
54 | border-radius: 8px;
55 | font-size: 1rem;
56 | }
57 |
58 | /* Global Buttons */
59 | button {
60 | background-color: #ff6347;
61 | color: white;
62 | border: none;
63 | padding: 10px 18px;
64 | border-radius: 8px;
65 | font-size: 1rem;
66 | cursor: pointer;
67 | margin-bottom: 20px;
68 | margin-top: 20px;
69 |
70 | /* Smoothed transition */
71 | transition: transform 0.25s cubic-bezier(0.22, 1, 0.36, 1), background-color 0.3s ease;
72 | }
73 |
74 | button:hover {
75 | background-color: #e5533d;
76 | transform: scale(1.05);
77 | }
78 | .button-group {
79 | display: flex;
80 | justify-content: center;
81 | gap: 12px;
82 | margin-top: 15px;
83 | }
84 |
85 | .recipe-card .button-group button,
86 | .recipe-card .button-group a {
87 | margin: 0;
88 | }
89 |
90 |
91 |
92 |
93 | .edit-btn {
94 | background-color: #007bff;
95 | margin-left: 10px;
96 | }
97 |
98 | .edit-btn:hover {
99 | background-color: #0056b3;
100 | }
101 |
102 | .delete-btn {
103 | background-color: #dc3545;
104 | margin-top: 10px;
105 | }
106 |
107 | .delete-btn:hover {
108 | background-color: #c82333;
109 | }
110 |
111 | .save-btn {
112 | margin-top: 10px;
113 | background-color: #ff6347;
114 | }
115 |
116 | .save-btn:hover {
117 | background-color: #e5533d;
118 | }
119 |
120 | /* Error message */
121 | .error {
122 | color: red;
123 | margin-bottom: 10px;
124 | }
125 |
126 | /* Links */
127 | a {
128 | text-decoration: none;
129 | color: inherit;
130 | }
131 |
132 | /* ---------------------- */
133 | /* Home & Recipe Grid */
134 | /* ---------------------- */
135 | .recipe-grid {
136 | display: grid;
137 | grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
138 | gap: 20px;
139 | margin-top: 20px;
140 | }
141 |
142 |
143 |
144 | .recipe-card:hover {
145 | transform: scale(1.05);
146 | box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
147 | }
148 |
149 | .recipe-card img {
150 | width: 100%;
151 | height: 150px;
152 | object-fit: cover;
153 | border-radius: 8px;
154 | }
155 |
156 | .recipe-card h3 {
157 | margin-top: 10px;
158 | font-size: 1.1rem;
159 | }
160 |
161 |
162 |
163 |
164 | /* ---------------------- */
165 | /* Recipe List Page */
166 | /* ---------------------- */
167 | .search-bar {
168 | width: 100%;
169 | padding: 10px;
170 | margin: 15px 0;
171 | border: 1px solid #ccc;
172 | border-radius: 5px;
173 | }
174 |
175 | .filter-buttons {
176 | display: flex;
177 | flex-wrap: wrap;
178 | gap: 10px;
179 | margin-bottom: 20px;
180 | }
181 |
182 | .filter-buttons button {
183 | padding: 10px;
184 | border: none;
185 | background-color: #ddd;
186 | cursor: pointer;
187 | border-radius: 5px;
188 | transition: background 0.3s;
189 | }
190 |
191 | .filter-buttons button:hover {
192 | background-color: #ccc;
193 | }
194 |
195 | .filter-buttons button.active {
196 | background-color: #ff6347;
197 | color: white;
198 | }
199 |
200 | /* ---------------------- */
201 | /* Recipe Details Page */
202 | /* ---------------------- */
203 | .recipe-image {
204 | width: 100%;
205 | max-width: 400px;
206 | border-radius: 8px;
207 | margin: 10px 0;
208 | }
209 |
210 | /* ---------------------- */
211 | /* User Profile Page */
212 | /* ---------------------- */
213 | .logoutButton {
214 | background-color: #ff6347;
215 | color: white;
216 | padding: 10px 15px;
217 | border-radius: 8px;
218 | border: none;
219 | cursor: pointer;
220 | margin-bottom: 20px;
221 | }
222 |
223 | ul {
224 | list-style-type: disc;
225 | padding-left: 20px;
226 | }
227 |
228 | /* ---------------------- */
229 | /* Profile Page Styling */
230 | /* ---------------------- */
231 |
232 | .container h2 {
233 | margin-bottom: 20px;
234 | color: #2c2c2c;
235 | font-size: 1.8rem;
236 | }
237 |
238 | .logout-button {
239 | background-color: #555;
240 | padding: 10px 18px;
241 | font-size: 1rem;
242 | border-radius: 8px;
243 | margin-bottom: 25px;
244 | }
245 |
246 | .logout-button:hover {
247 | background-color: #333;
248 | }
249 |
250 | /* Section titles */
251 | .container h3 {
252 | margin-top: 40px;
253 | margin-bottom: 15px;
254 | color: #444;
255 | border-bottom: 2px solid #eee;
256 | padding-bottom: 5px;
257 | }
258 |
259 | /* Recipe Cards */
260 | .recipe-card {
261 | background: white;
262 | padding: 15px;
263 | border-radius: 12px;
264 | box-shadow: 0 4px 10px rgba(0, 0, 0, 0.08);
265 | text-align: center;
266 | transition:
267 | transform 0.4s ease,
268 | box-shadow 0.4s ease,
269 | background 0.4s ease,
270 | border 0.4s ease;
271 | cursor: pointer;
272 | border: 2px solid transparent;
273 | position: relative;
274 | overflow: hidden;
275 | transform-style: preserve-3d;
276 | max-width: 300px;
277 |
278 | }
279 |
280 | .recipe-card:hover {
281 | transform: perspective(1000px) rotateX(3deg) rotateY(-3deg) scale(1.05);
282 | background: linear-gradient(90deg, #ff9e03, #f6ff00);
283 | box-shadow: 0 15px 30px rgba(255, 99, 71, 0.35);
284 | border: 1px solid #ffdd01;
285 | }
286 |
287 |
288 |
289 | .recipe-card img {
290 | width: 100%;
291 | height: 150px;
292 | object-fit: cover;
293 | border-radius: 8px;
294 | margin-bottom: 10px;
295 | }
296 |
297 | /* Button spacing inside cards */
298 | .recipe-card .edit-btn,
299 | .recipe-card .delete-btn {
300 | padding: 8px 16px;
301 | font-size: 0.95rem;
302 | border-radius: 8px;
303 | color: white;
304 | }
305 |
306 |
307 | .recipe-card .edit-btn {
308 | background-color: #007bff;
309 | }
310 |
311 |
312 | .recipe-card .edit-btn:hover {
313 | background-color: #0056b3;
314 | }
315 |
316 | .recipe-card .delete-btn {
317 | background-color: #dc3545;
318 |
319 | }
320 |
321 |
322 | .recipe-card .delete-btn:hover {
323 | background-color: #c82333;
324 | }
325 |
326 | /* "Remove from Favorites" Button */
327 | .recipe-card .remove-fav-btn {
328 | background-color: #aaa;
329 | }
330 |
331 | .recipe-card .remove-fav-btn:hover {
332 | background-color: #888;
333 | }
334 |
335 | /* ---------------------- */
336 | /* Profile Avatar + Layout */
337 | /* ---------------------- */
338 |
339 | .profile-header {
340 | text-align: center;
341 | margin-bottom: 30px;
342 | }
343 |
344 | /* Avatar Combo Animation */
345 | @keyframes bounceGlow {
346 | 0% {
347 | transform: scale(0.7);
348 | opacity: 0;
349 | }
350 | 60% {
351 | transform: scale(1.1);
352 | opacity: 1;
353 | }
354 | 100% {
355 | transform: scale(1);
356 | }
357 | }
358 |
359 | .profile-avatar {
360 | width: 100px;
361 | height: 100px;
362 | border-radius: 50%;
363 | margin-bottom: 10px;
364 | animation: bounceGlow 0.6s ease-out;
365 | transition: transform 0.3s ease, box-shadow 0.3s ease;
366 | }
367 |
368 | .profile-avatar:hover {
369 | transform: scale(1.1);
370 | box-shadow: 0 0 15px rgba(255, 99, 71, 0.5); /* subtle tomato glow */
371 | }
372 |
373 |
374 | /* Section Labels */
375 | .container h3 {
376 | margin-top: 40px;
377 | margin-bottom: 15px;
378 | color: #222;
379 | font-size: 1.3rem;
380 | border-bottom: 2px solid #eee;
381 | padding-bottom: 5px;
382 | }
383 |
384 | /* Logout at Bottom */
385 | .logout-container {
386 | margin-top: 50px;
387 | display: flex;
388 | justify-content: center;
389 | }
390 |
391 | .logout-button {
392 | background-color: #555;
393 | color: white;
394 | padding: 12px 20px;
395 | border: none;
396 | border-radius: 8px;
397 | font-size: 1rem;
398 | cursor: pointer;
399 | transition: background 0.3s ease;
400 | }
401 |
402 | .logout-button:hover {
403 | background-color: #333;
404 | }
405 |
406 | nav a {
407 | position: relative;
408 | padding: 5px;
409 | transition: color 0.3s ease;
410 | }
411 |
412 | nav a::after {
413 | content: "";
414 | position: absolute;
415 | left: 0;
416 | bottom: -3px;
417 | width: 100%;
418 | height: 2px;
419 | background-color: white;
420 | transform: scaleX(0);
421 | transform-origin: right;
422 | transition: transform 0.3s ease;
423 | }
424 |
425 | nav a:hover {
426 | color: #ffd7c1;
427 | }
428 |
429 | nav a:hover::after {
430 | transform: scaleX(1);
431 | transform-origin: left;
432 | }
433 |
434 | .active-link {
435 | font-weight: bold;
436 | color: #ffd7c1; /* soft highlight color */
437 | }
438 |
439 | nav a.active-link::after {
440 | transform: scaleX(1);
441 | transform-origin: left;
442 | }
443 |
444 | /* === HOME PAGE STYLES === */
445 |
446 | .home-container {
447 | padding: 2rem;
448 | max-width: 1200px;
449 | margin: 0 auto;
450 | text-align: center;
451 | }
452 |
453 | .home-hero {
454 | margin-bottom: 3rem;
455 | }
456 |
457 | .home-hero h1 {
458 | font-size: 2.5rem;
459 | color: #ff6347;
460 | margin-bottom: 1rem;
461 | }
462 |
463 | .home-hero p {
464 | font-size: 1.2rem;
465 | color: #333;
466 | }
467 |
468 | .featured-section {
469 | margin-top: 2rem;
470 | }
471 |
472 | .featured-recipes {
473 | display: grid;
474 | grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
475 | gap: 1.5rem;
476 | margin-top: 1rem;
477 | }
478 |
479 | .featured-card {
480 | background-color: #fff;
481 | border: none;
482 | border-radius: 16px;
483 | overflow: hidden;
484 | box-shadow: 0 8px 16px rgba(0, 0, 0, 0.08);
485 | transition: all 0.3s ease;
486 | text-decoration: none;
487 | color: inherit;
488 | }
489 |
490 | .featured-card:hover {
491 | transform: translateY(-5px) scale(1.1);
492 | border: none;
493 | box-shadow: 0px 12px 40px rgb(255, 157, 0);
494 | }
495 |
496 | .featured-card img {
497 | width: 100%;
498 | height: 200px;
499 | object-fit: cover;
500 | border-bottom: 2px solid #eee;
501 | margin-bottom: 10px;
502 | }
503 |
504 | .featured-card h3,
505 | .featured-card p {
506 | padding: 0.8rem 1rem;
507 | text-align: center;
508 | margin-bottom: 8px;
509 | }
510 |
511 |
512 | /* === Recipe Details Page === */
513 | .recipe-details {
514 | max-width: 800px;
515 | margin: 0 auto;
516 | margin-top: 20px;
517 | background-color: #fff;
518 | padding: 30px;
519 | border-radius: 12px;
520 | box-shadow: 0 8px 20px rgba(0, 0, 0, 0.05);
521 | }
522 |
523 | .recipe-details h2 {
524 | font-size: 2rem;
525 | color: #ff6347;
526 | margin-bottom: 10px;
527 | }
528 |
529 | .recipe-details p {
530 | margin-bottom: 10px;
531 | color: #555;
532 | }
533 |
534 | .recipe-details img {
535 | width: 100%;
536 | max-height: 400px;
537 | object-fit: cover;
538 | border-radius: 12px;
539 | margin: 20px auto;
540 | display: block;
541 | }
542 |
543 | /* Ingredients */
544 | /* Only style comment list with bullets */
545 | .recipe-details .comments-section ul {
546 | list-style: disc;
547 | padding-left: 20px;
548 | margin-bottom: 20px;
549 | }
550 |
551 | .recipe-details .comments-section li {
552 | margin-bottom: 8px;
553 | }
554 |
555 |
556 | /* Instructions */
557 | .recipe-details h3 {
558 | margin-top: 30px;
559 | margin-bottom: 10px;
560 | color: #333;
561 | }
562 |
563 | .recipe-details .save-btn {
564 | display: inline-block;
565 | margin-top: 15px;
566 | padding: 10px 16px;
567 | background-color: #ff6347;
568 | border: none;
569 | color: white;
570 | border-radius: 8px;
571 | cursor: pointer;
572 | transition: background 0.3s ease;
573 | }
574 |
575 | .recipe-details .save-btn:hover {
576 | background-color: #e5533d;
577 | }
578 |
579 | /* Comments */
580 | .recipe-details .comments-section {
581 | margin-top: 40px;
582 | }
583 |
584 | .comments-section ul {
585 | margin-top: 10px;
586 | padding-left: 20px;
587 | }
588 |
589 | .comments-section li {
590 | margin-bottom: 10px;
591 | border-bottom: 1px solid #eee;
592 | padding-bottom: 5px;
593 | color: #333;
594 | }
595 |
596 | /* Comment Form */
597 | .recipe-details form {
598 | margin-top: 20px;
599 | display: flex;
600 | flex-direction: column;
601 | }
602 |
603 | .recipe-details textarea {
604 | resize: vertical;
605 | min-height: 80px;
606 | margin-bottom: 10px;
607 | }
608 |
609 | /* === Ingredients as Stylish Pills === */
610 | .ingredient-list {
611 | display: flex;
612 | flex-wrap: wrap;
613 | gap: 10px;
614 | margin-bottom: 25px;
615 | padding: 0;
616 | list-style: none;
617 | }
618 |
619 | .ingredient-pill {
620 | background-color: gold;
621 | color: #333;
622 | padding: 8px 12px;
623 | border-radius: 20px;
624 | font-size: 0.95rem;
625 | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
626 | transition: transform 0.2s ease;
627 | }
628 |
629 | .ingredient-pill:hover {
630 | transform: scale(1.05);
631 | background-color: #ffea09;
632 | }
633 |
634 | .comment-badges {
635 | display: flex;
636 | flex-direction: column;
637 | gap: 12px;
638 | margin-top: 20px;
639 | }
640 |
641 | .comment-badge {
642 | background-color: #fff5ef;
643 | border-left: 5px solid #ff6347;
644 | padding: 12px 16px;
645 | border-radius: 10px;
646 | box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
647 | }
648 |
649 | .comment-user {
650 | font-weight: bold;
651 | color: #ff6347;
652 | margin-right: 5px;
653 | }
654 |
655 | .comment-text {
656 | font-style: none;
657 | color: #444;
658 | }
659 |
660 | /* Search Bar */
661 | .search-bar {
662 | width: 100%;
663 | max-width: 500px;
664 | margin: 0 auto 20px auto;
665 | display: block;
666 | padding: 12px 15px;
667 | font-size: 1rem;
668 | border: 1px solid #ccc;
669 | border-radius: 30px;
670 | box-shadow: 0 2px 6px rgba(0,0,0,0.05);
671 | outline: none;
672 | transition: border-color 0.3s ease;
673 | }
674 |
675 | .search-bar:focus {
676 | border-color: #ff6347;
677 | }
678 |
679 | /* Filter Buttons */
680 | .filter-buttons {
681 | display: flex;
682 | flex-wrap: wrap;
683 | gap: 10px;
684 | justify-content: center;
685 | margin-bottom: 25px;
686 | }
687 |
688 | .filter-buttons button {
689 | background-color: #f5f5f5;
690 | color: #333;
691 | border: none;
692 | padding: 10px 18px;
693 | border-radius: 30px;
694 | font-size: 0.9rem;
695 | cursor: pointer;
696 | transition: all 0.3s ease;
697 | box-shadow: 0 2px 5px rgba(0,0,0,0.05);
698 | }
699 |
700 | .filter-buttons button:hover {
701 | background-color: #ff6347;
702 | color: white;
703 | }
704 |
705 | .filter-buttons .active {
706 | background-color: #ff6347;
707 | color: white;
708 | box-shadow: 0 4px 10px rgba(255, 99, 71, 0.3);
709 | }
710 |
711 | /* Center the heading and search input */
712 | .search-section {
713 | text-align: center;
714 | margin-bottom: 30px;
715 | }
716 |
717 | .search-section h2 {
718 | font-size: 2rem;
719 | margin-bottom: 15px;
720 | color: #ff6347;
721 | }
722 |
723 | .filter-bar {
724 | display: flex;
725 | justify-content: center;
726 | margin-bottom: 20px;
727 | }
728 |
729 | .category-dropdown {
730 | padding: 10px 15px;
731 | border-radius: 25px;
732 | font-size: 1rem;
733 | border: 1px solid #ccc;
734 | background-color: white;
735 | box-shadow: 0 2px 6px rgba(0,0,0,0.05);
736 | cursor: pointer;
737 | transition: border-color 0.3s ease;
738 | }
739 |
740 | .category-dropdown:focus {
741 | border-color: #ff6347;
742 | }
743 |
744 | /* More Recipe Details */
745 | .instructions-block {
746 | background-color: #fff5ef;
747 | padding: 20px;
748 | border-radius: 10px;
749 | line-height: 1.6;
750 | color: #444;
751 | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
752 | margin-bottom: 30px;
753 | white-space: pre-wrap; /* Preserve line breaks if they exist */
754 | }
755 |
756 | .recipe-details form {
757 | background-color: #fff;
758 | padding: 20px;
759 | border-radius: 12px;
760 | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
761 | margin-top: 30px;
762 | }
763 |
764 | .recipe-details form textarea {
765 | border: 1px solid #ccc;
766 | border-radius: 8px;
767 | padding: 12px;
768 | font-size: 1rem;
769 | margin-bottom: 15px;
770 | }
771 |
772 | .recipe-details form button {
773 | width: fit-content;
774 | align-self: flex-end;
775 | }
776 |
777 | .recipe-details .save-btn {
778 | margin: 20px 0;
779 | }
780 |
781 | .center-button {
782 | display: flex;
783 | justify-content: center;
784 | margin: 25px 0;
785 | }
786 |
787 | .recipe-details h2,
788 | .recipe-details p {
789 | text-align: center;
790 | }
791 |
792 | .recipe-details section {
793 | margin-top: 30px;
794 | }
795 |
796 | .recipe-details .save-btn {
797 | display: block;
798 | margin: 20px auto;
799 | background-color: #ff6347;
800 | border: none;
801 | color: white;
802 | padding: 12px 20px;
803 | border-radius: 8px;
804 | cursor: pointer;
805 | transition: transform 0.2s ease, background 0.3s ease;
806 | }
807 |
808 | .recipe-details .save-btn:hover {
809 | transform: scale(1.05);
810 | background-color: #e5533d;
811 | }
812 |
813 | .recipe-details form {
814 | margin: 20px auto 0;
815 | max-width: 600px;
816 | }
817 |
818 | .recipe-details textarea {
819 | padding: 12px;
820 | border-radius: 8px;
821 | border: 1px solid #ccc;
822 | }
823 | .recipe-details button[type="submit"] {
824 | display: block;
825 | margin: 20px auto;
826 | padding: 12px 20px;
827 | background-color: #ff6347;
828 | color: white;
829 | border: none;
830 | border-radius: 8px;
831 | font-size: 1rem;
832 | cursor: pointer;
833 | transition: transform 0.2s ease, background-color 0.3s ease;
834 | }
835 |
836 | .recipe-details button[type="submit"]:hover {
837 | transform: scale(1.05);
838 | background-color: #e5533d;
839 | }
840 |
841 | .success-badge {
842 | text-align: center;
843 | background-color: #d4edda;
844 | color: #155724;
845 | border: 2px solid #c3e6cb;
846 | padding: 10px 15px;
847 | border-radius: 8px;
848 | margin: 15px auto;
849 | width: fit-content;
850 | font-weight: bold;
851 | animation: fadeOut 2s forwards;
852 | }
853 |
854 | @keyframes fadeOut {
855 | 0% {
856 | opacity: 1;
857 | transform: translateY(0);
858 | }
859 | 80% {
860 | opacity: 1;
861 | }
862 | 100% {
863 | opacity: 0;
864 | transform: translateY(-10px);
865 | }
866 | }
867 |
868 | /* === Recipe Form Styling === */
869 | .form-container {
870 | max-width: 600px;
871 | margin: 50px auto;
872 | background-color: white;
873 | padding: 30px 40px;
874 | border-radius: 16px;
875 | box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
876 | }
877 |
878 | .form-container h2 {
879 | text-align: center;
880 | color: #ff6347;
881 | margin-bottom: 25px;
882 | font-size: 2rem;
883 | }
884 |
885 | /* Keep input/textarea styles from earlier, already looks good */
886 |
887 | /* Submit Button */
888 | .form-container button[type="submit"] {
889 | width: 100%;
890 | background-color: #ff6347;
891 | color: white;
892 | padding: 12px;
893 | font-size: 1rem;
894 | border: none;
895 | border-radius: 8px;
896 | cursor: pointer;
897 | transition: background 0.3s ease;
898 | }
899 |
900 | .form-container button[type="submit"]:hover {
901 | background-color: #e5533d;
902 | }
903 |
904 | /* === Auth Form Styling === */
905 | .form-container {
906 | max-width: 400px;
907 | margin: 60px auto;
908 | padding: 30px;
909 | background-color: white;
910 | border-radius: 16px;
911 | box-shadow: 0 10px 24px rgba(0, 0, 0, 0.08);
912 | }
913 |
914 | .form-container h2 {
915 | text-align: center;
916 | color: #ff6347;
917 | margin-bottom: 20px;
918 | font-size: 2rem;
919 | }
920 |
921 | /* Already global input & button styles should cover the rest */
922 |
923 | /* Form Footer */
924 | .form-footer {
925 | text-align: center;
926 | margin-top: 20px;
927 | font-size: 0.95rem;
928 | color: #555;
929 | }
930 |
931 | .form-footer a {
932 | color: #ff6347;
933 | font-weight: bold;
934 | text-decoration: none;
935 | }
936 |
937 | .form-footer a:hover {
938 | text-decoration: underline;
939 | }
940 |
941 | .auth-wrapper {
942 | display: flex;
943 | justify-content: center;
944 | align-items: center;
945 | min-height: calc(100vh - 80px); /* adjust if needed for navbar height */
946 | }
947 |
948 | .featured-card:hover {
949 | transform: perspective(1000px) rotateX(3deg) rotateY(-3deg) scale(1.05);
950 | background: linear-gradient(90deg, #ff9e03, #f6ff00);
951 | box-shadow: 0 15px 30px rgba(255, 99, 71, 0.35);
952 | border: 1px solid #ffdd01;
953 | }
954 |
955 | .fade-in {
956 | animation: fadeIn 0.6s ease-out both;
957 | }
958 |
959 | @keyframes fadeIn {
960 | 0% { opacity: 0; transform: translateY(10px); }
961 | 100% { opacity: 1; transform: translateY(0); }
962 | }
963 |
964 |
965 | .app-footer {
966 | text-align: center;
967 | padding: 20px 10px;
968 | background-color: #fe681c;
969 | color: white;
970 | font-size: 0.95rem;
971 | margin-top: 40px;
972 | border-top: 1px solid #eee;
973 | }
974 |
975 | html, body, #root {
976 | height: 100%;
977 | }
978 |
979 | .app-wrapper {
980 | display: flex;
981 | flex-direction: column;
982 | min-height: 100vh;
983 | }
984 |
985 | .app-wrapper > main {
986 | flex: 1;
987 | }
988 |
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 |
4 | // https://vite.dev/config/
5 | export default defineConfig({
6 | plugins: [react()],
7 | })
8 |
--------------------------------------------------------------------------------