├── .env ├── .gitignore ├── README.md ├── eslint.config.js ├── index.html ├── package-lock.json ├── package.json ├── script.md ├── src ├── App.tsx ├── fileManager │ ├── components │ │ ├── FileManager.tsx │ │ ├── FileQuickActions.tsx │ │ ├── FileThumbnail.tsx │ │ ├── FilesDataGrid.tsx │ │ └── UploadProgressCard.tsx │ ├── hooks │ │ ├── useFileDeleteMutation.ts │ │ ├── useFileManagerStore.ts │ │ ├── useFileUploadMutation.ts │ │ └── useFilesQuery.ts │ └── types │ │ ├── ExtendedFile.ts │ │ └── FileDataGridRow.ts ├── main.tsx ├── shared │ ├── confirm │ │ ├── components │ │ │ └── ConfirmProvider.tsx │ │ └── hooks │ │ │ └── useConfirm.ts │ ├── httpClient.ts │ ├── theme.ts │ ├── ui │ │ ├── BulkActions.tsx │ │ ├── ThemeToggle.tsx │ │ └── Topbar.tsx │ └── utils.ts └── vite-env.d.ts ├── tsconfig.app.json ├── tsconfig.app.tsbuildinfo ├── tsconfig.json ├── tsconfig.node.json ├── tsconfig.node.tsbuildinfo └── vite.config.ts /.env: -------------------------------------------------------------------------------- 1 | VITE_API_URL=http://localhost:3000 -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # File Manager Frontend Tutorial 2 | 3 | This is a simple React project powered by Vite 5. 4 | 5 | ## Requirements 6 | 7 | - Node.js (version 18 or higher) 8 | - npm (Node Package Manager) 9 | 10 | ## Setup 11 | 12 | 1. Clone the repository to your local machine. 13 | 2. Install the dependencies using npm: 14 | 15 | ```bash 16 | npm install 17 | ``` 18 | 19 | ## Running the Project 20 | 21 | To start the development server, run the following command: 22 | 23 | ```bash 24 | npm run dev 25 | ``` 26 | 27 | The server will start and your project will be available at the specified port (default: **localhost:5173**). 28 | -------------------------------------------------------------------------------- /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 | import tseslint from 'typescript-eslint' 6 | 7 | export default tseslint.config( 8 | { ignores: ['dist'] }, 9 | { 10 | extends: [js.configs.recommended, ...tseslint.configs.recommended], 11 | files: ['**/*.{ts,tsx}'], 12 | languageOptions: { 13 | ecmaVersion: 2020, 14 | globals: globals.browser, 15 | }, 16 | plugins: { 17 | 'react-hooks': reactHooks, 18 | 'react-refresh': reactRefresh, 19 | }, 20 | rules: { 21 | ...reactHooks.configs.recommended.rules, 22 | 'react-refresh/only-export-components': [ 23 | 'warn', 24 | { allowConstantExport: true }, 25 | ], 26 | }, 27 | }, 28 | ) 29 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | File manager 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "version": "0.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "frontend", 9 | "version": "0.0.0", 10 | "dependencies": { 11 | "@emotion/react": "^11.13.3", 12 | "@emotion/styled": "^11.13.0", 13 | "@formkit/auto-animate": "^0.8.2", 14 | "@mui/icons-material": "^6.1.1", 15 | "@mui/lab": "^6.0.0-beta.10", 16 | "@mui/material": "^6.1.1", 17 | "@mui/x-data-grid": "^7.18.0", 18 | "@tanstack/react-query": "^5.56.2", 19 | "axios": "^1.7.7", 20 | "react": "^18.3.1", 21 | "react-dom": "^18.3.1", 22 | "react-dropzone": "^14.2.3", 23 | "zustand": "^5.0.0-rc.2" 24 | }, 25 | "devDependencies": { 26 | "@eslint/js": "^9.9.0", 27 | "@types/node": "^22.7.3", 28 | "@types/react": "^18.3.3", 29 | "@types/react-dom": "^18.3.0", 30 | "@vitejs/plugin-react-swc": "^3.5.0", 31 | "eslint": "^9.9.0", 32 | "eslint-plugin-react-hooks": "^5.1.0-rc.0", 33 | "eslint-plugin-react-refresh": "^0.4.9", 34 | "globals": "^15.9.0", 35 | "path": "^0.12.7", 36 | "typescript": "^5.5.3", 37 | "typescript-eslint": "^8.0.1", 38 | "vite": "^5.4.1" 39 | } 40 | }, 41 | "node_modules/@babel/code-frame": { 42 | "version": "7.24.7", 43 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", 44 | "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", 45 | "dependencies": { 46 | "@babel/highlight": "^7.24.7", 47 | "picocolors": "^1.0.0" 48 | }, 49 | "engines": { 50 | "node": ">=6.9.0" 51 | } 52 | }, 53 | "node_modules/@babel/generator": { 54 | "version": "7.25.6", 55 | "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", 56 | "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", 57 | "dependencies": { 58 | "@babel/types": "^7.25.6", 59 | "@jridgewell/gen-mapping": "^0.3.5", 60 | "@jridgewell/trace-mapping": "^0.3.25", 61 | "jsesc": "^2.5.1" 62 | }, 63 | "engines": { 64 | "node": ">=6.9.0" 65 | } 66 | }, 67 | "node_modules/@babel/helper-module-imports": { 68 | "version": "7.24.7", 69 | "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", 70 | "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", 71 | "dependencies": { 72 | "@babel/traverse": "^7.24.7", 73 | "@babel/types": "^7.24.7" 74 | }, 75 | "engines": { 76 | "node": ">=6.9.0" 77 | } 78 | }, 79 | "node_modules/@babel/helper-string-parser": { 80 | "version": "7.24.8", 81 | "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", 82 | "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", 83 | "engines": { 84 | "node": ">=6.9.0" 85 | } 86 | }, 87 | "node_modules/@babel/helper-validator-identifier": { 88 | "version": "7.24.7", 89 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", 90 | "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", 91 | "engines": { 92 | "node": ">=6.9.0" 93 | } 94 | }, 95 | "node_modules/@babel/highlight": { 96 | "version": "7.24.7", 97 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", 98 | "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", 99 | "dependencies": { 100 | "@babel/helper-validator-identifier": "^7.24.7", 101 | "chalk": "^2.4.2", 102 | "js-tokens": "^4.0.0", 103 | "picocolors": "^1.0.0" 104 | }, 105 | "engines": { 106 | "node": ">=6.9.0" 107 | } 108 | }, 109 | "node_modules/@babel/parser": { 110 | "version": "7.25.6", 111 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", 112 | "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", 113 | "dependencies": { 114 | "@babel/types": "^7.25.6" 115 | }, 116 | "bin": { 117 | "parser": "bin/babel-parser.js" 118 | }, 119 | "engines": { 120 | "node": ">=6.0.0" 121 | } 122 | }, 123 | "node_modules/@babel/runtime": { 124 | "version": "7.25.6", 125 | "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", 126 | "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", 127 | "dependencies": { 128 | "regenerator-runtime": "^0.14.0" 129 | }, 130 | "engines": { 131 | "node": ">=6.9.0" 132 | } 133 | }, 134 | "node_modules/@babel/template": { 135 | "version": "7.25.0", 136 | "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", 137 | "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", 138 | "dependencies": { 139 | "@babel/code-frame": "^7.24.7", 140 | "@babel/parser": "^7.25.0", 141 | "@babel/types": "^7.25.0" 142 | }, 143 | "engines": { 144 | "node": ">=6.9.0" 145 | } 146 | }, 147 | "node_modules/@babel/traverse": { 148 | "version": "7.25.6", 149 | "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", 150 | "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", 151 | "dependencies": { 152 | "@babel/code-frame": "^7.24.7", 153 | "@babel/generator": "^7.25.6", 154 | "@babel/parser": "^7.25.6", 155 | "@babel/template": "^7.25.0", 156 | "@babel/types": "^7.25.6", 157 | "debug": "^4.3.1", 158 | "globals": "^11.1.0" 159 | }, 160 | "engines": { 161 | "node": ">=6.9.0" 162 | } 163 | }, 164 | "node_modules/@babel/traverse/node_modules/globals": { 165 | "version": "11.12.0", 166 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", 167 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", 168 | "engines": { 169 | "node": ">=4" 170 | } 171 | }, 172 | "node_modules/@babel/types": { 173 | "version": "7.25.6", 174 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", 175 | "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", 176 | "dependencies": { 177 | "@babel/helper-string-parser": "^7.24.8", 178 | "@babel/helper-validator-identifier": "^7.24.7", 179 | "to-fast-properties": "^2.0.0" 180 | }, 181 | "engines": { 182 | "node": ">=6.9.0" 183 | } 184 | }, 185 | "node_modules/@emotion/babel-plugin": { 186 | "version": "11.12.0", 187 | "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz", 188 | "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==", 189 | "dependencies": { 190 | "@babel/helper-module-imports": "^7.16.7", 191 | "@babel/runtime": "^7.18.3", 192 | "@emotion/hash": "^0.9.2", 193 | "@emotion/memoize": "^0.9.0", 194 | "@emotion/serialize": "^1.2.0", 195 | "babel-plugin-macros": "^3.1.0", 196 | "convert-source-map": "^1.5.0", 197 | "escape-string-regexp": "^4.0.0", 198 | "find-root": "^1.1.0", 199 | "source-map": "^0.5.7", 200 | "stylis": "4.2.0" 201 | } 202 | }, 203 | "node_modules/@emotion/cache": { 204 | "version": "11.13.1", 205 | "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.1.tgz", 206 | "integrity": "sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==", 207 | "dependencies": { 208 | "@emotion/memoize": "^0.9.0", 209 | "@emotion/sheet": "^1.4.0", 210 | "@emotion/utils": "^1.4.0", 211 | "@emotion/weak-memoize": "^0.4.0", 212 | "stylis": "4.2.0" 213 | } 214 | }, 215 | "node_modules/@emotion/hash": { 216 | "version": "0.9.2", 217 | "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", 218 | "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==" 219 | }, 220 | "node_modules/@emotion/is-prop-valid": { 221 | "version": "1.3.1", 222 | "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz", 223 | "integrity": "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==", 224 | "dependencies": { 225 | "@emotion/memoize": "^0.9.0" 226 | } 227 | }, 228 | "node_modules/@emotion/memoize": { 229 | "version": "0.9.0", 230 | "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", 231 | "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" 232 | }, 233 | "node_modules/@emotion/react": { 234 | "version": "11.13.3", 235 | "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.3.tgz", 236 | "integrity": "sha512-lIsdU6JNrmYfJ5EbUCf4xW1ovy5wKQ2CkPRM4xogziOxH1nXxBSjpC9YqbFAP7circxMfYp+6x676BqWcEiixg==", 237 | "dependencies": { 238 | "@babel/runtime": "^7.18.3", 239 | "@emotion/babel-plugin": "^11.12.0", 240 | "@emotion/cache": "^11.13.0", 241 | "@emotion/serialize": "^1.3.1", 242 | "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", 243 | "@emotion/utils": "^1.4.0", 244 | "@emotion/weak-memoize": "^0.4.0", 245 | "hoist-non-react-statics": "^3.3.1" 246 | }, 247 | "peerDependencies": { 248 | "react": ">=16.8.0" 249 | }, 250 | "peerDependenciesMeta": { 251 | "@types/react": { 252 | "optional": true 253 | } 254 | } 255 | }, 256 | "node_modules/@emotion/serialize": { 257 | "version": "1.3.2", 258 | "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.2.tgz", 259 | "integrity": "sha512-grVnMvVPK9yUVE6rkKfAJlYZgo0cu3l9iMC77V7DW6E1DUIrU68pSEXRmFZFOFB1QFo57TncmOcvcbMDWsL4yA==", 260 | "dependencies": { 261 | "@emotion/hash": "^0.9.2", 262 | "@emotion/memoize": "^0.9.0", 263 | "@emotion/unitless": "^0.10.0", 264 | "@emotion/utils": "^1.4.1", 265 | "csstype": "^3.0.2" 266 | } 267 | }, 268 | "node_modules/@emotion/sheet": { 269 | "version": "1.4.0", 270 | "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", 271 | "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==" 272 | }, 273 | "node_modules/@emotion/styled": { 274 | "version": "11.13.0", 275 | "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.13.0.tgz", 276 | "integrity": "sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==", 277 | "dependencies": { 278 | "@babel/runtime": "^7.18.3", 279 | "@emotion/babel-plugin": "^11.12.0", 280 | "@emotion/is-prop-valid": "^1.3.0", 281 | "@emotion/serialize": "^1.3.0", 282 | "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", 283 | "@emotion/utils": "^1.4.0" 284 | }, 285 | "peerDependencies": { 286 | "@emotion/react": "^11.0.0-rc.0", 287 | "react": ">=16.8.0" 288 | }, 289 | "peerDependenciesMeta": { 290 | "@types/react": { 291 | "optional": true 292 | } 293 | } 294 | }, 295 | "node_modules/@emotion/unitless": { 296 | "version": "0.10.0", 297 | "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", 298 | "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==" 299 | }, 300 | "node_modules/@emotion/use-insertion-effect-with-fallbacks": { 301 | "version": "1.1.0", 302 | "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz", 303 | "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==", 304 | "peerDependencies": { 305 | "react": ">=16.8.0" 306 | } 307 | }, 308 | "node_modules/@emotion/utils": { 309 | "version": "1.4.1", 310 | "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.1.tgz", 311 | "integrity": "sha512-BymCXzCG3r72VKJxaYVwOXATqXIZ85cuvg0YOUDxMGNrKc1DJRZk8MgV5wyXRyEayIMd4FuXJIUgTBXvDNW5cA==" 312 | }, 313 | "node_modules/@emotion/weak-memoize": { 314 | "version": "0.4.0", 315 | "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", 316 | "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==" 317 | }, 318 | "node_modules/@esbuild/aix-ppc64": { 319 | "version": "0.21.5", 320 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", 321 | "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", 322 | "cpu": [ 323 | "ppc64" 324 | ], 325 | "dev": true, 326 | "optional": true, 327 | "os": [ 328 | "aix" 329 | ], 330 | "engines": { 331 | "node": ">=12" 332 | } 333 | }, 334 | "node_modules/@esbuild/android-arm": { 335 | "version": "0.21.5", 336 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", 337 | "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", 338 | "cpu": [ 339 | "arm" 340 | ], 341 | "dev": true, 342 | "optional": true, 343 | "os": [ 344 | "android" 345 | ], 346 | "engines": { 347 | "node": ">=12" 348 | } 349 | }, 350 | "node_modules/@esbuild/android-arm64": { 351 | "version": "0.21.5", 352 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", 353 | "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", 354 | "cpu": [ 355 | "arm64" 356 | ], 357 | "dev": true, 358 | "optional": true, 359 | "os": [ 360 | "android" 361 | ], 362 | "engines": { 363 | "node": ">=12" 364 | } 365 | }, 366 | "node_modules/@esbuild/android-x64": { 367 | "version": "0.21.5", 368 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", 369 | "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", 370 | "cpu": [ 371 | "x64" 372 | ], 373 | "dev": true, 374 | "optional": true, 375 | "os": [ 376 | "android" 377 | ], 378 | "engines": { 379 | "node": ">=12" 380 | } 381 | }, 382 | "node_modules/@esbuild/darwin-arm64": { 383 | "version": "0.21.5", 384 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", 385 | "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", 386 | "cpu": [ 387 | "arm64" 388 | ], 389 | "dev": true, 390 | "optional": true, 391 | "os": [ 392 | "darwin" 393 | ], 394 | "engines": { 395 | "node": ">=12" 396 | } 397 | }, 398 | "node_modules/@esbuild/darwin-x64": { 399 | "version": "0.21.5", 400 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", 401 | "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", 402 | "cpu": [ 403 | "x64" 404 | ], 405 | "dev": true, 406 | "optional": true, 407 | "os": [ 408 | "darwin" 409 | ], 410 | "engines": { 411 | "node": ">=12" 412 | } 413 | }, 414 | "node_modules/@esbuild/freebsd-arm64": { 415 | "version": "0.21.5", 416 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", 417 | "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", 418 | "cpu": [ 419 | "arm64" 420 | ], 421 | "dev": true, 422 | "optional": true, 423 | "os": [ 424 | "freebsd" 425 | ], 426 | "engines": { 427 | "node": ">=12" 428 | } 429 | }, 430 | "node_modules/@esbuild/freebsd-x64": { 431 | "version": "0.21.5", 432 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", 433 | "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", 434 | "cpu": [ 435 | "x64" 436 | ], 437 | "dev": true, 438 | "optional": true, 439 | "os": [ 440 | "freebsd" 441 | ], 442 | "engines": { 443 | "node": ">=12" 444 | } 445 | }, 446 | "node_modules/@esbuild/linux-arm": { 447 | "version": "0.21.5", 448 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", 449 | "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", 450 | "cpu": [ 451 | "arm" 452 | ], 453 | "dev": true, 454 | "optional": true, 455 | "os": [ 456 | "linux" 457 | ], 458 | "engines": { 459 | "node": ">=12" 460 | } 461 | }, 462 | "node_modules/@esbuild/linux-arm64": { 463 | "version": "0.21.5", 464 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", 465 | "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", 466 | "cpu": [ 467 | "arm64" 468 | ], 469 | "dev": true, 470 | "optional": true, 471 | "os": [ 472 | "linux" 473 | ], 474 | "engines": { 475 | "node": ">=12" 476 | } 477 | }, 478 | "node_modules/@esbuild/linux-ia32": { 479 | "version": "0.21.5", 480 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", 481 | "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", 482 | "cpu": [ 483 | "ia32" 484 | ], 485 | "dev": true, 486 | "optional": true, 487 | "os": [ 488 | "linux" 489 | ], 490 | "engines": { 491 | "node": ">=12" 492 | } 493 | }, 494 | "node_modules/@esbuild/linux-loong64": { 495 | "version": "0.21.5", 496 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", 497 | "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", 498 | "cpu": [ 499 | "loong64" 500 | ], 501 | "dev": true, 502 | "optional": true, 503 | "os": [ 504 | "linux" 505 | ], 506 | "engines": { 507 | "node": ">=12" 508 | } 509 | }, 510 | "node_modules/@esbuild/linux-mips64el": { 511 | "version": "0.21.5", 512 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", 513 | "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", 514 | "cpu": [ 515 | "mips64el" 516 | ], 517 | "dev": true, 518 | "optional": true, 519 | "os": [ 520 | "linux" 521 | ], 522 | "engines": { 523 | "node": ">=12" 524 | } 525 | }, 526 | "node_modules/@esbuild/linux-ppc64": { 527 | "version": "0.21.5", 528 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", 529 | "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", 530 | "cpu": [ 531 | "ppc64" 532 | ], 533 | "dev": true, 534 | "optional": true, 535 | "os": [ 536 | "linux" 537 | ], 538 | "engines": { 539 | "node": ">=12" 540 | } 541 | }, 542 | "node_modules/@esbuild/linux-riscv64": { 543 | "version": "0.21.5", 544 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", 545 | "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", 546 | "cpu": [ 547 | "riscv64" 548 | ], 549 | "dev": true, 550 | "optional": true, 551 | "os": [ 552 | "linux" 553 | ], 554 | "engines": { 555 | "node": ">=12" 556 | } 557 | }, 558 | "node_modules/@esbuild/linux-s390x": { 559 | "version": "0.21.5", 560 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", 561 | "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", 562 | "cpu": [ 563 | "s390x" 564 | ], 565 | "dev": true, 566 | "optional": true, 567 | "os": [ 568 | "linux" 569 | ], 570 | "engines": { 571 | "node": ">=12" 572 | } 573 | }, 574 | "node_modules/@esbuild/linux-x64": { 575 | "version": "0.21.5", 576 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", 577 | "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", 578 | "cpu": [ 579 | "x64" 580 | ], 581 | "dev": true, 582 | "optional": true, 583 | "os": [ 584 | "linux" 585 | ], 586 | "engines": { 587 | "node": ">=12" 588 | } 589 | }, 590 | "node_modules/@esbuild/netbsd-x64": { 591 | "version": "0.21.5", 592 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", 593 | "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", 594 | "cpu": [ 595 | "x64" 596 | ], 597 | "dev": true, 598 | "optional": true, 599 | "os": [ 600 | "netbsd" 601 | ], 602 | "engines": { 603 | "node": ">=12" 604 | } 605 | }, 606 | "node_modules/@esbuild/openbsd-x64": { 607 | "version": "0.21.5", 608 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", 609 | "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", 610 | "cpu": [ 611 | "x64" 612 | ], 613 | "dev": true, 614 | "optional": true, 615 | "os": [ 616 | "openbsd" 617 | ], 618 | "engines": { 619 | "node": ">=12" 620 | } 621 | }, 622 | "node_modules/@esbuild/sunos-x64": { 623 | "version": "0.21.5", 624 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", 625 | "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", 626 | "cpu": [ 627 | "x64" 628 | ], 629 | "dev": true, 630 | "optional": true, 631 | "os": [ 632 | "sunos" 633 | ], 634 | "engines": { 635 | "node": ">=12" 636 | } 637 | }, 638 | "node_modules/@esbuild/win32-arm64": { 639 | "version": "0.21.5", 640 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", 641 | "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", 642 | "cpu": [ 643 | "arm64" 644 | ], 645 | "dev": true, 646 | "optional": true, 647 | "os": [ 648 | "win32" 649 | ], 650 | "engines": { 651 | "node": ">=12" 652 | } 653 | }, 654 | "node_modules/@esbuild/win32-ia32": { 655 | "version": "0.21.5", 656 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", 657 | "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", 658 | "cpu": [ 659 | "ia32" 660 | ], 661 | "dev": true, 662 | "optional": true, 663 | "os": [ 664 | "win32" 665 | ], 666 | "engines": { 667 | "node": ">=12" 668 | } 669 | }, 670 | "node_modules/@esbuild/win32-x64": { 671 | "version": "0.21.5", 672 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", 673 | "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", 674 | "cpu": [ 675 | "x64" 676 | ], 677 | "dev": true, 678 | "optional": true, 679 | "os": [ 680 | "win32" 681 | ], 682 | "engines": { 683 | "node": ">=12" 684 | } 685 | }, 686 | "node_modules/@eslint-community/eslint-utils": { 687 | "version": "4.4.0", 688 | "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", 689 | "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", 690 | "dev": true, 691 | "dependencies": { 692 | "eslint-visitor-keys": "^3.3.0" 693 | }, 694 | "engines": { 695 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 696 | }, 697 | "peerDependencies": { 698 | "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" 699 | } 700 | }, 701 | "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { 702 | "version": "3.4.3", 703 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", 704 | "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", 705 | "dev": true, 706 | "engines": { 707 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 708 | }, 709 | "funding": { 710 | "url": "https://opencollective.com/eslint" 711 | } 712 | }, 713 | "node_modules/@eslint-community/regexpp": { 714 | "version": "4.11.1", 715 | "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", 716 | "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", 717 | "dev": true, 718 | "engines": { 719 | "node": "^12.0.0 || ^14.0.0 || >=16.0.0" 720 | } 721 | }, 722 | "node_modules/@eslint/config-array": { 723 | "version": "0.18.0", 724 | "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", 725 | "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", 726 | "dev": true, 727 | "dependencies": { 728 | "@eslint/object-schema": "^2.1.4", 729 | "debug": "^4.3.1", 730 | "minimatch": "^3.1.2" 731 | }, 732 | "engines": { 733 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 734 | } 735 | }, 736 | "node_modules/@eslint/core": { 737 | "version": "0.6.0", 738 | "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.6.0.tgz", 739 | "integrity": "sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg==", 740 | "dev": true, 741 | "engines": { 742 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 743 | } 744 | }, 745 | "node_modules/@eslint/eslintrc": { 746 | "version": "3.1.0", 747 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", 748 | "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", 749 | "dev": true, 750 | "dependencies": { 751 | "ajv": "^6.12.4", 752 | "debug": "^4.3.2", 753 | "espree": "^10.0.1", 754 | "globals": "^14.0.0", 755 | "ignore": "^5.2.0", 756 | "import-fresh": "^3.2.1", 757 | "js-yaml": "^4.1.0", 758 | "minimatch": "^3.1.2", 759 | "strip-json-comments": "^3.1.1" 760 | }, 761 | "engines": { 762 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 763 | }, 764 | "funding": { 765 | "url": "https://opencollective.com/eslint" 766 | } 767 | }, 768 | "node_modules/@eslint/eslintrc/node_modules/globals": { 769 | "version": "14.0.0", 770 | "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", 771 | "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", 772 | "dev": true, 773 | "engines": { 774 | "node": ">=18" 775 | }, 776 | "funding": { 777 | "url": "https://github.com/sponsors/sindresorhus" 778 | } 779 | }, 780 | "node_modules/@eslint/js": { 781 | "version": "9.11.1", 782 | "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.11.1.tgz", 783 | "integrity": "sha512-/qu+TWz8WwPWc7/HcIJKi+c+MOm46GdVaSlTTQcaqaL53+GsoA6MxWp5PtTx48qbSP7ylM1Kn7nhvkugfJvRSA==", 784 | "dev": true, 785 | "engines": { 786 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 787 | } 788 | }, 789 | "node_modules/@eslint/object-schema": { 790 | "version": "2.1.4", 791 | "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", 792 | "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", 793 | "dev": true, 794 | "engines": { 795 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 796 | } 797 | }, 798 | "node_modules/@eslint/plugin-kit": { 799 | "version": "0.2.0", 800 | "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz", 801 | "integrity": "sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==", 802 | "dev": true, 803 | "dependencies": { 804 | "levn": "^0.4.1" 805 | }, 806 | "engines": { 807 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 808 | } 809 | }, 810 | "node_modules/@floating-ui/core": { 811 | "version": "1.6.8", 812 | "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.8.tgz", 813 | "integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==", 814 | "dependencies": { 815 | "@floating-ui/utils": "^0.2.8" 816 | } 817 | }, 818 | "node_modules/@floating-ui/dom": { 819 | "version": "1.6.11", 820 | "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.11.tgz", 821 | "integrity": "sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ==", 822 | "dependencies": { 823 | "@floating-ui/core": "^1.6.0", 824 | "@floating-ui/utils": "^0.2.8" 825 | } 826 | }, 827 | "node_modules/@floating-ui/react-dom": { 828 | "version": "2.1.2", 829 | "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.2.tgz", 830 | "integrity": "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==", 831 | "dependencies": { 832 | "@floating-ui/dom": "^1.0.0" 833 | }, 834 | "peerDependencies": { 835 | "react": ">=16.8.0", 836 | "react-dom": ">=16.8.0" 837 | } 838 | }, 839 | "node_modules/@floating-ui/utils": { 840 | "version": "0.2.8", 841 | "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz", 842 | "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==" 843 | }, 844 | "node_modules/@formkit/auto-animate": { 845 | "version": "0.8.2", 846 | "resolved": "https://registry.npmjs.org/@formkit/auto-animate/-/auto-animate-0.8.2.tgz", 847 | "integrity": "sha512-SwPWfeRa5veb1hOIBMdzI+73te5puUBHmqqaF1Bu7FjvxlYSz/kJcZKSa9Cg60zL0uRNeJL2SbRxV6Jp6Q1nFQ==" 848 | }, 849 | "node_modules/@humanwhocodes/module-importer": { 850 | "version": "1.0.1", 851 | "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", 852 | "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", 853 | "dev": true, 854 | "engines": { 855 | "node": ">=12.22" 856 | }, 857 | "funding": { 858 | "type": "github", 859 | "url": "https://github.com/sponsors/nzakas" 860 | } 861 | }, 862 | "node_modules/@humanwhocodes/retry": { 863 | "version": "0.3.0", 864 | "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", 865 | "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", 866 | "dev": true, 867 | "engines": { 868 | "node": ">=18.18" 869 | }, 870 | "funding": { 871 | "type": "github", 872 | "url": "https://github.com/sponsors/nzakas" 873 | } 874 | }, 875 | "node_modules/@jridgewell/gen-mapping": { 876 | "version": "0.3.5", 877 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", 878 | "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", 879 | "dependencies": { 880 | "@jridgewell/set-array": "^1.2.1", 881 | "@jridgewell/sourcemap-codec": "^1.4.10", 882 | "@jridgewell/trace-mapping": "^0.3.24" 883 | }, 884 | "engines": { 885 | "node": ">=6.0.0" 886 | } 887 | }, 888 | "node_modules/@jridgewell/resolve-uri": { 889 | "version": "3.1.2", 890 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", 891 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", 892 | "engines": { 893 | "node": ">=6.0.0" 894 | } 895 | }, 896 | "node_modules/@jridgewell/set-array": { 897 | "version": "1.2.1", 898 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", 899 | "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", 900 | "engines": { 901 | "node": ">=6.0.0" 902 | } 903 | }, 904 | "node_modules/@jridgewell/sourcemap-codec": { 905 | "version": "1.5.0", 906 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", 907 | "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" 908 | }, 909 | "node_modules/@jridgewell/trace-mapping": { 910 | "version": "0.3.25", 911 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", 912 | "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", 913 | "dependencies": { 914 | "@jridgewell/resolve-uri": "^3.1.0", 915 | "@jridgewell/sourcemap-codec": "^1.4.14" 916 | } 917 | }, 918 | "node_modules/@mui/base": { 919 | "version": "5.0.0-beta.58", 920 | "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.58.tgz", 921 | "integrity": "sha512-P0E7ZrxOuyYqBvVv9w8k7wm+Xzx/KRu+BGgFcR2htTsGCpJNQJCSUXNUZ50MUmSU9hzqhwbQWNXhV1MBTl6F7A==", 922 | "dependencies": { 923 | "@babel/runtime": "^7.25.0", 924 | "@floating-ui/react-dom": "^2.1.1", 925 | "@mui/types": "^7.2.15", 926 | "@mui/utils": "6.0.0-rc.0", 927 | "@popperjs/core": "^2.11.8", 928 | "clsx": "^2.1.1", 929 | "prop-types": "^15.8.1" 930 | }, 931 | "engines": { 932 | "node": ">=14.0.0" 933 | }, 934 | "funding": { 935 | "type": "opencollective", 936 | "url": "https://opencollective.com/mui-org" 937 | }, 938 | "peerDependencies": { 939 | "@types/react": "^17.0.0 || ^18.0.0", 940 | "react": "^17.0.0 || ^18.0.0", 941 | "react-dom": "^17.0.0 || ^18.0.0" 942 | }, 943 | "peerDependenciesMeta": { 944 | "@types/react": { 945 | "optional": true 946 | } 947 | } 948 | }, 949 | "node_modules/@mui/base/node_modules/@mui/utils": { 950 | "version": "6.0.0-rc.0", 951 | "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.0.0-rc.0.tgz", 952 | "integrity": "sha512-tBp0ILEXDL0bbDDT8PnZOjCqSm5Dfk2N0Z45uzRw+wVl6fVvloC9zw8avl+OdX1Bg3ubs/ttKn8nRNv17bpM5A==", 953 | "dependencies": { 954 | "@babel/runtime": "^7.25.0", 955 | "@mui/types": "^7.2.15", 956 | "@types/prop-types": "^15.7.12", 957 | "clsx": "^2.1.1", 958 | "prop-types": "^15.8.1", 959 | "react-is": "^18.3.1" 960 | }, 961 | "engines": { 962 | "node": ">=14.0.0" 963 | }, 964 | "funding": { 965 | "type": "opencollective", 966 | "url": "https://opencollective.com/mui-org" 967 | }, 968 | "peerDependencies": { 969 | "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", 970 | "react": "^17.0.0 || ^18.0.0 || ^19.0.0" 971 | }, 972 | "peerDependenciesMeta": { 973 | "@types/react": { 974 | "optional": true 975 | } 976 | } 977 | }, 978 | "node_modules/@mui/core-downloads-tracker": { 979 | "version": "6.1.1", 980 | "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.1.1.tgz", 981 | "integrity": "sha512-VdQC1tPIIcZAnf62L2M1eQif0x2vlKg3YK4kGYbtijSH4niEgI21GnstykW1vQIs+Bc6L+Hua2GATYVjilJ22A==", 982 | "funding": { 983 | "type": "opencollective", 984 | "url": "https://opencollective.com/mui-org" 985 | } 986 | }, 987 | "node_modules/@mui/icons-material": { 988 | "version": "6.1.1", 989 | "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.1.1.tgz", 990 | "integrity": "sha512-sy/YKwcLPW8VcacNP2uWMYR9xyWuwO9NN9FXuGEU90bRshBXj8pdKk+joe3TCW7oviVS3zXLHlc94wQ0jNsQRQ==", 991 | "dependencies": { 992 | "@babel/runtime": "^7.25.6" 993 | }, 994 | "engines": { 995 | "node": ">=14.0.0" 996 | }, 997 | "funding": { 998 | "type": "opencollective", 999 | "url": "https://opencollective.com/mui-org" 1000 | }, 1001 | "peerDependencies": { 1002 | "@mui/material": "^6.1.1", 1003 | "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", 1004 | "react": "^17.0.0 || ^18.0.0 || ^19.0.0" 1005 | }, 1006 | "peerDependenciesMeta": { 1007 | "@types/react": { 1008 | "optional": true 1009 | } 1010 | } 1011 | }, 1012 | "node_modules/@mui/lab": { 1013 | "version": "6.0.0-beta.10", 1014 | "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-6.0.0-beta.10.tgz", 1015 | "integrity": "sha512-eqCBz5SZS8Un9To3UcjH01AxkOOgvme/g0ZstFC8Nz1Kg5/EJMA0ByhKS5AvUMzUKrv0FXMdbuPqbBvF3bVrXg==", 1016 | "dependencies": { 1017 | "@babel/runtime": "^7.25.6", 1018 | "@mui/base": "5.0.0-beta.58", 1019 | "@mui/system": "^6.1.1", 1020 | "@mui/types": "^7.2.17", 1021 | "@mui/utils": "^6.1.1", 1022 | "clsx": "^2.1.1", 1023 | "prop-types": "^15.8.1" 1024 | }, 1025 | "engines": { 1026 | "node": ">=14.0.0" 1027 | }, 1028 | "funding": { 1029 | "type": "opencollective", 1030 | "url": "https://opencollective.com/mui-org" 1031 | }, 1032 | "peerDependencies": { 1033 | "@emotion/react": "^11.5.0", 1034 | "@emotion/styled": "^11.3.0", 1035 | "@mui/material": "^6.1.1", 1036 | "@mui/material-pigment-css": "^6.1.1", 1037 | "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", 1038 | "react": "^17.0.0 || ^18.0.0 || ^19.0.0", 1039 | "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" 1040 | }, 1041 | "peerDependenciesMeta": { 1042 | "@emotion/react": { 1043 | "optional": true 1044 | }, 1045 | "@emotion/styled": { 1046 | "optional": true 1047 | }, 1048 | "@mui/material-pigment-css": { 1049 | "optional": true 1050 | }, 1051 | "@types/react": { 1052 | "optional": true 1053 | } 1054 | } 1055 | }, 1056 | "node_modules/@mui/material": { 1057 | "version": "6.1.1", 1058 | "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.1.1.tgz", 1059 | "integrity": "sha512-b+eULldTqtqTCbN++2BtBWCir/1LwEYw+2mIlOt2GiEUh1EBBw4/wIukGKKNt3xrCZqRA80yLLkV6tF61Lq3cA==", 1060 | "dependencies": { 1061 | "@babel/runtime": "^7.25.6", 1062 | "@mui/core-downloads-tracker": "^6.1.1", 1063 | "@mui/system": "^6.1.1", 1064 | "@mui/types": "^7.2.17", 1065 | "@mui/utils": "^6.1.1", 1066 | "@popperjs/core": "^2.11.8", 1067 | "@types/react-transition-group": "^4.4.11", 1068 | "clsx": "^2.1.1", 1069 | "csstype": "^3.1.3", 1070 | "prop-types": "^15.8.1", 1071 | "react-is": "^18.3.1", 1072 | "react-transition-group": "^4.4.5" 1073 | }, 1074 | "engines": { 1075 | "node": ">=14.0.0" 1076 | }, 1077 | "funding": { 1078 | "type": "opencollective", 1079 | "url": "https://opencollective.com/mui-org" 1080 | }, 1081 | "peerDependencies": { 1082 | "@emotion/react": "^11.5.0", 1083 | "@emotion/styled": "^11.3.0", 1084 | "@mui/material-pigment-css": "^6.1.1", 1085 | "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", 1086 | "react": "^17.0.0 || ^18.0.0 || ^19.0.0", 1087 | "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" 1088 | }, 1089 | "peerDependenciesMeta": { 1090 | "@emotion/react": { 1091 | "optional": true 1092 | }, 1093 | "@emotion/styled": { 1094 | "optional": true 1095 | }, 1096 | "@mui/material-pigment-css": { 1097 | "optional": true 1098 | }, 1099 | "@types/react": { 1100 | "optional": true 1101 | } 1102 | } 1103 | }, 1104 | "node_modules/@mui/private-theming": { 1105 | "version": "6.1.1", 1106 | "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.1.1.tgz", 1107 | "integrity": "sha512-JlrjIdhyZUtewtdAuUsvi3ZnO0YS49IW4Mfz19ZWTlQ0sDGga6LNPVwHClWr2/zJK2we2BQx9/i8M32rgKuzrg==", 1108 | "dependencies": { 1109 | "@babel/runtime": "^7.25.6", 1110 | "@mui/utils": "^6.1.1", 1111 | "prop-types": "^15.8.1" 1112 | }, 1113 | "engines": { 1114 | "node": ">=14.0.0" 1115 | }, 1116 | "funding": { 1117 | "type": "opencollective", 1118 | "url": "https://opencollective.com/mui-org" 1119 | }, 1120 | "peerDependencies": { 1121 | "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", 1122 | "react": "^17.0.0 || ^18.0.0 || ^19.0.0" 1123 | }, 1124 | "peerDependenciesMeta": { 1125 | "@types/react": { 1126 | "optional": true 1127 | } 1128 | } 1129 | }, 1130 | "node_modules/@mui/styled-engine": { 1131 | "version": "6.1.1", 1132 | "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.1.1.tgz", 1133 | "integrity": "sha512-HJyIoMpFb11fnHuRtUILOXgq6vj4LhIlE8maG4SwP/W+E5sa7HFexhnB3vOMT7bKys4UKNxhobC8jwWxYilGsA==", 1134 | "dependencies": { 1135 | "@babel/runtime": "^7.25.6", 1136 | "@emotion/cache": "^11.13.1", 1137 | "@emotion/sheet": "^1.4.0", 1138 | "csstype": "^3.1.3", 1139 | "prop-types": "^15.8.1" 1140 | }, 1141 | "engines": { 1142 | "node": ">=14.0.0" 1143 | }, 1144 | "funding": { 1145 | "type": "opencollective", 1146 | "url": "https://opencollective.com/mui-org" 1147 | }, 1148 | "peerDependencies": { 1149 | "@emotion/react": "^11.4.1", 1150 | "@emotion/styled": "^11.3.0", 1151 | "react": "^17.0.0 || ^18.0.0 || ^19.0.0" 1152 | }, 1153 | "peerDependenciesMeta": { 1154 | "@emotion/react": { 1155 | "optional": true 1156 | }, 1157 | "@emotion/styled": { 1158 | "optional": true 1159 | } 1160 | } 1161 | }, 1162 | "node_modules/@mui/system": { 1163 | "version": "6.1.1", 1164 | "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.1.1.tgz", 1165 | "integrity": "sha512-PaYsCz2tUOcpu3T0okDEsSuP/yCDIj9JZ4Tox1JovRSKIjltHpXPsXZSGr3RiWdtM1MTQMFMCZzu0+CKbyy+Kw==", 1166 | "dependencies": { 1167 | "@babel/runtime": "^7.25.6", 1168 | "@mui/private-theming": "^6.1.1", 1169 | "@mui/styled-engine": "^6.1.1", 1170 | "@mui/types": "^7.2.17", 1171 | "@mui/utils": "^6.1.1", 1172 | "clsx": "^2.1.1", 1173 | "csstype": "^3.1.3", 1174 | "prop-types": "^15.8.1" 1175 | }, 1176 | "engines": { 1177 | "node": ">=14.0.0" 1178 | }, 1179 | "funding": { 1180 | "type": "opencollective", 1181 | "url": "https://opencollective.com/mui-org" 1182 | }, 1183 | "peerDependencies": { 1184 | "@emotion/react": "^11.5.0", 1185 | "@emotion/styled": "^11.3.0", 1186 | "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", 1187 | "react": "^17.0.0 || ^18.0.0 || ^19.0.0" 1188 | }, 1189 | "peerDependenciesMeta": { 1190 | "@emotion/react": { 1191 | "optional": true 1192 | }, 1193 | "@emotion/styled": { 1194 | "optional": true 1195 | }, 1196 | "@types/react": { 1197 | "optional": true 1198 | } 1199 | } 1200 | }, 1201 | "node_modules/@mui/types": { 1202 | "version": "7.2.17", 1203 | "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.17.tgz", 1204 | "integrity": "sha512-oyumoJgB6jDV8JFzRqjBo2daUuHpzDjoO/e3IrRhhHo/FxJlaVhET6mcNrKHUq2E+R+q3ql0qAtvQ4rfWHhAeQ==", 1205 | "peerDependencies": { 1206 | "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" 1207 | }, 1208 | "peerDependenciesMeta": { 1209 | "@types/react": { 1210 | "optional": true 1211 | } 1212 | } 1213 | }, 1214 | "node_modules/@mui/utils": { 1215 | "version": "6.1.1", 1216 | "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.1.1.tgz", 1217 | "integrity": "sha512-HlRrgdJSPbYDXPpoVMWZV8AE7WcFtAk13rWNWAEVWKSanzBBkymjz3km+Th/Srowsh4pf1fTSP1B0L116wQBYw==", 1218 | "dependencies": { 1219 | "@babel/runtime": "^7.25.6", 1220 | "@mui/types": "^7.2.17", 1221 | "@types/prop-types": "^15.7.12", 1222 | "clsx": "^2.1.1", 1223 | "prop-types": "^15.8.1", 1224 | "react-is": "^18.3.1" 1225 | }, 1226 | "engines": { 1227 | "node": ">=14.0.0" 1228 | }, 1229 | "funding": { 1230 | "type": "opencollective", 1231 | "url": "https://opencollective.com/mui-org" 1232 | }, 1233 | "peerDependencies": { 1234 | "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", 1235 | "react": "^17.0.0 || ^18.0.0 || ^19.0.0" 1236 | }, 1237 | "peerDependenciesMeta": { 1238 | "@types/react": { 1239 | "optional": true 1240 | } 1241 | } 1242 | }, 1243 | "node_modules/@mui/x-data-grid": { 1244 | "version": "7.18.0", 1245 | "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-7.18.0.tgz", 1246 | "integrity": "sha512-41UjJbRxWk+Yk/lfvaO55Pwo5p+F5s3rOTiHLl53ikCT5GuJ5OCCvik0Bi3c6DzTuUBdrEucae2618rydc2DGw==", 1247 | "dependencies": { 1248 | "@babel/runtime": "^7.25.6", 1249 | "@mui/utils": "^5.16.6", 1250 | "@mui/x-internals": "7.18.0", 1251 | "clsx": "^2.1.1", 1252 | "prop-types": "^15.8.1", 1253 | "reselect": "^5.1.1" 1254 | }, 1255 | "engines": { 1256 | "node": ">=14.0.0" 1257 | }, 1258 | "funding": { 1259 | "type": "opencollective", 1260 | "url": "https://opencollective.com/mui-org" 1261 | }, 1262 | "peerDependencies": { 1263 | "@emotion/react": "^11.9.0", 1264 | "@emotion/styled": "^11.8.1", 1265 | "@mui/material": "^5.15.14 || ^6.0.0", 1266 | "@mui/system": "^5.15.14 || ^6.0.0", 1267 | "react": "^17.0.0 || ^18.0.0", 1268 | "react-dom": "^17.0.0 || ^18.0.0" 1269 | }, 1270 | "peerDependenciesMeta": { 1271 | "@emotion/react": { 1272 | "optional": true 1273 | }, 1274 | "@emotion/styled": { 1275 | "optional": true 1276 | } 1277 | } 1278 | }, 1279 | "node_modules/@mui/x-data-grid/node_modules/@mui/utils": { 1280 | "version": "5.16.6", 1281 | "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.6.tgz", 1282 | "integrity": "sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA==", 1283 | "dependencies": { 1284 | "@babel/runtime": "^7.23.9", 1285 | "@mui/types": "^7.2.15", 1286 | "@types/prop-types": "^15.7.12", 1287 | "clsx": "^2.1.1", 1288 | "prop-types": "^15.8.1", 1289 | "react-is": "^18.3.1" 1290 | }, 1291 | "engines": { 1292 | "node": ">=12.0.0" 1293 | }, 1294 | "funding": { 1295 | "type": "opencollective", 1296 | "url": "https://opencollective.com/mui-org" 1297 | }, 1298 | "peerDependencies": { 1299 | "@types/react": "^17.0.0 || ^18.0.0", 1300 | "react": "^17.0.0 || ^18.0.0" 1301 | }, 1302 | "peerDependenciesMeta": { 1303 | "@types/react": { 1304 | "optional": true 1305 | } 1306 | } 1307 | }, 1308 | "node_modules/@mui/x-internals": { 1309 | "version": "7.18.0", 1310 | "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.18.0.tgz", 1311 | "integrity": "sha512-lzCHOWIR0cAIY1bGrWSprYerahbnH5C31ql/2OWCEjcngL2NAV1M6oKI2Vp4HheqzJ822c60UyWyapvyjSzY/A==", 1312 | "dependencies": { 1313 | "@babel/runtime": "^7.25.6", 1314 | "@mui/utils": "^5.16.6" 1315 | }, 1316 | "engines": { 1317 | "node": ">=14.0.0" 1318 | }, 1319 | "funding": { 1320 | "type": "opencollective", 1321 | "url": "https://opencollective.com/mui-org" 1322 | }, 1323 | "peerDependencies": { 1324 | "react": "^17.0.0 || ^18.0.0" 1325 | } 1326 | }, 1327 | "node_modules/@mui/x-internals/node_modules/@mui/utils": { 1328 | "version": "5.16.6", 1329 | "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.6.tgz", 1330 | "integrity": "sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA==", 1331 | "dependencies": { 1332 | "@babel/runtime": "^7.23.9", 1333 | "@mui/types": "^7.2.15", 1334 | "@types/prop-types": "^15.7.12", 1335 | "clsx": "^2.1.1", 1336 | "prop-types": "^15.8.1", 1337 | "react-is": "^18.3.1" 1338 | }, 1339 | "engines": { 1340 | "node": ">=12.0.0" 1341 | }, 1342 | "funding": { 1343 | "type": "opencollective", 1344 | "url": "https://opencollective.com/mui-org" 1345 | }, 1346 | "peerDependencies": { 1347 | "@types/react": "^17.0.0 || ^18.0.0", 1348 | "react": "^17.0.0 || ^18.0.0" 1349 | }, 1350 | "peerDependenciesMeta": { 1351 | "@types/react": { 1352 | "optional": true 1353 | } 1354 | } 1355 | }, 1356 | "node_modules/@nodelib/fs.scandir": { 1357 | "version": "2.1.5", 1358 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 1359 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 1360 | "dev": true, 1361 | "dependencies": { 1362 | "@nodelib/fs.stat": "2.0.5", 1363 | "run-parallel": "^1.1.9" 1364 | }, 1365 | "engines": { 1366 | "node": ">= 8" 1367 | } 1368 | }, 1369 | "node_modules/@nodelib/fs.stat": { 1370 | "version": "2.0.5", 1371 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 1372 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 1373 | "dev": true, 1374 | "engines": { 1375 | "node": ">= 8" 1376 | } 1377 | }, 1378 | "node_modules/@nodelib/fs.walk": { 1379 | "version": "1.2.8", 1380 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 1381 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 1382 | "dev": true, 1383 | "dependencies": { 1384 | "@nodelib/fs.scandir": "2.1.5", 1385 | "fastq": "^1.6.0" 1386 | }, 1387 | "engines": { 1388 | "node": ">= 8" 1389 | } 1390 | }, 1391 | "node_modules/@popperjs/core": { 1392 | "version": "2.11.8", 1393 | "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", 1394 | "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", 1395 | "funding": { 1396 | "type": "opencollective", 1397 | "url": "https://opencollective.com/popperjs" 1398 | } 1399 | }, 1400 | "node_modules/@rollup/rollup-android-arm-eabi": { 1401 | "version": "4.22.5", 1402 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.5.tgz", 1403 | "integrity": "sha512-SU5cvamg0Eyu/F+kLeMXS7GoahL+OoizlclVFX3l5Ql6yNlywJJ0OuqTzUx0v+aHhPHEB/56CT06GQrRrGNYww==", 1404 | "cpu": [ 1405 | "arm" 1406 | ], 1407 | "dev": true, 1408 | "optional": true, 1409 | "os": [ 1410 | "android" 1411 | ] 1412 | }, 1413 | "node_modules/@rollup/rollup-android-arm64": { 1414 | "version": "4.22.5", 1415 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.5.tgz", 1416 | "integrity": "sha512-S4pit5BP6E5R5C8S6tgU/drvgjtYW76FBuG6+ibG3tMvlD1h9LHVF9KmlmaUBQ8Obou7hEyS+0w+IR/VtxwNMQ==", 1417 | "cpu": [ 1418 | "arm64" 1419 | ], 1420 | "dev": true, 1421 | "optional": true, 1422 | "os": [ 1423 | "android" 1424 | ] 1425 | }, 1426 | "node_modules/@rollup/rollup-darwin-arm64": { 1427 | "version": "4.22.5", 1428 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.5.tgz", 1429 | "integrity": "sha512-250ZGg4ipTL0TGvLlfACkIxS9+KLtIbn7BCZjsZj88zSg2Lvu3Xdw6dhAhfe/FjjXPVNCtcSp+WZjVsD3a/Zlw==", 1430 | "cpu": [ 1431 | "arm64" 1432 | ], 1433 | "dev": true, 1434 | "optional": true, 1435 | "os": [ 1436 | "darwin" 1437 | ] 1438 | }, 1439 | "node_modules/@rollup/rollup-darwin-x64": { 1440 | "version": "4.22.5", 1441 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.5.tgz", 1442 | "integrity": "sha512-D8brJEFg5D+QxFcW6jYANu+Rr9SlKtTenmsX5hOSzNYVrK5oLAEMTUgKWYJP+wdKyCdeSwnapLsn+OVRFycuQg==", 1443 | "cpu": [ 1444 | "x64" 1445 | ], 1446 | "dev": true, 1447 | "optional": true, 1448 | "os": [ 1449 | "darwin" 1450 | ] 1451 | }, 1452 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": { 1453 | "version": "4.22.5", 1454 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.5.tgz", 1455 | "integrity": "sha512-PNqXYmdNFyWNg0ma5LdY8wP+eQfdvyaBAojAXgO7/gs0Q/6TQJVXAXe8gwW9URjbS0YAammur0fynYGiWsKlXw==", 1456 | "cpu": [ 1457 | "arm" 1458 | ], 1459 | "dev": true, 1460 | "optional": true, 1461 | "os": [ 1462 | "linux" 1463 | ] 1464 | }, 1465 | "node_modules/@rollup/rollup-linux-arm-musleabihf": { 1466 | "version": "4.22.5", 1467 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.5.tgz", 1468 | "integrity": "sha512-kSSCZOKz3HqlrEuwKd9TYv7vxPYD77vHSUvM2y0YaTGnFc8AdI5TTQRrM1yIp3tXCKrSL9A7JLoILjtad5t8pQ==", 1469 | "cpu": [ 1470 | "arm" 1471 | ], 1472 | "dev": true, 1473 | "optional": true, 1474 | "os": [ 1475 | "linux" 1476 | ] 1477 | }, 1478 | "node_modules/@rollup/rollup-linux-arm64-gnu": { 1479 | "version": "4.22.5", 1480 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.5.tgz", 1481 | "integrity": "sha512-oTXQeJHRbOnwRnRffb6bmqmUugz0glXaPyspp4gbQOPVApdpRrY/j7KP3lr7M8kTfQTyrBUzFjj5EuHAhqH4/w==", 1482 | "cpu": [ 1483 | "arm64" 1484 | ], 1485 | "dev": true, 1486 | "optional": true, 1487 | "os": [ 1488 | "linux" 1489 | ] 1490 | }, 1491 | "node_modules/@rollup/rollup-linux-arm64-musl": { 1492 | "version": "4.22.5", 1493 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.5.tgz", 1494 | "integrity": "sha512-qnOTIIs6tIGFKCHdhYitgC2XQ2X25InIbZFor5wh+mALH84qnFHvc+vmWUpyX97B0hNvwNUL4B+MB8vJvH65Fw==", 1495 | "cpu": [ 1496 | "arm64" 1497 | ], 1498 | "dev": true, 1499 | "optional": true, 1500 | "os": [ 1501 | "linux" 1502 | ] 1503 | }, 1504 | "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { 1505 | "version": "4.22.5", 1506 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.5.tgz", 1507 | "integrity": "sha512-TMYu+DUdNlgBXING13rHSfUc3Ky5nLPbWs4bFnT+R6Vu3OvXkTkixvvBKk8uO4MT5Ab6lC3U7x8S8El2q5o56w==", 1508 | "cpu": [ 1509 | "ppc64" 1510 | ], 1511 | "dev": true, 1512 | "optional": true, 1513 | "os": [ 1514 | "linux" 1515 | ] 1516 | }, 1517 | "node_modules/@rollup/rollup-linux-riscv64-gnu": { 1518 | "version": "4.22.5", 1519 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.5.tgz", 1520 | "integrity": "sha512-PTQq1Kz22ZRvuhr3uURH+U/Q/a0pbxJoICGSprNLAoBEkyD3Sh9qP5I0Asn0y0wejXQBbsVMRZRxlbGFD9OK4A==", 1521 | "cpu": [ 1522 | "riscv64" 1523 | ], 1524 | "dev": true, 1525 | "optional": true, 1526 | "os": [ 1527 | "linux" 1528 | ] 1529 | }, 1530 | "node_modules/@rollup/rollup-linux-s390x-gnu": { 1531 | "version": "4.22.5", 1532 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.5.tgz", 1533 | "integrity": "sha512-bR5nCojtpuMss6TDEmf/jnBnzlo+6n1UhgwqUvRoe4VIotC7FG1IKkyJbwsT7JDsF2jxR+NTnuOwiGv0hLyDoQ==", 1534 | "cpu": [ 1535 | "s390x" 1536 | ], 1537 | "dev": true, 1538 | "optional": true, 1539 | "os": [ 1540 | "linux" 1541 | ] 1542 | }, 1543 | "node_modules/@rollup/rollup-linux-x64-gnu": { 1544 | "version": "4.22.5", 1545 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.5.tgz", 1546 | "integrity": "sha512-N0jPPhHjGShcB9/XXZQWuWBKZQnC1F36Ce3sDqWpujsGjDz/CQtOL9LgTrJ+rJC8MJeesMWrMWVLKKNR/tMOCA==", 1547 | "cpu": [ 1548 | "x64" 1549 | ], 1550 | "dev": true, 1551 | "optional": true, 1552 | "os": [ 1553 | "linux" 1554 | ] 1555 | }, 1556 | "node_modules/@rollup/rollup-linux-x64-musl": { 1557 | "version": "4.22.5", 1558 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.5.tgz", 1559 | "integrity": "sha512-uBa2e28ohzNNwjr6Uxm4XyaA1M/8aTgfF2T7UIlElLaeXkgpmIJ2EitVNQxjO9xLLLy60YqAgKn/AqSpCUkE9g==", 1560 | "cpu": [ 1561 | "x64" 1562 | ], 1563 | "dev": true, 1564 | "optional": true, 1565 | "os": [ 1566 | "linux" 1567 | ] 1568 | }, 1569 | "node_modules/@rollup/rollup-win32-arm64-msvc": { 1570 | "version": "4.22.5", 1571 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.5.tgz", 1572 | "integrity": "sha512-RXT8S1HP8AFN/Kr3tg4fuYrNxZ/pZf1HemC5Tsddc6HzgGnJm0+Lh5rAHJkDuW3StI0ynNXukidROMXYl6ew8w==", 1573 | "cpu": [ 1574 | "arm64" 1575 | ], 1576 | "dev": true, 1577 | "optional": true, 1578 | "os": [ 1579 | "win32" 1580 | ] 1581 | }, 1582 | "node_modules/@rollup/rollup-win32-ia32-msvc": { 1583 | "version": "4.22.5", 1584 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.5.tgz", 1585 | "integrity": "sha512-ElTYOh50InL8kzyUD6XsnPit7jYCKrphmddKAe1/Ytt74apOxDq5YEcbsiKs0fR3vff3jEneMM+3I7jbqaMyBg==", 1586 | "cpu": [ 1587 | "ia32" 1588 | ], 1589 | "dev": true, 1590 | "optional": true, 1591 | "os": [ 1592 | "win32" 1593 | ] 1594 | }, 1595 | "node_modules/@rollup/rollup-win32-x64-msvc": { 1596 | "version": "4.22.5", 1597 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.5.tgz", 1598 | "integrity": "sha512-+lvL/4mQxSV8MukpkKyyvfwhH266COcWlXE/1qxwN08ajovta3459zrjLghYMgDerlzNwLAcFpvU+WWE5y6nAQ==", 1599 | "cpu": [ 1600 | "x64" 1601 | ], 1602 | "dev": true, 1603 | "optional": true, 1604 | "os": [ 1605 | "win32" 1606 | ] 1607 | }, 1608 | "node_modules/@swc/core": { 1609 | "version": "1.7.26", 1610 | "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.7.26.tgz", 1611 | "integrity": "sha512-f5uYFf+TmMQyYIoxkn/evWhNGuUzC730dFwAKGwBVHHVoPyak1/GvJUm6i1SKl+2Hrj9oN0i3WSoWWZ4pgI8lw==", 1612 | "dev": true, 1613 | "hasInstallScript": true, 1614 | "dependencies": { 1615 | "@swc/counter": "^0.1.3", 1616 | "@swc/types": "^0.1.12" 1617 | }, 1618 | "engines": { 1619 | "node": ">=10" 1620 | }, 1621 | "funding": { 1622 | "type": "opencollective", 1623 | "url": "https://opencollective.com/swc" 1624 | }, 1625 | "optionalDependencies": { 1626 | "@swc/core-darwin-arm64": "1.7.26", 1627 | "@swc/core-darwin-x64": "1.7.26", 1628 | "@swc/core-linux-arm-gnueabihf": "1.7.26", 1629 | "@swc/core-linux-arm64-gnu": "1.7.26", 1630 | "@swc/core-linux-arm64-musl": "1.7.26", 1631 | "@swc/core-linux-x64-gnu": "1.7.26", 1632 | "@swc/core-linux-x64-musl": "1.7.26", 1633 | "@swc/core-win32-arm64-msvc": "1.7.26", 1634 | "@swc/core-win32-ia32-msvc": "1.7.26", 1635 | "@swc/core-win32-x64-msvc": "1.7.26" 1636 | }, 1637 | "peerDependencies": { 1638 | "@swc/helpers": "*" 1639 | }, 1640 | "peerDependenciesMeta": { 1641 | "@swc/helpers": { 1642 | "optional": true 1643 | } 1644 | } 1645 | }, 1646 | "node_modules/@swc/core-darwin-arm64": { 1647 | "version": "1.7.26", 1648 | "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.7.26.tgz", 1649 | "integrity": "sha512-FF3CRYTg6a7ZVW4yT9mesxoVVZTrcSWtmZhxKCYJX9brH4CS/7PRPjAKNk6kzWgWuRoglP7hkjQcd6EpMcZEAw==", 1650 | "cpu": [ 1651 | "arm64" 1652 | ], 1653 | "dev": true, 1654 | "optional": true, 1655 | "os": [ 1656 | "darwin" 1657 | ], 1658 | "engines": { 1659 | "node": ">=10" 1660 | } 1661 | }, 1662 | "node_modules/@swc/core-darwin-x64": { 1663 | "version": "1.7.26", 1664 | "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.7.26.tgz", 1665 | "integrity": "sha512-az3cibZdsay2HNKmc4bjf62QVukuiMRh5sfM5kHR/JMTrLyS6vSw7Ihs3UTkZjUxkLTT8ro54LI6sV6sUQUbLQ==", 1666 | "cpu": [ 1667 | "x64" 1668 | ], 1669 | "dev": true, 1670 | "optional": true, 1671 | "os": [ 1672 | "darwin" 1673 | ], 1674 | "engines": { 1675 | "node": ">=10" 1676 | } 1677 | }, 1678 | "node_modules/@swc/core-linux-arm-gnueabihf": { 1679 | "version": "1.7.26", 1680 | "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.7.26.tgz", 1681 | "integrity": "sha512-VYPFVJDO5zT5U3RpCdHE5v1gz4mmR8BfHecUZTmD2v1JeFY6fv9KArJUpjrHEEsjK/ucXkQFmJ0jaiWXmpOV9Q==", 1682 | "cpu": [ 1683 | "arm" 1684 | ], 1685 | "dev": true, 1686 | "optional": true, 1687 | "os": [ 1688 | "linux" 1689 | ], 1690 | "engines": { 1691 | "node": ">=10" 1692 | } 1693 | }, 1694 | "node_modules/@swc/core-linux-arm64-gnu": { 1695 | "version": "1.7.26", 1696 | "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.7.26.tgz", 1697 | "integrity": "sha512-YKevOV7abpjcAzXrhsl+W48Z9mZvgoVs2eP5nY+uoMAdP2b3GxC0Df1Co0I90o2lkzO4jYBpTMcZlmUXLdXn+Q==", 1698 | "cpu": [ 1699 | "arm64" 1700 | ], 1701 | "dev": true, 1702 | "optional": true, 1703 | "os": [ 1704 | "linux" 1705 | ], 1706 | "engines": { 1707 | "node": ">=10" 1708 | } 1709 | }, 1710 | "node_modules/@swc/core-linux-arm64-musl": { 1711 | "version": "1.7.26", 1712 | "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.7.26.tgz", 1713 | "integrity": "sha512-3w8iZICMkQQON0uIcvz7+Q1MPOW6hJ4O5ETjA0LSP/tuKqx30hIniCGOgPDnv3UTMruLUnQbtBwVCZTBKR3Rkg==", 1714 | "cpu": [ 1715 | "arm64" 1716 | ], 1717 | "dev": true, 1718 | "optional": true, 1719 | "os": [ 1720 | "linux" 1721 | ], 1722 | "engines": { 1723 | "node": ">=10" 1724 | } 1725 | }, 1726 | "node_modules/@swc/core-linux-x64-gnu": { 1727 | "version": "1.7.26", 1728 | "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.7.26.tgz", 1729 | "integrity": "sha512-c+pp9Zkk2lqb06bNGkR2Looxrs7FtGDMA4/aHjZcCqATgp348hOKH5WPvNLBl+yPrISuWjbKDVn3NgAvfvpH4w==", 1730 | "cpu": [ 1731 | "x64" 1732 | ], 1733 | "dev": true, 1734 | "optional": true, 1735 | "os": [ 1736 | "linux" 1737 | ], 1738 | "engines": { 1739 | "node": ">=10" 1740 | } 1741 | }, 1742 | "node_modules/@swc/core-linux-x64-musl": { 1743 | "version": "1.7.26", 1744 | "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.7.26.tgz", 1745 | "integrity": "sha512-PgtyfHBF6xG87dUSSdTJHwZ3/8vWZfNIXQV2GlwEpslrOkGqy+WaiiyE7Of7z9AvDILfBBBcJvJ/r8u980wAfQ==", 1746 | "cpu": [ 1747 | "x64" 1748 | ], 1749 | "dev": true, 1750 | "optional": true, 1751 | "os": [ 1752 | "linux" 1753 | ], 1754 | "engines": { 1755 | "node": ">=10" 1756 | } 1757 | }, 1758 | "node_modules/@swc/core-win32-arm64-msvc": { 1759 | "version": "1.7.26", 1760 | "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.7.26.tgz", 1761 | "integrity": "sha512-9TNXPIJqFynlAOrRD6tUQjMq7KApSklK3R/tXgIxc7Qx+lWu8hlDQ/kVPLpU7PWvMMwC/3hKBW+p5f+Tms1hmA==", 1762 | "cpu": [ 1763 | "arm64" 1764 | ], 1765 | "dev": true, 1766 | "optional": true, 1767 | "os": [ 1768 | "win32" 1769 | ], 1770 | "engines": { 1771 | "node": ">=10" 1772 | } 1773 | }, 1774 | "node_modules/@swc/core-win32-ia32-msvc": { 1775 | "version": "1.7.26", 1776 | "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.7.26.tgz", 1777 | "integrity": "sha512-9YngxNcG3177GYdsTum4V98Re+TlCeJEP4kEwEg9EagT5s3YejYdKwVAkAsJszzkXuyRDdnHUpYbTrPG6FiXrQ==", 1778 | "cpu": [ 1779 | "ia32" 1780 | ], 1781 | "dev": true, 1782 | "optional": true, 1783 | "os": [ 1784 | "win32" 1785 | ], 1786 | "engines": { 1787 | "node": ">=10" 1788 | } 1789 | }, 1790 | "node_modules/@swc/core-win32-x64-msvc": { 1791 | "version": "1.7.26", 1792 | "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.7.26.tgz", 1793 | "integrity": "sha512-VR+hzg9XqucgLjXxA13MtV5O3C0bK0ywtLIBw/+a+O+Oc6mxFWHtdUeXDbIi5AiPbn0fjgVJMqYnyjGyyX8u0w==", 1794 | "cpu": [ 1795 | "x64" 1796 | ], 1797 | "dev": true, 1798 | "optional": true, 1799 | "os": [ 1800 | "win32" 1801 | ], 1802 | "engines": { 1803 | "node": ">=10" 1804 | } 1805 | }, 1806 | "node_modules/@swc/counter": { 1807 | "version": "0.1.3", 1808 | "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", 1809 | "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", 1810 | "dev": true 1811 | }, 1812 | "node_modules/@swc/types": { 1813 | "version": "0.1.12", 1814 | "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.12.tgz", 1815 | "integrity": "sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==", 1816 | "dev": true, 1817 | "dependencies": { 1818 | "@swc/counter": "^0.1.3" 1819 | } 1820 | }, 1821 | "node_modules/@tanstack/query-core": { 1822 | "version": "5.56.2", 1823 | "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.56.2.tgz", 1824 | "integrity": "sha512-gor0RI3/R5rVV3gXfddh1MM+hgl0Z4G7tj6Xxpq6p2I03NGPaJ8dITY9Gz05zYYb/EJq9vPas/T4wn9EaDPd4Q==", 1825 | "funding": { 1826 | "type": "github", 1827 | "url": "https://github.com/sponsors/tannerlinsley" 1828 | } 1829 | }, 1830 | "node_modules/@tanstack/react-query": { 1831 | "version": "5.56.2", 1832 | "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.56.2.tgz", 1833 | "integrity": "sha512-SR0GzHVo6yzhN72pnRhkEFRAHMsUo5ZPzAxfTMvUxFIDVS6W9LYUp6nXW3fcHVdg0ZJl8opSH85jqahvm6DSVg==", 1834 | "dependencies": { 1835 | "@tanstack/query-core": "5.56.2" 1836 | }, 1837 | "funding": { 1838 | "type": "github", 1839 | "url": "https://github.com/sponsors/tannerlinsley" 1840 | }, 1841 | "peerDependencies": { 1842 | "react": "^18 || ^19" 1843 | } 1844 | }, 1845 | "node_modules/@types/estree": { 1846 | "version": "1.0.6", 1847 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", 1848 | "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", 1849 | "dev": true 1850 | }, 1851 | "node_modules/@types/json-schema": { 1852 | "version": "7.0.15", 1853 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", 1854 | "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", 1855 | "dev": true 1856 | }, 1857 | "node_modules/@types/node": { 1858 | "version": "22.7.3", 1859 | "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.3.tgz", 1860 | "integrity": "sha512-qXKfhXXqGTyBskvWEzJZPUxSslAiLaB6JGP1ic/XTH9ctGgzdgYguuLP1C601aRTSDNlLb0jbKqXjZ48GNraSA==", 1861 | "dev": true, 1862 | "dependencies": { 1863 | "undici-types": "~6.19.2" 1864 | } 1865 | }, 1866 | "node_modules/@types/parse-json": { 1867 | "version": "4.0.2", 1868 | "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", 1869 | "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" 1870 | }, 1871 | "node_modules/@types/prop-types": { 1872 | "version": "15.7.13", 1873 | "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", 1874 | "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==" 1875 | }, 1876 | "node_modules/@types/react": { 1877 | "version": "18.3.9", 1878 | "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.9.tgz", 1879 | "integrity": "sha512-+BpAVyTpJkNWWSSnaLBk6ePpHLOGJKnEQNbINNovPWzvEUyAe3e+/d494QdEh71RekM/qV7lw6jzf1HGrJyAtQ==", 1880 | "dependencies": { 1881 | "@types/prop-types": "*", 1882 | "csstype": "^3.0.2" 1883 | } 1884 | }, 1885 | "node_modules/@types/react-dom": { 1886 | "version": "18.3.0", 1887 | "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", 1888 | "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", 1889 | "dev": true, 1890 | "dependencies": { 1891 | "@types/react": "*" 1892 | } 1893 | }, 1894 | "node_modules/@types/react-transition-group": { 1895 | "version": "4.4.11", 1896 | "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.11.tgz", 1897 | "integrity": "sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==", 1898 | "dependencies": { 1899 | "@types/react": "*" 1900 | } 1901 | }, 1902 | "node_modules/@typescript-eslint/eslint-plugin": { 1903 | "version": "8.7.0", 1904 | "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.7.0.tgz", 1905 | "integrity": "sha512-RIHOoznhA3CCfSTFiB6kBGLQtB/sox+pJ6jeFu6FxJvqL8qRxq/FfGO/UhsGgQM9oGdXkV4xUgli+dt26biB6A==", 1906 | "dev": true, 1907 | "dependencies": { 1908 | "@eslint-community/regexpp": "^4.10.0", 1909 | "@typescript-eslint/scope-manager": "8.7.0", 1910 | "@typescript-eslint/type-utils": "8.7.0", 1911 | "@typescript-eslint/utils": "8.7.0", 1912 | "@typescript-eslint/visitor-keys": "8.7.0", 1913 | "graphemer": "^1.4.0", 1914 | "ignore": "^5.3.1", 1915 | "natural-compare": "^1.4.0", 1916 | "ts-api-utils": "^1.3.0" 1917 | }, 1918 | "engines": { 1919 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1920 | }, 1921 | "funding": { 1922 | "type": "opencollective", 1923 | "url": "https://opencollective.com/typescript-eslint" 1924 | }, 1925 | "peerDependencies": { 1926 | "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", 1927 | "eslint": "^8.57.0 || ^9.0.0" 1928 | }, 1929 | "peerDependenciesMeta": { 1930 | "typescript": { 1931 | "optional": true 1932 | } 1933 | } 1934 | }, 1935 | "node_modules/@typescript-eslint/parser": { 1936 | "version": "8.7.0", 1937 | "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.7.0.tgz", 1938 | "integrity": "sha512-lN0btVpj2unxHlNYLI//BQ7nzbMJYBVQX5+pbNXvGYazdlgYonMn4AhhHifQ+J4fGRYA/m1DjaQjx+fDetqBOQ==", 1939 | "dev": true, 1940 | "dependencies": { 1941 | "@typescript-eslint/scope-manager": "8.7.0", 1942 | "@typescript-eslint/types": "8.7.0", 1943 | "@typescript-eslint/typescript-estree": "8.7.0", 1944 | "@typescript-eslint/visitor-keys": "8.7.0", 1945 | "debug": "^4.3.4" 1946 | }, 1947 | "engines": { 1948 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1949 | }, 1950 | "funding": { 1951 | "type": "opencollective", 1952 | "url": "https://opencollective.com/typescript-eslint" 1953 | }, 1954 | "peerDependencies": { 1955 | "eslint": "^8.57.0 || ^9.0.0" 1956 | }, 1957 | "peerDependenciesMeta": { 1958 | "typescript": { 1959 | "optional": true 1960 | } 1961 | } 1962 | }, 1963 | "node_modules/@typescript-eslint/scope-manager": { 1964 | "version": "8.7.0", 1965 | "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.7.0.tgz", 1966 | "integrity": "sha512-87rC0k3ZlDOuz82zzXRtQ7Akv3GKhHs0ti4YcbAJtaomllXoSO8hi7Ix3ccEvCd824dy9aIX+j3d2UMAfCtVpg==", 1967 | "dev": true, 1968 | "dependencies": { 1969 | "@typescript-eslint/types": "8.7.0", 1970 | "@typescript-eslint/visitor-keys": "8.7.0" 1971 | }, 1972 | "engines": { 1973 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1974 | }, 1975 | "funding": { 1976 | "type": "opencollective", 1977 | "url": "https://opencollective.com/typescript-eslint" 1978 | } 1979 | }, 1980 | "node_modules/@typescript-eslint/type-utils": { 1981 | "version": "8.7.0", 1982 | "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.7.0.tgz", 1983 | "integrity": "sha512-tl0N0Mj3hMSkEYhLkjREp54OSb/FI6qyCzfiiclvJvOqre6hsZTGSnHtmFLDU8TIM62G7ygEa1bI08lcuRwEnQ==", 1984 | "dev": true, 1985 | "dependencies": { 1986 | "@typescript-eslint/typescript-estree": "8.7.0", 1987 | "@typescript-eslint/utils": "8.7.0", 1988 | "debug": "^4.3.4", 1989 | "ts-api-utils": "^1.3.0" 1990 | }, 1991 | "engines": { 1992 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1993 | }, 1994 | "funding": { 1995 | "type": "opencollective", 1996 | "url": "https://opencollective.com/typescript-eslint" 1997 | }, 1998 | "peerDependenciesMeta": { 1999 | "typescript": { 2000 | "optional": true 2001 | } 2002 | } 2003 | }, 2004 | "node_modules/@typescript-eslint/types": { 2005 | "version": "8.7.0", 2006 | "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.7.0.tgz", 2007 | "integrity": "sha512-LLt4BLHFwSfASHSF2K29SZ+ZCsbQOM+LuarPjRUuHm+Qd09hSe3GCeaQbcCr+Mik+0QFRmep/FyZBO6fJ64U3w==", 2008 | "dev": true, 2009 | "engines": { 2010 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 2011 | }, 2012 | "funding": { 2013 | "type": "opencollective", 2014 | "url": "https://opencollective.com/typescript-eslint" 2015 | } 2016 | }, 2017 | "node_modules/@typescript-eslint/typescript-estree": { 2018 | "version": "8.7.0", 2019 | "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.7.0.tgz", 2020 | "integrity": "sha512-MC8nmcGHsmfAKxwnluTQpNqceniT8SteVwd2voYlmiSWGOtjvGXdPl17dYu2797GVscK30Z04WRM28CrKS9WOg==", 2021 | "dev": true, 2022 | "dependencies": { 2023 | "@typescript-eslint/types": "8.7.0", 2024 | "@typescript-eslint/visitor-keys": "8.7.0", 2025 | "debug": "^4.3.4", 2026 | "fast-glob": "^3.3.2", 2027 | "is-glob": "^4.0.3", 2028 | "minimatch": "^9.0.4", 2029 | "semver": "^7.6.0", 2030 | "ts-api-utils": "^1.3.0" 2031 | }, 2032 | "engines": { 2033 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 2034 | }, 2035 | "funding": { 2036 | "type": "opencollective", 2037 | "url": "https://opencollective.com/typescript-eslint" 2038 | }, 2039 | "peerDependenciesMeta": { 2040 | "typescript": { 2041 | "optional": true 2042 | } 2043 | } 2044 | }, 2045 | "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { 2046 | "version": "2.0.1", 2047 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 2048 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 2049 | "dev": true, 2050 | "dependencies": { 2051 | "balanced-match": "^1.0.0" 2052 | } 2053 | }, 2054 | "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { 2055 | "version": "9.0.5", 2056 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", 2057 | "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", 2058 | "dev": true, 2059 | "dependencies": { 2060 | "brace-expansion": "^2.0.1" 2061 | }, 2062 | "engines": { 2063 | "node": ">=16 || 14 >=14.17" 2064 | }, 2065 | "funding": { 2066 | "url": "https://github.com/sponsors/isaacs" 2067 | } 2068 | }, 2069 | "node_modules/@typescript-eslint/utils": { 2070 | "version": "8.7.0", 2071 | "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.7.0.tgz", 2072 | "integrity": "sha512-ZbdUdwsl2X/s3CiyAu3gOlfQzpbuG3nTWKPoIvAu1pu5r8viiJvv2NPN2AqArL35NCYtw/lrPPfM4gxrMLNLPw==", 2073 | "dev": true, 2074 | "dependencies": { 2075 | "@eslint-community/eslint-utils": "^4.4.0", 2076 | "@typescript-eslint/scope-manager": "8.7.0", 2077 | "@typescript-eslint/types": "8.7.0", 2078 | "@typescript-eslint/typescript-estree": "8.7.0" 2079 | }, 2080 | "engines": { 2081 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 2082 | }, 2083 | "funding": { 2084 | "type": "opencollective", 2085 | "url": "https://opencollective.com/typescript-eslint" 2086 | }, 2087 | "peerDependencies": { 2088 | "eslint": "^8.57.0 || ^9.0.0" 2089 | } 2090 | }, 2091 | "node_modules/@typescript-eslint/visitor-keys": { 2092 | "version": "8.7.0", 2093 | "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.7.0.tgz", 2094 | "integrity": "sha512-b1tx0orFCCh/THWPQa2ZwWzvOeyzzp36vkJYOpVg0u8UVOIsfVrnuC9FqAw9gRKn+rG2VmWQ/zDJZzkxUnj/XQ==", 2095 | "dev": true, 2096 | "dependencies": { 2097 | "@typescript-eslint/types": "8.7.0", 2098 | "eslint-visitor-keys": "^3.4.3" 2099 | }, 2100 | "engines": { 2101 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 2102 | }, 2103 | "funding": { 2104 | "type": "opencollective", 2105 | "url": "https://opencollective.com/typescript-eslint" 2106 | } 2107 | }, 2108 | "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { 2109 | "version": "3.4.3", 2110 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", 2111 | "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", 2112 | "dev": true, 2113 | "engines": { 2114 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 2115 | }, 2116 | "funding": { 2117 | "url": "https://opencollective.com/eslint" 2118 | } 2119 | }, 2120 | "node_modules/@vitejs/plugin-react-swc": { 2121 | "version": "3.7.0", 2122 | "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.7.0.tgz", 2123 | "integrity": "sha512-yrknSb3Dci6svCd/qhHqhFPDSw0QtjumcqdKMoNNzmOl5lMXTTiqzjWtG4Qask2HdvvzaNgSunbQGet8/GrKdA==", 2124 | "dev": true, 2125 | "dependencies": { 2126 | "@swc/core": "^1.5.7" 2127 | }, 2128 | "peerDependencies": { 2129 | "vite": "^4 || ^5" 2130 | } 2131 | }, 2132 | "node_modules/acorn": { 2133 | "version": "8.12.1", 2134 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", 2135 | "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", 2136 | "dev": true, 2137 | "bin": { 2138 | "acorn": "bin/acorn" 2139 | }, 2140 | "engines": { 2141 | "node": ">=0.4.0" 2142 | } 2143 | }, 2144 | "node_modules/acorn-jsx": { 2145 | "version": "5.3.2", 2146 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", 2147 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", 2148 | "dev": true, 2149 | "peerDependencies": { 2150 | "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" 2151 | } 2152 | }, 2153 | "node_modules/ajv": { 2154 | "version": "6.12.6", 2155 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 2156 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 2157 | "dev": true, 2158 | "dependencies": { 2159 | "fast-deep-equal": "^3.1.1", 2160 | "fast-json-stable-stringify": "^2.0.0", 2161 | "json-schema-traverse": "^0.4.1", 2162 | "uri-js": "^4.2.2" 2163 | }, 2164 | "funding": { 2165 | "type": "github", 2166 | "url": "https://github.com/sponsors/epoberezkin" 2167 | } 2168 | }, 2169 | "node_modules/ansi-regex": { 2170 | "version": "5.0.1", 2171 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 2172 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 2173 | "dev": true, 2174 | "engines": { 2175 | "node": ">=8" 2176 | } 2177 | }, 2178 | "node_modules/ansi-styles": { 2179 | "version": "3.2.1", 2180 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 2181 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 2182 | "dependencies": { 2183 | "color-convert": "^1.9.0" 2184 | }, 2185 | "engines": { 2186 | "node": ">=4" 2187 | } 2188 | }, 2189 | "node_modules/argparse": { 2190 | "version": "2.0.1", 2191 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 2192 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 2193 | "dev": true 2194 | }, 2195 | "node_modules/asynckit": { 2196 | "version": "0.4.0", 2197 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 2198 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" 2199 | }, 2200 | "node_modules/attr-accept": { 2201 | "version": "2.2.2", 2202 | "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz", 2203 | "integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==", 2204 | "engines": { 2205 | "node": ">=4" 2206 | } 2207 | }, 2208 | "node_modules/axios": { 2209 | "version": "1.7.7", 2210 | "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", 2211 | "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", 2212 | "dependencies": { 2213 | "follow-redirects": "^1.15.6", 2214 | "form-data": "^4.0.0", 2215 | "proxy-from-env": "^1.1.0" 2216 | } 2217 | }, 2218 | "node_modules/babel-plugin-macros": { 2219 | "version": "3.1.0", 2220 | "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", 2221 | "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", 2222 | "dependencies": { 2223 | "@babel/runtime": "^7.12.5", 2224 | "cosmiconfig": "^7.0.0", 2225 | "resolve": "^1.19.0" 2226 | }, 2227 | "engines": { 2228 | "node": ">=10", 2229 | "npm": ">=6" 2230 | } 2231 | }, 2232 | "node_modules/balanced-match": { 2233 | "version": "1.0.2", 2234 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 2235 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 2236 | "dev": true 2237 | }, 2238 | "node_modules/brace-expansion": { 2239 | "version": "1.1.11", 2240 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 2241 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 2242 | "dev": true, 2243 | "dependencies": { 2244 | "balanced-match": "^1.0.0", 2245 | "concat-map": "0.0.1" 2246 | } 2247 | }, 2248 | "node_modules/braces": { 2249 | "version": "3.0.3", 2250 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", 2251 | "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", 2252 | "dev": true, 2253 | "dependencies": { 2254 | "fill-range": "^7.1.1" 2255 | }, 2256 | "engines": { 2257 | "node": ">=8" 2258 | } 2259 | }, 2260 | "node_modules/callsites": { 2261 | "version": "3.1.0", 2262 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 2263 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 2264 | "engines": { 2265 | "node": ">=6" 2266 | } 2267 | }, 2268 | "node_modules/chalk": { 2269 | "version": "2.4.2", 2270 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 2271 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 2272 | "dependencies": { 2273 | "ansi-styles": "^3.2.1", 2274 | "escape-string-regexp": "^1.0.5", 2275 | "supports-color": "^5.3.0" 2276 | }, 2277 | "engines": { 2278 | "node": ">=4" 2279 | } 2280 | }, 2281 | "node_modules/chalk/node_modules/escape-string-regexp": { 2282 | "version": "1.0.5", 2283 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 2284 | "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", 2285 | "engines": { 2286 | "node": ">=0.8.0" 2287 | } 2288 | }, 2289 | "node_modules/clsx": { 2290 | "version": "2.1.1", 2291 | "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", 2292 | "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", 2293 | "engines": { 2294 | "node": ">=6" 2295 | } 2296 | }, 2297 | "node_modules/color-convert": { 2298 | "version": "1.9.3", 2299 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 2300 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 2301 | "dependencies": { 2302 | "color-name": "1.1.3" 2303 | } 2304 | }, 2305 | "node_modules/color-name": { 2306 | "version": "1.1.3", 2307 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 2308 | "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" 2309 | }, 2310 | "node_modules/combined-stream": { 2311 | "version": "1.0.8", 2312 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 2313 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 2314 | "dependencies": { 2315 | "delayed-stream": "~1.0.0" 2316 | }, 2317 | "engines": { 2318 | "node": ">= 0.8" 2319 | } 2320 | }, 2321 | "node_modules/concat-map": { 2322 | "version": "0.0.1", 2323 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 2324 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 2325 | "dev": true 2326 | }, 2327 | "node_modules/convert-source-map": { 2328 | "version": "1.9.0", 2329 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", 2330 | "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" 2331 | }, 2332 | "node_modules/cosmiconfig": { 2333 | "version": "7.1.0", 2334 | "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", 2335 | "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", 2336 | "dependencies": { 2337 | "@types/parse-json": "^4.0.0", 2338 | "import-fresh": "^3.2.1", 2339 | "parse-json": "^5.0.0", 2340 | "path-type": "^4.0.0", 2341 | "yaml": "^1.10.0" 2342 | }, 2343 | "engines": { 2344 | "node": ">=10" 2345 | } 2346 | }, 2347 | "node_modules/cross-spawn": { 2348 | "version": "7.0.3", 2349 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", 2350 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", 2351 | "dev": true, 2352 | "dependencies": { 2353 | "path-key": "^3.1.0", 2354 | "shebang-command": "^2.0.0", 2355 | "which": "^2.0.1" 2356 | }, 2357 | "engines": { 2358 | "node": ">= 8" 2359 | } 2360 | }, 2361 | "node_modules/csstype": { 2362 | "version": "3.1.3", 2363 | "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", 2364 | "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" 2365 | }, 2366 | "node_modules/debug": { 2367 | "version": "4.3.7", 2368 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", 2369 | "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", 2370 | "dependencies": { 2371 | "ms": "^2.1.3" 2372 | }, 2373 | "engines": { 2374 | "node": ">=6.0" 2375 | }, 2376 | "peerDependenciesMeta": { 2377 | "supports-color": { 2378 | "optional": true 2379 | } 2380 | } 2381 | }, 2382 | "node_modules/deep-is": { 2383 | "version": "0.1.4", 2384 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", 2385 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", 2386 | "dev": true 2387 | }, 2388 | "node_modules/delayed-stream": { 2389 | "version": "1.0.0", 2390 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 2391 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", 2392 | "engines": { 2393 | "node": ">=0.4.0" 2394 | } 2395 | }, 2396 | "node_modules/dom-helpers": { 2397 | "version": "5.2.1", 2398 | "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", 2399 | "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", 2400 | "dependencies": { 2401 | "@babel/runtime": "^7.8.7", 2402 | "csstype": "^3.0.2" 2403 | } 2404 | }, 2405 | "node_modules/error-ex": { 2406 | "version": "1.3.2", 2407 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", 2408 | "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", 2409 | "dependencies": { 2410 | "is-arrayish": "^0.2.1" 2411 | } 2412 | }, 2413 | "node_modules/esbuild": { 2414 | "version": "0.21.5", 2415 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", 2416 | "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", 2417 | "dev": true, 2418 | "hasInstallScript": true, 2419 | "bin": { 2420 | "esbuild": "bin/esbuild" 2421 | }, 2422 | "engines": { 2423 | "node": ">=12" 2424 | }, 2425 | "optionalDependencies": { 2426 | "@esbuild/aix-ppc64": "0.21.5", 2427 | "@esbuild/android-arm": "0.21.5", 2428 | "@esbuild/android-arm64": "0.21.5", 2429 | "@esbuild/android-x64": "0.21.5", 2430 | "@esbuild/darwin-arm64": "0.21.5", 2431 | "@esbuild/darwin-x64": "0.21.5", 2432 | "@esbuild/freebsd-arm64": "0.21.5", 2433 | "@esbuild/freebsd-x64": "0.21.5", 2434 | "@esbuild/linux-arm": "0.21.5", 2435 | "@esbuild/linux-arm64": "0.21.5", 2436 | "@esbuild/linux-ia32": "0.21.5", 2437 | "@esbuild/linux-loong64": "0.21.5", 2438 | "@esbuild/linux-mips64el": "0.21.5", 2439 | "@esbuild/linux-ppc64": "0.21.5", 2440 | "@esbuild/linux-riscv64": "0.21.5", 2441 | "@esbuild/linux-s390x": "0.21.5", 2442 | "@esbuild/linux-x64": "0.21.5", 2443 | "@esbuild/netbsd-x64": "0.21.5", 2444 | "@esbuild/openbsd-x64": "0.21.5", 2445 | "@esbuild/sunos-x64": "0.21.5", 2446 | "@esbuild/win32-arm64": "0.21.5", 2447 | "@esbuild/win32-ia32": "0.21.5", 2448 | "@esbuild/win32-x64": "0.21.5" 2449 | } 2450 | }, 2451 | "node_modules/escape-string-regexp": { 2452 | "version": "4.0.0", 2453 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 2454 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 2455 | "engines": { 2456 | "node": ">=10" 2457 | }, 2458 | "funding": { 2459 | "url": "https://github.com/sponsors/sindresorhus" 2460 | } 2461 | }, 2462 | "node_modules/eslint": { 2463 | "version": "9.11.1", 2464 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.11.1.tgz", 2465 | "integrity": "sha512-MobhYKIoAO1s1e4VUrgx1l1Sk2JBR/Gqjjgw8+mfgoLE2xwsHur4gdfTxyTgShrhvdVFTaJSgMiQBl1jv/AWxg==", 2466 | "dev": true, 2467 | "dependencies": { 2468 | "@eslint-community/eslint-utils": "^4.2.0", 2469 | "@eslint-community/regexpp": "^4.11.0", 2470 | "@eslint/config-array": "^0.18.0", 2471 | "@eslint/core": "^0.6.0", 2472 | "@eslint/eslintrc": "^3.1.0", 2473 | "@eslint/js": "9.11.1", 2474 | "@eslint/plugin-kit": "^0.2.0", 2475 | "@humanwhocodes/module-importer": "^1.0.1", 2476 | "@humanwhocodes/retry": "^0.3.0", 2477 | "@nodelib/fs.walk": "^1.2.8", 2478 | "@types/estree": "^1.0.6", 2479 | "@types/json-schema": "^7.0.15", 2480 | "ajv": "^6.12.4", 2481 | "chalk": "^4.0.0", 2482 | "cross-spawn": "^7.0.2", 2483 | "debug": "^4.3.2", 2484 | "escape-string-regexp": "^4.0.0", 2485 | "eslint-scope": "^8.0.2", 2486 | "eslint-visitor-keys": "^4.0.0", 2487 | "espree": "^10.1.0", 2488 | "esquery": "^1.5.0", 2489 | "esutils": "^2.0.2", 2490 | "fast-deep-equal": "^3.1.3", 2491 | "file-entry-cache": "^8.0.0", 2492 | "find-up": "^5.0.0", 2493 | "glob-parent": "^6.0.2", 2494 | "ignore": "^5.2.0", 2495 | "imurmurhash": "^0.1.4", 2496 | "is-glob": "^4.0.0", 2497 | "is-path-inside": "^3.0.3", 2498 | "json-stable-stringify-without-jsonify": "^1.0.1", 2499 | "lodash.merge": "^4.6.2", 2500 | "minimatch": "^3.1.2", 2501 | "natural-compare": "^1.4.0", 2502 | "optionator": "^0.9.3", 2503 | "strip-ansi": "^6.0.1", 2504 | "text-table": "^0.2.0" 2505 | }, 2506 | "bin": { 2507 | "eslint": "bin/eslint.js" 2508 | }, 2509 | "engines": { 2510 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 2511 | }, 2512 | "funding": { 2513 | "url": "https://eslint.org/donate" 2514 | }, 2515 | "peerDependencies": { 2516 | "jiti": "*" 2517 | }, 2518 | "peerDependenciesMeta": { 2519 | "jiti": { 2520 | "optional": true 2521 | } 2522 | } 2523 | }, 2524 | "node_modules/eslint-plugin-react-hooks": { 2525 | "version": "5.1.0-rc-fb9a90fa48-20240614", 2526 | "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.1.0-rc-fb9a90fa48-20240614.tgz", 2527 | "integrity": "sha512-xsiRwaDNF5wWNC4ZHLut+x/YcAxksUd9Rizt7LaEn3bV8VyYRpXnRJQlLOfYaVy9esk4DFP4zPPnoNVjq5Gc0w==", 2528 | "dev": true, 2529 | "engines": { 2530 | "node": ">=10" 2531 | }, 2532 | "peerDependencies": { 2533 | "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" 2534 | } 2535 | }, 2536 | "node_modules/eslint-plugin-react-refresh": { 2537 | "version": "0.4.12", 2538 | "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.12.tgz", 2539 | "integrity": "sha512-9neVjoGv20FwYtCP6CB1dzR1vr57ZDNOXst21wd2xJ/cTlM2xLq0GWVlSNTdMn/4BtP6cHYBMCSp1wFBJ9jBsg==", 2540 | "dev": true, 2541 | "peerDependencies": { 2542 | "eslint": ">=7" 2543 | } 2544 | }, 2545 | "node_modules/eslint-scope": { 2546 | "version": "8.0.2", 2547 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", 2548 | "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", 2549 | "dev": true, 2550 | "dependencies": { 2551 | "esrecurse": "^4.3.0", 2552 | "estraverse": "^5.2.0" 2553 | }, 2554 | "engines": { 2555 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 2556 | }, 2557 | "funding": { 2558 | "url": "https://opencollective.com/eslint" 2559 | } 2560 | }, 2561 | "node_modules/eslint-visitor-keys": { 2562 | "version": "4.0.0", 2563 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", 2564 | "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", 2565 | "dev": true, 2566 | "engines": { 2567 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 2568 | }, 2569 | "funding": { 2570 | "url": "https://opencollective.com/eslint" 2571 | } 2572 | }, 2573 | "node_modules/eslint/node_modules/ansi-styles": { 2574 | "version": "4.3.0", 2575 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 2576 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 2577 | "dev": true, 2578 | "dependencies": { 2579 | "color-convert": "^2.0.1" 2580 | }, 2581 | "engines": { 2582 | "node": ">=8" 2583 | }, 2584 | "funding": { 2585 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 2586 | } 2587 | }, 2588 | "node_modules/eslint/node_modules/chalk": { 2589 | "version": "4.1.2", 2590 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 2591 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 2592 | "dev": true, 2593 | "dependencies": { 2594 | "ansi-styles": "^4.1.0", 2595 | "supports-color": "^7.1.0" 2596 | }, 2597 | "engines": { 2598 | "node": ">=10" 2599 | }, 2600 | "funding": { 2601 | "url": "https://github.com/chalk/chalk?sponsor=1" 2602 | } 2603 | }, 2604 | "node_modules/eslint/node_modules/color-convert": { 2605 | "version": "2.0.1", 2606 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 2607 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 2608 | "dev": true, 2609 | "dependencies": { 2610 | "color-name": "~1.1.4" 2611 | }, 2612 | "engines": { 2613 | "node": ">=7.0.0" 2614 | } 2615 | }, 2616 | "node_modules/eslint/node_modules/color-name": { 2617 | "version": "1.1.4", 2618 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 2619 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 2620 | "dev": true 2621 | }, 2622 | "node_modules/eslint/node_modules/has-flag": { 2623 | "version": "4.0.0", 2624 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 2625 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 2626 | "dev": true, 2627 | "engines": { 2628 | "node": ">=8" 2629 | } 2630 | }, 2631 | "node_modules/eslint/node_modules/supports-color": { 2632 | "version": "7.2.0", 2633 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 2634 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 2635 | "dev": true, 2636 | "dependencies": { 2637 | "has-flag": "^4.0.0" 2638 | }, 2639 | "engines": { 2640 | "node": ">=8" 2641 | } 2642 | }, 2643 | "node_modules/espree": { 2644 | "version": "10.1.0", 2645 | "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", 2646 | "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", 2647 | "dev": true, 2648 | "dependencies": { 2649 | "acorn": "^8.12.0", 2650 | "acorn-jsx": "^5.3.2", 2651 | "eslint-visitor-keys": "^4.0.0" 2652 | }, 2653 | "engines": { 2654 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 2655 | }, 2656 | "funding": { 2657 | "url": "https://opencollective.com/eslint" 2658 | } 2659 | }, 2660 | "node_modules/esquery": { 2661 | "version": "1.6.0", 2662 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", 2663 | "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", 2664 | "dev": true, 2665 | "dependencies": { 2666 | "estraverse": "^5.1.0" 2667 | }, 2668 | "engines": { 2669 | "node": ">=0.10" 2670 | } 2671 | }, 2672 | "node_modules/esrecurse": { 2673 | "version": "4.3.0", 2674 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 2675 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 2676 | "dev": true, 2677 | "dependencies": { 2678 | "estraverse": "^5.2.0" 2679 | }, 2680 | "engines": { 2681 | "node": ">=4.0" 2682 | } 2683 | }, 2684 | "node_modules/estraverse": { 2685 | "version": "5.3.0", 2686 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 2687 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 2688 | "dev": true, 2689 | "engines": { 2690 | "node": ">=4.0" 2691 | } 2692 | }, 2693 | "node_modules/esutils": { 2694 | "version": "2.0.3", 2695 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 2696 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 2697 | "dev": true, 2698 | "engines": { 2699 | "node": ">=0.10.0" 2700 | } 2701 | }, 2702 | "node_modules/fast-deep-equal": { 2703 | "version": "3.1.3", 2704 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 2705 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 2706 | "dev": true 2707 | }, 2708 | "node_modules/fast-glob": { 2709 | "version": "3.3.2", 2710 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", 2711 | "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", 2712 | "dev": true, 2713 | "dependencies": { 2714 | "@nodelib/fs.stat": "^2.0.2", 2715 | "@nodelib/fs.walk": "^1.2.3", 2716 | "glob-parent": "^5.1.2", 2717 | "merge2": "^1.3.0", 2718 | "micromatch": "^4.0.4" 2719 | }, 2720 | "engines": { 2721 | "node": ">=8.6.0" 2722 | } 2723 | }, 2724 | "node_modules/fast-glob/node_modules/glob-parent": { 2725 | "version": "5.1.2", 2726 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 2727 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 2728 | "dev": true, 2729 | "dependencies": { 2730 | "is-glob": "^4.0.1" 2731 | }, 2732 | "engines": { 2733 | "node": ">= 6" 2734 | } 2735 | }, 2736 | "node_modules/fast-json-stable-stringify": { 2737 | "version": "2.1.0", 2738 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 2739 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 2740 | "dev": true 2741 | }, 2742 | "node_modules/fast-levenshtein": { 2743 | "version": "2.0.6", 2744 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 2745 | "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", 2746 | "dev": true 2747 | }, 2748 | "node_modules/fastq": { 2749 | "version": "1.17.1", 2750 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", 2751 | "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", 2752 | "dev": true, 2753 | "dependencies": { 2754 | "reusify": "^1.0.4" 2755 | } 2756 | }, 2757 | "node_modules/file-entry-cache": { 2758 | "version": "8.0.0", 2759 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", 2760 | "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", 2761 | "dev": true, 2762 | "dependencies": { 2763 | "flat-cache": "^4.0.0" 2764 | }, 2765 | "engines": { 2766 | "node": ">=16.0.0" 2767 | } 2768 | }, 2769 | "node_modules/file-selector": { 2770 | "version": "0.6.0", 2771 | "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.6.0.tgz", 2772 | "integrity": "sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==", 2773 | "dependencies": { 2774 | "tslib": "^2.4.0" 2775 | }, 2776 | "engines": { 2777 | "node": ">= 12" 2778 | } 2779 | }, 2780 | "node_modules/fill-range": { 2781 | "version": "7.1.1", 2782 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", 2783 | "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", 2784 | "dev": true, 2785 | "dependencies": { 2786 | "to-regex-range": "^5.0.1" 2787 | }, 2788 | "engines": { 2789 | "node": ">=8" 2790 | } 2791 | }, 2792 | "node_modules/find-root": { 2793 | "version": "1.1.0", 2794 | "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", 2795 | "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" 2796 | }, 2797 | "node_modules/find-up": { 2798 | "version": "5.0.0", 2799 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 2800 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 2801 | "dev": true, 2802 | "dependencies": { 2803 | "locate-path": "^6.0.0", 2804 | "path-exists": "^4.0.0" 2805 | }, 2806 | "engines": { 2807 | "node": ">=10" 2808 | }, 2809 | "funding": { 2810 | "url": "https://github.com/sponsors/sindresorhus" 2811 | } 2812 | }, 2813 | "node_modules/flat-cache": { 2814 | "version": "4.0.1", 2815 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", 2816 | "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", 2817 | "dev": true, 2818 | "dependencies": { 2819 | "flatted": "^3.2.9", 2820 | "keyv": "^4.5.4" 2821 | }, 2822 | "engines": { 2823 | "node": ">=16" 2824 | } 2825 | }, 2826 | "node_modules/flatted": { 2827 | "version": "3.3.1", 2828 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", 2829 | "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", 2830 | "dev": true 2831 | }, 2832 | "node_modules/follow-redirects": { 2833 | "version": "1.15.9", 2834 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", 2835 | "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", 2836 | "funding": [ 2837 | { 2838 | "type": "individual", 2839 | "url": "https://github.com/sponsors/RubenVerborgh" 2840 | } 2841 | ], 2842 | "engines": { 2843 | "node": ">=4.0" 2844 | }, 2845 | "peerDependenciesMeta": { 2846 | "debug": { 2847 | "optional": true 2848 | } 2849 | } 2850 | }, 2851 | "node_modules/form-data": { 2852 | "version": "4.0.0", 2853 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", 2854 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", 2855 | "dependencies": { 2856 | "asynckit": "^0.4.0", 2857 | "combined-stream": "^1.0.8", 2858 | "mime-types": "^2.1.12" 2859 | }, 2860 | "engines": { 2861 | "node": ">= 6" 2862 | } 2863 | }, 2864 | "node_modules/fsevents": { 2865 | "version": "2.3.3", 2866 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 2867 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 2868 | "dev": true, 2869 | "hasInstallScript": true, 2870 | "optional": true, 2871 | "os": [ 2872 | "darwin" 2873 | ], 2874 | "engines": { 2875 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 2876 | } 2877 | }, 2878 | "node_modules/function-bind": { 2879 | "version": "1.1.2", 2880 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 2881 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 2882 | "funding": { 2883 | "url": "https://github.com/sponsors/ljharb" 2884 | } 2885 | }, 2886 | "node_modules/glob-parent": { 2887 | "version": "6.0.2", 2888 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", 2889 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", 2890 | "dev": true, 2891 | "dependencies": { 2892 | "is-glob": "^4.0.3" 2893 | }, 2894 | "engines": { 2895 | "node": ">=10.13.0" 2896 | } 2897 | }, 2898 | "node_modules/globals": { 2899 | "version": "15.9.0", 2900 | "resolved": "https://registry.npmjs.org/globals/-/globals-15.9.0.tgz", 2901 | "integrity": "sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==", 2902 | "dev": true, 2903 | "engines": { 2904 | "node": ">=18" 2905 | }, 2906 | "funding": { 2907 | "url": "https://github.com/sponsors/sindresorhus" 2908 | } 2909 | }, 2910 | "node_modules/graphemer": { 2911 | "version": "1.4.0", 2912 | "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", 2913 | "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", 2914 | "dev": true 2915 | }, 2916 | "node_modules/has-flag": { 2917 | "version": "3.0.0", 2918 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 2919 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", 2920 | "engines": { 2921 | "node": ">=4" 2922 | } 2923 | }, 2924 | "node_modules/hasown": { 2925 | "version": "2.0.2", 2926 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 2927 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 2928 | "dependencies": { 2929 | "function-bind": "^1.1.2" 2930 | }, 2931 | "engines": { 2932 | "node": ">= 0.4" 2933 | } 2934 | }, 2935 | "node_modules/hoist-non-react-statics": { 2936 | "version": "3.3.2", 2937 | "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", 2938 | "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", 2939 | "dependencies": { 2940 | "react-is": "^16.7.0" 2941 | } 2942 | }, 2943 | "node_modules/hoist-non-react-statics/node_modules/react-is": { 2944 | "version": "16.13.1", 2945 | "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", 2946 | "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" 2947 | }, 2948 | "node_modules/ignore": { 2949 | "version": "5.3.2", 2950 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", 2951 | "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", 2952 | "dev": true, 2953 | "engines": { 2954 | "node": ">= 4" 2955 | } 2956 | }, 2957 | "node_modules/import-fresh": { 2958 | "version": "3.3.0", 2959 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", 2960 | "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", 2961 | "dependencies": { 2962 | "parent-module": "^1.0.0", 2963 | "resolve-from": "^4.0.0" 2964 | }, 2965 | "engines": { 2966 | "node": ">=6" 2967 | }, 2968 | "funding": { 2969 | "url": "https://github.com/sponsors/sindresorhus" 2970 | } 2971 | }, 2972 | "node_modules/imurmurhash": { 2973 | "version": "0.1.4", 2974 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 2975 | "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", 2976 | "dev": true, 2977 | "engines": { 2978 | "node": ">=0.8.19" 2979 | } 2980 | }, 2981 | "node_modules/inherits": { 2982 | "version": "2.0.3", 2983 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 2984 | "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", 2985 | "dev": true 2986 | }, 2987 | "node_modules/is-arrayish": { 2988 | "version": "0.2.1", 2989 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", 2990 | "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" 2991 | }, 2992 | "node_modules/is-core-module": { 2993 | "version": "2.15.1", 2994 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", 2995 | "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", 2996 | "dependencies": { 2997 | "hasown": "^2.0.2" 2998 | }, 2999 | "engines": { 3000 | "node": ">= 0.4" 3001 | }, 3002 | "funding": { 3003 | "url": "https://github.com/sponsors/ljharb" 3004 | } 3005 | }, 3006 | "node_modules/is-extglob": { 3007 | "version": "2.1.1", 3008 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 3009 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 3010 | "dev": true, 3011 | "engines": { 3012 | "node": ">=0.10.0" 3013 | } 3014 | }, 3015 | "node_modules/is-glob": { 3016 | "version": "4.0.3", 3017 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 3018 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 3019 | "dev": true, 3020 | "dependencies": { 3021 | "is-extglob": "^2.1.1" 3022 | }, 3023 | "engines": { 3024 | "node": ">=0.10.0" 3025 | } 3026 | }, 3027 | "node_modules/is-number": { 3028 | "version": "7.0.0", 3029 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 3030 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 3031 | "dev": true, 3032 | "engines": { 3033 | "node": ">=0.12.0" 3034 | } 3035 | }, 3036 | "node_modules/is-path-inside": { 3037 | "version": "3.0.3", 3038 | "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", 3039 | "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", 3040 | "dev": true, 3041 | "engines": { 3042 | "node": ">=8" 3043 | } 3044 | }, 3045 | "node_modules/isexe": { 3046 | "version": "2.0.0", 3047 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 3048 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 3049 | "dev": true 3050 | }, 3051 | "node_modules/js-tokens": { 3052 | "version": "4.0.0", 3053 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 3054 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" 3055 | }, 3056 | "node_modules/js-yaml": { 3057 | "version": "4.1.0", 3058 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 3059 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 3060 | "dev": true, 3061 | "dependencies": { 3062 | "argparse": "^2.0.1" 3063 | }, 3064 | "bin": { 3065 | "js-yaml": "bin/js-yaml.js" 3066 | } 3067 | }, 3068 | "node_modules/jsesc": { 3069 | "version": "2.5.2", 3070 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", 3071 | "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", 3072 | "bin": { 3073 | "jsesc": "bin/jsesc" 3074 | }, 3075 | "engines": { 3076 | "node": ">=4" 3077 | } 3078 | }, 3079 | "node_modules/json-buffer": { 3080 | "version": "3.0.1", 3081 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", 3082 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", 3083 | "dev": true 3084 | }, 3085 | "node_modules/json-parse-even-better-errors": { 3086 | "version": "2.3.1", 3087 | "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", 3088 | "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" 3089 | }, 3090 | "node_modules/json-schema-traverse": { 3091 | "version": "0.4.1", 3092 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 3093 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 3094 | "dev": true 3095 | }, 3096 | "node_modules/json-stable-stringify-without-jsonify": { 3097 | "version": "1.0.1", 3098 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 3099 | "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", 3100 | "dev": true 3101 | }, 3102 | "node_modules/keyv": { 3103 | "version": "4.5.4", 3104 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", 3105 | "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", 3106 | "dev": true, 3107 | "dependencies": { 3108 | "json-buffer": "3.0.1" 3109 | } 3110 | }, 3111 | "node_modules/levn": { 3112 | "version": "0.4.1", 3113 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 3114 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 3115 | "dev": true, 3116 | "dependencies": { 3117 | "prelude-ls": "^1.2.1", 3118 | "type-check": "~0.4.0" 3119 | }, 3120 | "engines": { 3121 | "node": ">= 0.8.0" 3122 | } 3123 | }, 3124 | "node_modules/lines-and-columns": { 3125 | "version": "1.2.4", 3126 | "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", 3127 | "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" 3128 | }, 3129 | "node_modules/locate-path": { 3130 | "version": "6.0.0", 3131 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 3132 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 3133 | "dev": true, 3134 | "dependencies": { 3135 | "p-locate": "^5.0.0" 3136 | }, 3137 | "engines": { 3138 | "node": ">=10" 3139 | }, 3140 | "funding": { 3141 | "url": "https://github.com/sponsors/sindresorhus" 3142 | } 3143 | }, 3144 | "node_modules/lodash.merge": { 3145 | "version": "4.6.2", 3146 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", 3147 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", 3148 | "dev": true 3149 | }, 3150 | "node_modules/loose-envify": { 3151 | "version": "1.4.0", 3152 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", 3153 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", 3154 | "dependencies": { 3155 | "js-tokens": "^3.0.0 || ^4.0.0" 3156 | }, 3157 | "bin": { 3158 | "loose-envify": "cli.js" 3159 | } 3160 | }, 3161 | "node_modules/merge2": { 3162 | "version": "1.4.1", 3163 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", 3164 | "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", 3165 | "dev": true, 3166 | "engines": { 3167 | "node": ">= 8" 3168 | } 3169 | }, 3170 | "node_modules/micromatch": { 3171 | "version": "4.0.8", 3172 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", 3173 | "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", 3174 | "dev": true, 3175 | "dependencies": { 3176 | "braces": "^3.0.3", 3177 | "picomatch": "^2.3.1" 3178 | }, 3179 | "engines": { 3180 | "node": ">=8.6" 3181 | } 3182 | }, 3183 | "node_modules/mime-db": { 3184 | "version": "1.52.0", 3185 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 3186 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 3187 | "engines": { 3188 | "node": ">= 0.6" 3189 | } 3190 | }, 3191 | "node_modules/mime-types": { 3192 | "version": "2.1.35", 3193 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 3194 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 3195 | "dependencies": { 3196 | "mime-db": "1.52.0" 3197 | }, 3198 | "engines": { 3199 | "node": ">= 0.6" 3200 | } 3201 | }, 3202 | "node_modules/minimatch": { 3203 | "version": "3.1.2", 3204 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 3205 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 3206 | "dev": true, 3207 | "dependencies": { 3208 | "brace-expansion": "^1.1.7" 3209 | }, 3210 | "engines": { 3211 | "node": "*" 3212 | } 3213 | }, 3214 | "node_modules/ms": { 3215 | "version": "2.1.3", 3216 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 3217 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 3218 | }, 3219 | "node_modules/nanoid": { 3220 | "version": "3.3.7", 3221 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", 3222 | "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", 3223 | "dev": true, 3224 | "funding": [ 3225 | { 3226 | "type": "github", 3227 | "url": "https://github.com/sponsors/ai" 3228 | } 3229 | ], 3230 | "bin": { 3231 | "nanoid": "bin/nanoid.cjs" 3232 | }, 3233 | "engines": { 3234 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 3235 | } 3236 | }, 3237 | "node_modules/natural-compare": { 3238 | "version": "1.4.0", 3239 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 3240 | "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", 3241 | "dev": true 3242 | }, 3243 | "node_modules/object-assign": { 3244 | "version": "4.1.1", 3245 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 3246 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 3247 | "engines": { 3248 | "node": ">=0.10.0" 3249 | } 3250 | }, 3251 | "node_modules/optionator": { 3252 | "version": "0.9.4", 3253 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", 3254 | "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", 3255 | "dev": true, 3256 | "dependencies": { 3257 | "deep-is": "^0.1.3", 3258 | "fast-levenshtein": "^2.0.6", 3259 | "levn": "^0.4.1", 3260 | "prelude-ls": "^1.2.1", 3261 | "type-check": "^0.4.0", 3262 | "word-wrap": "^1.2.5" 3263 | }, 3264 | "engines": { 3265 | "node": ">= 0.8.0" 3266 | } 3267 | }, 3268 | "node_modules/p-limit": { 3269 | "version": "3.1.0", 3270 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 3271 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 3272 | "dev": true, 3273 | "dependencies": { 3274 | "yocto-queue": "^0.1.0" 3275 | }, 3276 | "engines": { 3277 | "node": ">=10" 3278 | }, 3279 | "funding": { 3280 | "url": "https://github.com/sponsors/sindresorhus" 3281 | } 3282 | }, 3283 | "node_modules/p-locate": { 3284 | "version": "5.0.0", 3285 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 3286 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 3287 | "dev": true, 3288 | "dependencies": { 3289 | "p-limit": "^3.0.2" 3290 | }, 3291 | "engines": { 3292 | "node": ">=10" 3293 | }, 3294 | "funding": { 3295 | "url": "https://github.com/sponsors/sindresorhus" 3296 | } 3297 | }, 3298 | "node_modules/parent-module": { 3299 | "version": "1.0.1", 3300 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 3301 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 3302 | "dependencies": { 3303 | "callsites": "^3.0.0" 3304 | }, 3305 | "engines": { 3306 | "node": ">=6" 3307 | } 3308 | }, 3309 | "node_modules/parse-json": { 3310 | "version": "5.2.0", 3311 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", 3312 | "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", 3313 | "dependencies": { 3314 | "@babel/code-frame": "^7.0.0", 3315 | "error-ex": "^1.3.1", 3316 | "json-parse-even-better-errors": "^2.3.0", 3317 | "lines-and-columns": "^1.1.6" 3318 | }, 3319 | "engines": { 3320 | "node": ">=8" 3321 | }, 3322 | "funding": { 3323 | "url": "https://github.com/sponsors/sindresorhus" 3324 | } 3325 | }, 3326 | "node_modules/path": { 3327 | "version": "0.12.7", 3328 | "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", 3329 | "integrity": "sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==", 3330 | "dev": true, 3331 | "dependencies": { 3332 | "process": "^0.11.1", 3333 | "util": "^0.10.3" 3334 | } 3335 | }, 3336 | "node_modules/path-exists": { 3337 | "version": "4.0.0", 3338 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 3339 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 3340 | "dev": true, 3341 | "engines": { 3342 | "node": ">=8" 3343 | } 3344 | }, 3345 | "node_modules/path-key": { 3346 | "version": "3.1.1", 3347 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 3348 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 3349 | "dev": true, 3350 | "engines": { 3351 | "node": ">=8" 3352 | } 3353 | }, 3354 | "node_modules/path-parse": { 3355 | "version": "1.0.7", 3356 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 3357 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" 3358 | }, 3359 | "node_modules/path-type": { 3360 | "version": "4.0.0", 3361 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", 3362 | "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", 3363 | "engines": { 3364 | "node": ">=8" 3365 | } 3366 | }, 3367 | "node_modules/picocolors": { 3368 | "version": "1.1.0", 3369 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", 3370 | "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==" 3371 | }, 3372 | "node_modules/picomatch": { 3373 | "version": "2.3.1", 3374 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 3375 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 3376 | "dev": true, 3377 | "engines": { 3378 | "node": ">=8.6" 3379 | }, 3380 | "funding": { 3381 | "url": "https://github.com/sponsors/jonschlinkert" 3382 | } 3383 | }, 3384 | "node_modules/postcss": { 3385 | "version": "8.4.47", 3386 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", 3387 | "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", 3388 | "dev": true, 3389 | "funding": [ 3390 | { 3391 | "type": "opencollective", 3392 | "url": "https://opencollective.com/postcss/" 3393 | }, 3394 | { 3395 | "type": "tidelift", 3396 | "url": "https://tidelift.com/funding/github/npm/postcss" 3397 | }, 3398 | { 3399 | "type": "github", 3400 | "url": "https://github.com/sponsors/ai" 3401 | } 3402 | ], 3403 | "dependencies": { 3404 | "nanoid": "^3.3.7", 3405 | "picocolors": "^1.1.0", 3406 | "source-map-js": "^1.2.1" 3407 | }, 3408 | "engines": { 3409 | "node": "^10 || ^12 || >=14" 3410 | } 3411 | }, 3412 | "node_modules/prelude-ls": { 3413 | "version": "1.2.1", 3414 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 3415 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 3416 | "dev": true, 3417 | "engines": { 3418 | "node": ">= 0.8.0" 3419 | } 3420 | }, 3421 | "node_modules/process": { 3422 | "version": "0.11.10", 3423 | "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", 3424 | "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", 3425 | "dev": true, 3426 | "engines": { 3427 | "node": ">= 0.6.0" 3428 | } 3429 | }, 3430 | "node_modules/prop-types": { 3431 | "version": "15.8.1", 3432 | "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", 3433 | "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", 3434 | "dependencies": { 3435 | "loose-envify": "^1.4.0", 3436 | "object-assign": "^4.1.1", 3437 | "react-is": "^16.13.1" 3438 | } 3439 | }, 3440 | "node_modules/prop-types/node_modules/react-is": { 3441 | "version": "16.13.1", 3442 | "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", 3443 | "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" 3444 | }, 3445 | "node_modules/proxy-from-env": { 3446 | "version": "1.1.0", 3447 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", 3448 | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" 3449 | }, 3450 | "node_modules/punycode": { 3451 | "version": "2.3.1", 3452 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 3453 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 3454 | "dev": true, 3455 | "engines": { 3456 | "node": ">=6" 3457 | } 3458 | }, 3459 | "node_modules/queue-microtask": { 3460 | "version": "1.2.3", 3461 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 3462 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 3463 | "dev": true, 3464 | "funding": [ 3465 | { 3466 | "type": "github", 3467 | "url": "https://github.com/sponsors/feross" 3468 | }, 3469 | { 3470 | "type": "patreon", 3471 | "url": "https://www.patreon.com/feross" 3472 | }, 3473 | { 3474 | "type": "consulting", 3475 | "url": "https://feross.org/support" 3476 | } 3477 | ] 3478 | }, 3479 | "node_modules/react": { 3480 | "version": "18.3.1", 3481 | "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", 3482 | "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", 3483 | "dependencies": { 3484 | "loose-envify": "^1.1.0" 3485 | }, 3486 | "engines": { 3487 | "node": ">=0.10.0" 3488 | } 3489 | }, 3490 | "node_modules/react-dom": { 3491 | "version": "18.3.1", 3492 | "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", 3493 | "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", 3494 | "dependencies": { 3495 | "loose-envify": "^1.1.0", 3496 | "scheduler": "^0.23.2" 3497 | }, 3498 | "peerDependencies": { 3499 | "react": "^18.3.1" 3500 | } 3501 | }, 3502 | "node_modules/react-dropzone": { 3503 | "version": "14.2.3", 3504 | "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.2.3.tgz", 3505 | "integrity": "sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==", 3506 | "dependencies": { 3507 | "attr-accept": "^2.2.2", 3508 | "file-selector": "^0.6.0", 3509 | "prop-types": "^15.8.1" 3510 | }, 3511 | "engines": { 3512 | "node": ">= 10.13" 3513 | }, 3514 | "peerDependencies": { 3515 | "react": ">= 16.8 || 18.0.0" 3516 | } 3517 | }, 3518 | "node_modules/react-is": { 3519 | "version": "18.3.1", 3520 | "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", 3521 | "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" 3522 | }, 3523 | "node_modules/react-transition-group": { 3524 | "version": "4.4.5", 3525 | "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", 3526 | "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", 3527 | "dependencies": { 3528 | "@babel/runtime": "^7.5.5", 3529 | "dom-helpers": "^5.0.1", 3530 | "loose-envify": "^1.4.0", 3531 | "prop-types": "^15.6.2" 3532 | }, 3533 | "peerDependencies": { 3534 | "react": ">=16.6.0", 3535 | "react-dom": ">=16.6.0" 3536 | } 3537 | }, 3538 | "node_modules/regenerator-runtime": { 3539 | "version": "0.14.1", 3540 | "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", 3541 | "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" 3542 | }, 3543 | "node_modules/reselect": { 3544 | "version": "5.1.1", 3545 | "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", 3546 | "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==" 3547 | }, 3548 | "node_modules/resolve": { 3549 | "version": "1.22.8", 3550 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", 3551 | "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", 3552 | "dependencies": { 3553 | "is-core-module": "^2.13.0", 3554 | "path-parse": "^1.0.7", 3555 | "supports-preserve-symlinks-flag": "^1.0.0" 3556 | }, 3557 | "bin": { 3558 | "resolve": "bin/resolve" 3559 | }, 3560 | "funding": { 3561 | "url": "https://github.com/sponsors/ljharb" 3562 | } 3563 | }, 3564 | "node_modules/resolve-from": { 3565 | "version": "4.0.0", 3566 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 3567 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 3568 | "engines": { 3569 | "node": ">=4" 3570 | } 3571 | }, 3572 | "node_modules/reusify": { 3573 | "version": "1.0.4", 3574 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", 3575 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", 3576 | "dev": true, 3577 | "engines": { 3578 | "iojs": ">=1.0.0", 3579 | "node": ">=0.10.0" 3580 | } 3581 | }, 3582 | "node_modules/rollup": { 3583 | "version": "4.22.5", 3584 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.5.tgz", 3585 | "integrity": "sha512-WoinX7GeQOFMGznEcWA1WrTQCd/tpEbMkc3nuMs9BT0CPjMdSjPMTVClwWd4pgSQwJdP65SK9mTCNvItlr5o7w==", 3586 | "dev": true, 3587 | "dependencies": { 3588 | "@types/estree": "1.0.6" 3589 | }, 3590 | "bin": { 3591 | "rollup": "dist/bin/rollup" 3592 | }, 3593 | "engines": { 3594 | "node": ">=18.0.0", 3595 | "npm": ">=8.0.0" 3596 | }, 3597 | "optionalDependencies": { 3598 | "@rollup/rollup-android-arm-eabi": "4.22.5", 3599 | "@rollup/rollup-android-arm64": "4.22.5", 3600 | "@rollup/rollup-darwin-arm64": "4.22.5", 3601 | "@rollup/rollup-darwin-x64": "4.22.5", 3602 | "@rollup/rollup-linux-arm-gnueabihf": "4.22.5", 3603 | "@rollup/rollup-linux-arm-musleabihf": "4.22.5", 3604 | "@rollup/rollup-linux-arm64-gnu": "4.22.5", 3605 | "@rollup/rollup-linux-arm64-musl": "4.22.5", 3606 | "@rollup/rollup-linux-powerpc64le-gnu": "4.22.5", 3607 | "@rollup/rollup-linux-riscv64-gnu": "4.22.5", 3608 | "@rollup/rollup-linux-s390x-gnu": "4.22.5", 3609 | "@rollup/rollup-linux-x64-gnu": "4.22.5", 3610 | "@rollup/rollup-linux-x64-musl": "4.22.5", 3611 | "@rollup/rollup-win32-arm64-msvc": "4.22.5", 3612 | "@rollup/rollup-win32-ia32-msvc": "4.22.5", 3613 | "@rollup/rollup-win32-x64-msvc": "4.22.5", 3614 | "fsevents": "~2.3.2" 3615 | } 3616 | }, 3617 | "node_modules/run-parallel": { 3618 | "version": "1.2.0", 3619 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 3620 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 3621 | "dev": true, 3622 | "funding": [ 3623 | { 3624 | "type": "github", 3625 | "url": "https://github.com/sponsors/feross" 3626 | }, 3627 | { 3628 | "type": "patreon", 3629 | "url": "https://www.patreon.com/feross" 3630 | }, 3631 | { 3632 | "type": "consulting", 3633 | "url": "https://feross.org/support" 3634 | } 3635 | ], 3636 | "dependencies": { 3637 | "queue-microtask": "^1.2.2" 3638 | } 3639 | }, 3640 | "node_modules/scheduler": { 3641 | "version": "0.23.2", 3642 | "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", 3643 | "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", 3644 | "dependencies": { 3645 | "loose-envify": "^1.1.0" 3646 | } 3647 | }, 3648 | "node_modules/semver": { 3649 | "version": "7.6.3", 3650 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", 3651 | "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", 3652 | "dev": true, 3653 | "bin": { 3654 | "semver": "bin/semver.js" 3655 | }, 3656 | "engines": { 3657 | "node": ">=10" 3658 | } 3659 | }, 3660 | "node_modules/shebang-command": { 3661 | "version": "2.0.0", 3662 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 3663 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 3664 | "dev": true, 3665 | "dependencies": { 3666 | "shebang-regex": "^3.0.0" 3667 | }, 3668 | "engines": { 3669 | "node": ">=8" 3670 | } 3671 | }, 3672 | "node_modules/shebang-regex": { 3673 | "version": "3.0.0", 3674 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 3675 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 3676 | "dev": true, 3677 | "engines": { 3678 | "node": ">=8" 3679 | } 3680 | }, 3681 | "node_modules/source-map": { 3682 | "version": "0.5.7", 3683 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", 3684 | "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", 3685 | "engines": { 3686 | "node": ">=0.10.0" 3687 | } 3688 | }, 3689 | "node_modules/source-map-js": { 3690 | "version": "1.2.1", 3691 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", 3692 | "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", 3693 | "dev": true, 3694 | "engines": { 3695 | "node": ">=0.10.0" 3696 | } 3697 | }, 3698 | "node_modules/strip-ansi": { 3699 | "version": "6.0.1", 3700 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 3701 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 3702 | "dev": true, 3703 | "dependencies": { 3704 | "ansi-regex": "^5.0.1" 3705 | }, 3706 | "engines": { 3707 | "node": ">=8" 3708 | } 3709 | }, 3710 | "node_modules/strip-json-comments": { 3711 | "version": "3.1.1", 3712 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 3713 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 3714 | "dev": true, 3715 | "engines": { 3716 | "node": ">=8" 3717 | }, 3718 | "funding": { 3719 | "url": "https://github.com/sponsors/sindresorhus" 3720 | } 3721 | }, 3722 | "node_modules/stylis": { 3723 | "version": "4.2.0", 3724 | "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", 3725 | "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" 3726 | }, 3727 | "node_modules/supports-color": { 3728 | "version": "5.5.0", 3729 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 3730 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 3731 | "dependencies": { 3732 | "has-flag": "^3.0.0" 3733 | }, 3734 | "engines": { 3735 | "node": ">=4" 3736 | } 3737 | }, 3738 | "node_modules/supports-preserve-symlinks-flag": { 3739 | "version": "1.0.0", 3740 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 3741 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 3742 | "engines": { 3743 | "node": ">= 0.4" 3744 | }, 3745 | "funding": { 3746 | "url": "https://github.com/sponsors/ljharb" 3747 | } 3748 | }, 3749 | "node_modules/text-table": { 3750 | "version": "0.2.0", 3751 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 3752 | "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", 3753 | "dev": true 3754 | }, 3755 | "node_modules/to-fast-properties": { 3756 | "version": "2.0.0", 3757 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", 3758 | "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", 3759 | "engines": { 3760 | "node": ">=4" 3761 | } 3762 | }, 3763 | "node_modules/to-regex-range": { 3764 | "version": "5.0.1", 3765 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 3766 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 3767 | "dev": true, 3768 | "dependencies": { 3769 | "is-number": "^7.0.0" 3770 | }, 3771 | "engines": { 3772 | "node": ">=8.0" 3773 | } 3774 | }, 3775 | "node_modules/ts-api-utils": { 3776 | "version": "1.3.0", 3777 | "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", 3778 | "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", 3779 | "dev": true, 3780 | "engines": { 3781 | "node": ">=16" 3782 | }, 3783 | "peerDependencies": { 3784 | "typescript": ">=4.2.0" 3785 | } 3786 | }, 3787 | "node_modules/tslib": { 3788 | "version": "2.7.0", 3789 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", 3790 | "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" 3791 | }, 3792 | "node_modules/type-check": { 3793 | "version": "0.4.0", 3794 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 3795 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 3796 | "dev": true, 3797 | "dependencies": { 3798 | "prelude-ls": "^1.2.1" 3799 | }, 3800 | "engines": { 3801 | "node": ">= 0.8.0" 3802 | } 3803 | }, 3804 | "node_modules/typescript": { 3805 | "version": "5.6.2", 3806 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", 3807 | "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", 3808 | "dev": true, 3809 | "bin": { 3810 | "tsc": "bin/tsc", 3811 | "tsserver": "bin/tsserver" 3812 | }, 3813 | "engines": { 3814 | "node": ">=14.17" 3815 | } 3816 | }, 3817 | "node_modules/typescript-eslint": { 3818 | "version": "8.7.0", 3819 | "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.7.0.tgz", 3820 | "integrity": "sha512-nEHbEYJyHwsuf7c3V3RS7Saq+1+la3i0ieR3qP0yjqWSzVmh8Drp47uOl9LjbPANac4S7EFSqvcYIKXUUwIfIQ==", 3821 | "dev": true, 3822 | "dependencies": { 3823 | "@typescript-eslint/eslint-plugin": "8.7.0", 3824 | "@typescript-eslint/parser": "8.7.0", 3825 | "@typescript-eslint/utils": "8.7.0" 3826 | }, 3827 | "engines": { 3828 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 3829 | }, 3830 | "funding": { 3831 | "type": "opencollective", 3832 | "url": "https://opencollective.com/typescript-eslint" 3833 | }, 3834 | "peerDependenciesMeta": { 3835 | "typescript": { 3836 | "optional": true 3837 | } 3838 | } 3839 | }, 3840 | "node_modules/undici-types": { 3841 | "version": "6.19.8", 3842 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", 3843 | "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", 3844 | "dev": true 3845 | }, 3846 | "node_modules/uri-js": { 3847 | "version": "4.4.1", 3848 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 3849 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 3850 | "dev": true, 3851 | "dependencies": { 3852 | "punycode": "^2.1.0" 3853 | } 3854 | }, 3855 | "node_modules/util": { 3856 | "version": "0.10.4", 3857 | "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", 3858 | "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", 3859 | "dev": true, 3860 | "dependencies": { 3861 | "inherits": "2.0.3" 3862 | } 3863 | }, 3864 | "node_modules/vite": { 3865 | "version": "5.4.8", 3866 | "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz", 3867 | "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==", 3868 | "dev": true, 3869 | "dependencies": { 3870 | "esbuild": "^0.21.3", 3871 | "postcss": "^8.4.43", 3872 | "rollup": "^4.20.0" 3873 | }, 3874 | "bin": { 3875 | "vite": "bin/vite.js" 3876 | }, 3877 | "engines": { 3878 | "node": "^18.0.0 || >=20.0.0" 3879 | }, 3880 | "funding": { 3881 | "url": "https://github.com/vitejs/vite?sponsor=1" 3882 | }, 3883 | "optionalDependencies": { 3884 | "fsevents": "~2.3.3" 3885 | }, 3886 | "peerDependencies": { 3887 | "@types/node": "^18.0.0 || >=20.0.0", 3888 | "less": "*", 3889 | "lightningcss": "^1.21.0", 3890 | "sass": "*", 3891 | "sass-embedded": "*", 3892 | "stylus": "*", 3893 | "sugarss": "*", 3894 | "terser": "^5.4.0" 3895 | }, 3896 | "peerDependenciesMeta": { 3897 | "@types/node": { 3898 | "optional": true 3899 | }, 3900 | "less": { 3901 | "optional": true 3902 | }, 3903 | "lightningcss": { 3904 | "optional": true 3905 | }, 3906 | "sass": { 3907 | "optional": true 3908 | }, 3909 | "sass-embedded": { 3910 | "optional": true 3911 | }, 3912 | "stylus": { 3913 | "optional": true 3914 | }, 3915 | "sugarss": { 3916 | "optional": true 3917 | }, 3918 | "terser": { 3919 | "optional": true 3920 | } 3921 | } 3922 | }, 3923 | "node_modules/which": { 3924 | "version": "2.0.2", 3925 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 3926 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 3927 | "dev": true, 3928 | "dependencies": { 3929 | "isexe": "^2.0.0" 3930 | }, 3931 | "bin": { 3932 | "node-which": "bin/node-which" 3933 | }, 3934 | "engines": { 3935 | "node": ">= 8" 3936 | } 3937 | }, 3938 | "node_modules/word-wrap": { 3939 | "version": "1.2.5", 3940 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", 3941 | "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", 3942 | "dev": true, 3943 | "engines": { 3944 | "node": ">=0.10.0" 3945 | } 3946 | }, 3947 | "node_modules/yaml": { 3948 | "version": "1.10.2", 3949 | "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", 3950 | "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", 3951 | "engines": { 3952 | "node": ">= 6" 3953 | } 3954 | }, 3955 | "node_modules/yocto-queue": { 3956 | "version": "0.1.0", 3957 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 3958 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 3959 | "dev": true, 3960 | "engines": { 3961 | "node": ">=10" 3962 | }, 3963 | "funding": { 3964 | "url": "https://github.com/sponsors/sindresorhus" 3965 | } 3966 | }, 3967 | "node_modules/zustand": { 3968 | "version": "5.0.0-rc.2", 3969 | "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.0-rc.2.tgz", 3970 | "integrity": "sha512-o2Nwuvnk8vQBX7CcHL8WfFkZNJdxB/VKeWw0tNglw8p4cypsZ3tRT7rTRTDNeUPFS0qaMBRSKe+fVwL5xpcE3A==", 3971 | "engines": { 3972 | "node": ">=12.20.0" 3973 | }, 3974 | "peerDependencies": { 3975 | "@types/react": ">=18.0.0", 3976 | "immer": ">=9.0.6", 3977 | "react": ">=18.0.0", 3978 | "use-sync-external-store": ">=1.2.0" 3979 | }, 3980 | "peerDependenciesMeta": { 3981 | "@types/react": { 3982 | "optional": true 3983 | }, 3984 | "immer": { 3985 | "optional": true 3986 | }, 3987 | "react": { 3988 | "optional": true 3989 | }, 3990 | "use-sync-external-store": { 3991 | "optional": true 3992 | } 3993 | } 3994 | } 3995 | } 3996 | } 3997 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc -b && vite build", 9 | "lint": "eslint .", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "@emotion/react": "^11.13.3", 14 | "@emotion/styled": "^11.13.0", 15 | "@formkit/auto-animate": "^0.8.2", 16 | "@mui/icons-material": "^6.1.1", 17 | "@mui/lab": "^6.0.0-beta.10", 18 | "@mui/material": "^6.1.1", 19 | "@mui/x-data-grid": "^7.18.0", 20 | "@tanstack/react-query": "^5.56.2", 21 | "axios": "^1.7.7", 22 | "react": "^18.3.1", 23 | "react-dom": "^18.3.1", 24 | "react-dropzone": "^14.2.3", 25 | "zustand": "^5.0.0-rc.2" 26 | }, 27 | "devDependencies": { 28 | "@eslint/js": "^9.9.0", 29 | "@types/node": "^22.7.3", 30 | "@types/react": "^18.3.3", 31 | "@types/react-dom": "^18.3.0", 32 | "@vitejs/plugin-react-swc": "^3.5.0", 33 | "eslint": "^9.9.0", 34 | "eslint-plugin-react-hooks": "^5.1.0-rc.0", 35 | "eslint-plugin-react-refresh": "^0.4.9", 36 | "globals": "^15.9.0", 37 | "path": "^0.12.7", 38 | "typescript": "^5.5.3", 39 | "typescript-eslint": "^8.0.1", 40 | "vite": "^5.4.1" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /script.md: -------------------------------------------------------------------------------- 1 | desc: 2 | zustand video 3 | react query video 4 | 5 | first comment on video that do you want to implemnt using nextjs or?? 6 | 7 | --- 8 | 9 | intro: 10 | 11 | In this tutorial, you'll learn how to build a file manager in React where users can drag and drop multiple files with smooth animations and real-time upload progress. These files will be uploaded in parallel to a Node.js server running on your localhost. If an upload is interrupted, the progress indicator will turn red. 12 | 13 | Once uploaded, the files will be displayed in a paginated Data Grid fetched from the server. Users can sort by columns, manage, download, or perform bulk actions on multiple files. 14 | 15 | We’ll primarily focus on state management throughout the app, including handling user input for file selection (with type and quantity validation), uploading files in parallel, updating progress, and managing data on the client with caching, mutation, and invalidation. 16 | 17 | So, let’s dive in and get started! 18 | 19 | --- 20 | 21 | If you want to follow along and save time, I've created a starter template for this project. It’s a simple React Vite setup with Material UI and a few other libraries to get us up and running quickly. You can find all the relevant gists and project links in the description below. 22 | 23 | In this React project, we'll be using Material UI, React Query, Zustand, and React Dropzone. 24 | 25 | ```bash 26 | git clone -b starting-template https://github.com/codegenixdev/file-manager-frontend-tutorial.git . 27 | ``` 28 | 29 | make sure at least using node 18 for best compatibility 30 | 31 | ```bash 32 | npm i 33 | ``` 34 | 35 | open localhost on port 5173 36 | 37 | show what things are installed (insist on dropzone) 38 | review tsconfig.app.json (paths) 39 | review vite.config.ts (paths) 40 | review .env 41 | vite-end.d.ts 42 | inside src, we have app.tsx, main.tsx and shared folder where we put our shared and common components or utilieis here 43 | 44 | main.tsx (show why things are wrapped inside what) 45 | view confirm provider and insist on that this is the best to handle confirms in react and by wrapping your project inside it, you can use it every where in your application with ease where we get to it soon 46 | 47 | App.tsx (our application will go inside this container) 48 | utils, theme and a simple axios httpclient to use it app wide 49 | topbar and theme toggle that we talked before. 50 | BulkActions.tsx where when user select multiple uploaded files, this component will show up and use can do group opertions like delete multiple files which i have implmented this component and you can use it everywhere that you want 51 | 52 | --- 53 | 54 | fileManager/components/FileManager.tsx 55 | 56 | ```tsx FileManager.tsx 57 | export function FileManager() { 58 | return <>file manager; 59 | } 60 | ``` 61 | 62 | import it in app.tsx 63 | 64 | ```tsx filemanager.tsx 65 | export function FileManager() { 66 | return ( 67 | <> 68 | Files 69 | 70 | Files and assets that have been uploaded as part of this project. 71 | 72 | ({ 74 | backgroundColor: alpha(colors.grey[500], 0.1), 75 | padding: 2, 76 | width: 1, 77 | borderRadius: `${theme.shape.borderRadius}px`, 78 | display: "flex", 79 | flexDirection: "column", 80 | gap: 2, 81 | marginBottom: 3, 82 | })} 83 | > 84 | 85 | 86 | 87 | Click to upload or drag and drop 88 | Max 10GB. 89 | 90 | 91 | 92 | ); 93 | } 94 | ``` 95 | 96 | show 97 | 98 | like and subscribe 99 | 100 | ```tsx filemanager.tsx 101 | const { getRootProps, getInputProps } = useDropzone(); 102 | ``` 103 | 104 | on button base 105 | 106 | ```tsx filemanager.tsx 107 | {...getRootProps()} 108 | ``` 109 | 110 | below it 111 | 112 | ```tsx 113 | 114 | ``` 115 | 116 | show 117 | thats perfect but how to keep track of what files user has dropped in the upload box or has selected and what to do with them 118 | 119 | ```tsx 120 | function onDrop(acceptedFiles: File[]) { 121 | console.log(acceptedFiles); 122 | } 123 | 124 | const { getRootProps, getInputProps } = useDropzone({ 125 | onDrop, 126 | }); 127 | ``` 128 | 129 | show that is logs 130 | 131 | ```tsx 132 | const { getRootProps, getInputProps } = useDropzone({ 133 | onDrop, 134 | // accept: { 135 | // "image/*": [], 136 | // "video/*": [], 137 | // }, 138 | maxFiles: 15, 139 | maxSize: 10_000_000_000, 140 | }); 141 | ``` 142 | 143 | !! try to show some other funcaitonlaity like show error if wrong file or rejected files. 144 | 145 | also there are so many other properties you can read the docs 146 | 147 | now lets continue how to handle and what to do with selected files. 148 | because we want to have access to selected files in many different components and do some operations on them, instead of creating a state here that keeps track of selected files, i prefer to use some state management solutions like react context or zustand. but for simplicity and because zustand is very simple and unopninated, i prefer it here. also i have a full course on it so you can check it out 149 | 150 | ```ts hooks/useFileManagerStore.ts 151 | import { create } from "zustand"; 152 | 153 | type FileState = { 154 | files: ExtendedFile[]; 155 | }; 156 | ``` 157 | 158 | ```ts types/extendedFile 159 | export type ExtendedFile = { 160 | file: File; 161 | id: string; 162 | uploadProgress: number; 163 | uploadStatus: "idle" | "pending" | "error" | "success"; 164 | }; 165 | ``` 166 | 167 | ```ts 168 | import { ExtendedFile } from "@/fileManager/types/extendedFile"; 169 | import { create } from "zustand"; 170 | 171 | type FileState = { 172 | files: ExtendedFile[]; 173 | }; 174 | 175 | type FileActions = { 176 | appendFiles: (acceptedFiles: File[]) => void; 177 | }; 178 | 179 | type FileSlice = FileState & FileActions; 180 | 181 | export const useFileManagerStore = create()((set) => ({ 182 | files: [], 183 | appendFiles: (acceptedFiles) => 184 | set((state) => { 185 | const notDuplicatedNewFiles: ExtendedFile[] = acceptedFiles 186 | .filter((file) => { 187 | const isDuplicate = state.files.some( 188 | (subItem) => subItem.id === `${file.name}${file.size}` 189 | ); 190 | return !isDuplicate; 191 | }) 192 | .map((file) => ({ 193 | file, 194 | id: `${file.name}${file.size}`, 195 | uploadStatus: "idle", 196 | uploadProgress: 0, 197 | })); 198 | 199 | return { 200 | files: [...state.files, ...notDuplicatedNewFiles], 201 | }; 202 | }), 203 | })); 204 | ``` 205 | 206 | ```tsx 207 | const appendFiles = useFileManagerStore((state) => state.appendFiles); 208 | const files = useFileManagerStore((state) => state.files); 209 | 210 | function onDrop(acceptedFiles: File[]) { 211 | appendFiles(acceptedFiles); 212 | console.log(acceptedFiles); 213 | } 214 | ``` 215 | 216 | now show what we want to achieve in final project 217 | 218 | ```tsx before closing button base 219 | 220 | {files.map((file) => ( 221 | 222 | 223 | 224 | ))} 225 | 226 | ``` 227 | 228 | ```tsx UploadProgressCard 229 | import { FileThumbnail } from "@/fileManager/components/FileThumbnail"; 230 | import { useFileManagerStore } from "@/fileManager/hooks/useFileManagerStore"; 231 | import { ExtendedFile } from "@/fileManager/types/extendedFile"; 232 | import { convertByteToMegabyte } from "@/shared/utils"; 233 | import CloseRoundedIcon from "@mui/icons-material/CloseRounded"; 234 | import { Card, CardHeader, IconButton, Typography } from "@mui/material"; 235 | 236 | import { Box, LinearProgress } from "@mui/material"; 237 | import { useCallback } from "react"; 238 | 239 | type Props = ExtendedFile; 240 | export function UploadProgressCard({ 241 | file, 242 | id, 243 | uploadStatus, 244 | uploadProgress, 245 | }: Props) { 246 | const removeFile = useFileManagerStore((state) => state.removeFile); 247 | 248 | const getStatusColor = useCallback(() => { 249 | switch (uploadStatus) { 250 | case "success": 251 | return "success"; 252 | case "error": 253 | return "error"; 254 | default: 255 | return "info"; 256 | } 257 | }, [uploadStatus]); 258 | 259 | function handleRemove() { 260 | removeFile(id); 261 | } 262 | 263 | return ( 264 | e.stopPropagation()} 268 | > 269 | 272 | 273 | 274 | } 275 | avatar={} 276 | title={file.name} 277 | subheader={ 278 | 279 | 280 | {convertByteToMegabyte(file.size)} 281 | 282 | 283 | 284 | 285 | ({ 287 | height: theme.spacing(1), 288 | borderRadius: theme.shape.borderRadius, 289 | "& .MuiLinearProgress-bar": { 290 | borderRadius: theme.shape.borderRadius, 291 | }, 292 | })} 293 | variant="determinate" 294 | color={getStatusColor()} 295 | value={uploadProgress} 296 | aria-label={`Progress: ${uploadProgress ?? 0}%`} 297 | /> 298 | 299 | {`${Math.round( 300 | uploadProgress ?? 0 301 | )}%`} 302 | 303 | 304 | } 305 | disableTypography 306 | /> 307 | 308 | ); 309 | } 310 | ``` 311 | 312 | ```tsx FileThumbnail 313 | import AudioFileRoundedIcon from "@mui/icons-material/AudioFileRounded"; 314 | import DescriptionRoundedIcon from "@mui/icons-material/DescriptionRounded"; 315 | import InsertDriveFileRoundedIcon from "@mui/icons-material/InsertDriveFileRounded"; 316 | 317 | import InsertPhotoRoundedIcon from "@mui/icons-material/InsertPhotoRounded"; 318 | import SmartDisplayRoundedIcon from "@mui/icons-material/SmartDisplayRounded"; 319 | 320 | function getFileType(extension: string) { 321 | switch (extension) { 322 | case "jpg": 323 | case "jpeg": 324 | case "png": 325 | case "gif": 326 | return "image"; 327 | case "mp4": 328 | case "mov": 329 | case "avi": 330 | case "mkv": 331 | return "video"; 332 | case "mp3": 333 | case "wav": 334 | return "audio"; 335 | case "pdf": 336 | case "doc": 337 | case "docx": 338 | case "txt": 339 | return "document"; 340 | default: 341 | return "file"; 342 | } 343 | } 344 | 345 | type FileThumbnailProps = Pick; 346 | 347 | export function FileThumbnail({ name }: FileThumbnailProps) { 348 | const extension = name.split(".").pop()?.toLowerCase(); 349 | const fileType = extension ? getFileType(extension) : "file"; 350 | 351 | switch (fileType) { 352 | case "image": 353 | return ; 354 | case "video": 355 | return ; 356 | case "audio": 357 | return ; 358 | case "document": 359 | return ; 360 | default: 361 | return ; 362 | } 363 | } 364 | ``` 365 | 366 | now import file upload progress in file manager 367 | 368 | show it 369 | 370 | now implement removeFile 371 | 372 | ```ts 373 | removeFile: (id: string) => void; 374 | 375 | removeFile: (id) => 376 | set((state) => ({ 377 | files: state.files.filter((file) => file.id !== id), 378 | })), 379 | ``` 380 | 381 | ```tsx upload card 382 | const removeFile = useFileManagerStore((state) => state.removeFile); 383 | // in avatar 384 | 385 | 386 | ; 387 | ``` 388 | 389 | show it that works 390 | disable ripple in button base 391 | to have better animation, we can use this amazing simple library 392 | 393 | ```tsx 394 | const [autoAnimateRef] = useAutoAnimate(); 395 | 396 | {files.map((file) => ( 397 | 398 | 399 | 400 | ))} 401 | ; 402 | ``` 403 | 404 | show animations 405 | 406 | now we need to implement upload logic 407 | we need a simple 408 | i have created a nodejs express server that you can clone it like this 409 | 410 | ```bash 411 | git clone https://github.com/codegenixdev/file-manager-backend-tutorial.git . 412 | npm i 413 | npm run dev 414 | ``` 415 | 416 | now it is running on localhost:3000 and uploaded files will be in the upload folder and we can use it in our project 417 | show endpoints in postman 418 | 419 | for simplicity i decided to use react query to communicate with our server and handle queries and mutations to our server in a more professional way. also i have a video on it. if are following along, the react query is installed (show package.json) and just make sure that in main.tsx the whole project is wrapped inside react query provider. 420 | 421 | create useFileUploadMutation.ts 422 | 423 | but before it, because we need to change the upload status and upload progress (show extendedFile) alot during the upload process so we need a way to manage these two properties more easily, so we can easily add two other actions to our store 424 | 425 | ```ts 426 | 427 | updateUploadProgress: (id: string, uploadProgress: number) => void; 428 | updateUploadStatus: ( 429 | id: string, 430 | uploadStatus: ExtendedFile["uploadStatus"] 431 | ) => void; 432 | 433 | updateUploadProgress: (id, uploadProgress) => 434 | set((state) => ({ 435 | files: state.files.map((file) => 436 | file.id === id ? { ...file, uploadProgress } : file 437 | ), 438 | })), 439 | 440 | updateUploadStatus: (id, uploadStatus) => 441 | set((state) => ({ 442 | files: state.files.map((file) => 443 | file.id === id ? { ...file, uploadStatus } : file 444 | ), 445 | })), 446 | 447 | ``` 448 | 449 | ```ts useFileUploadMutation.ts 450 | import { useFileManagerStore } from "@/fileManager/hooks/useFileManagerStore"; 451 | import { ExtendedFile } from "@/fileManager/types/extendedFile"; 452 | import { httpClient } from "@/shared/httpClient"; 453 | import { useMutation } from "@tanstack/react-query"; 454 | 455 | export function useFileUploadMutation() { 456 | const updateUploadProgress = useFileManagerStore( 457 | (state) => state.updateUploadProgress 458 | ); 459 | const updateUploadStatus = useFileManagerStore( 460 | (state) => state.updateUploadStatus 461 | ); 462 | const appendFiles = useFileManagerStore((state) => state.appendFiles); 463 | 464 | return useMutation({ 465 | mutationFn: async (files: ExtendedFile[]) => { 466 | const uploadPromises = files.map(async (file) => { 467 | if (file.uploadStatus === "idle") { 468 | updateUploadStatus(file.id, "pending"); 469 | 470 | const formData = new FormData(); 471 | formData.append("file", file.file); 472 | 473 | return httpClient 474 | .post(`${import.meta.env.VITE_API_URL}/upload`, formData, { 475 | headers: { 476 | "Content-Type": "multipart/form-data", 477 | }, 478 | onUploadProgress: (event) => { 479 | if (event.lengthComputable && event.total) { 480 | const percentComplete = Math.round( 481 | (event.loaded / event.total) * 100 482 | ); 483 | updateUploadProgress(file.id, percentComplete); 484 | } 485 | }, 486 | }) 487 | .then(() => { 488 | updateUploadStatus(file.id, "success"); 489 | }) 490 | .catch(() => { 491 | updateUploadStatus(file.id, "error"); 492 | }); 493 | } 494 | return Promise.resolve(); 495 | }); 496 | 497 | await Promise.all(uploadPromises); 498 | }, 499 | onMutate: (variables) => { 500 | appendFiles(variables.map((item) => item.file)); 501 | }, 502 | }); 503 | } 504 | ``` 505 | 506 | to use it 507 | 508 | ```tsx 509 | const [autoAnimateRef] = useAutoAnimate(); 510 | 511 | const fileUploadMutation = useFileUploadMutation(); 512 | 513 | function onDrop(acceptedFiles: File[]) { 514 | fileUploadMutation.mutate( 515 | acceptedFiles.map((item) => ({ 516 | file: item, 517 | id: `${item.name}${item.size}`, 518 | uploadProgress: 0, 519 | uploadStatus: "idle", 520 | })) 521 | ); 522 | } 523 | ``` 524 | 525 | now upload a file and show the uploads folder (try a heavy file) 526 | 527 | show it becomes red if upload becomes intruptted 528 | 529 | but i want the file to be removed after a few seconds if uploaded 530 | 531 | ```tsx UploadProgressCard 532 | const [progress, setProgress] = useState(0); 533 | 534 | useEffect(() => { 535 | if (uploadStatus === "success") { 536 | let progressValue = 0; 537 | 538 | const interval = setInterval(() => { 539 | progressValue += 3; 540 | setProgress((prev) => prev + 3); 541 | if (progressValue >= 100) { 542 | removeFile(id); 543 | clearInterval(interval); 544 | } 545 | }, 50); 546 | return () => clearInterval(interval); 547 | } 548 | }, [id, removeFile, uploadStatus]); 549 | 550 | 551 | action={ 552 | 553 | 560 | 568 | 569 | 570 | 571 | 572 | 573 | } 574 | 575 | ``` 576 | 577 | show it 578 | 579 | now we need to create a query to fetch files from server to show files in a data grid 580 | show final project (upload something and show that data grid updates), show pagination and page size and sorting 581 | 582 | ```ts useFilesQuery.ts 583 | import { GridPaginationModel } from "@mui/x-data-grid"; 584 | import { useQuery } from "@tanstack/react-query"; 585 | 586 | import { GridSortModel } from "@mui/x-data-grid"; 587 | import { FileDataGridRow } from "@/fileManager/types/fileDataGridRow"; 588 | import { httpClient } from "@/shared/httpClient"; 589 | 590 | export function useFilesQuery({ 591 | paginationModel, 592 | sortModel, 593 | }: { 594 | paginationModel: GridPaginationModel; 595 | sortModel: GridSortModel; 596 | }) { 597 | return useQuery({ 598 | queryKey: ["files", { paginationModel, sortModel }], 599 | queryFn: async () => { 600 | const sortField = 601 | sortModel.length > 0 ? sortModel[0].field : "dateUploaded"; 602 | const sortOrder = sortModel.length > 0 ? sortModel[0].sort : "asc"; 603 | 604 | type Response = { 605 | totalFilesCount: number; 606 | files: FileDataGridRow[]; 607 | }; 608 | 609 | const { data } = await httpClient.get(`/files`, { 610 | params: { 611 | page: paginationModel.page, 612 | pageSize: paginationModel.pageSize, 613 | sortField, 614 | sortOrder, 615 | }, 616 | }); 617 | 618 | return data; 619 | }, 620 | }); 621 | } 622 | ``` 623 | 624 | ```ts fileDataGridRow 625 | export type FileDataGridRow = { 626 | id: string; 627 | filename: string; 628 | size: number; 629 | dateUploaded: string; 630 | }; 631 | ``` 632 | 633 | ```ts FilesDataGrid.tsx 634 | import { Stack, Typography } from "@mui/material"; 635 | 636 | import { FileThumbnail } from "@/fileManager/components/FileThumbnail"; 637 | import { useFilesQuery } from "@/fileManager/hooks/useFilesQuery"; 638 | import { FileDataGridRow } from "@/fileManager/types/fileDataGridRow"; 639 | import { convertByteToMegabyte } from "@/shared/utils"; 640 | import { DataGrid, GridColDef, GridSortModel } from "@mui/x-data-grid"; 641 | import { useMemo, useRef, useState } from "react"; 642 | 643 | const columns: GridColDef[] = [ 644 | { 645 | field: "filename", 646 | headerName: "File Name", 647 | flex: 1, 648 | renderCell: ({ row }) => ( 649 | 657 | 658 | 659 | {row.filename} 660 | 661 | 662 | ), 663 | }, 664 | { 665 | field: "size", 666 | headerName: "Size", 667 | flex: 1, 668 | valueFormatter: (value) => convertByteToMegabyte(value), 669 | }, 670 | { 671 | field: "dateUploaded", 672 | headerName: "Date Uploaded", 673 | flex: 1, 674 | valueFormatter: (value) => new Date(value).toDateString(), 675 | }, 676 | ]; 677 | 678 | export function FilesDataGrid() { 679 | const [sortModel, setSortModel] = useState([ 680 | { field: "dateUploaded", sort: "desc" }, 681 | ]); 682 | 683 | const [paginationModel, setPaginationModel] = useState({ 684 | page: 0, 685 | pageSize: 10, 686 | }); 687 | 688 | const filesQuery = useFilesQuery({ paginationModel, sortModel }); 689 | const rowCountRef = useRef(filesQuery.data?.totalFilesCount || 0); 690 | 691 | const rowCount = useMemo(() => { 692 | if (filesQuery.data?.totalFilesCount !== undefined) { 693 | rowCountRef.current = filesQuery.data.totalFilesCount; 694 | } 695 | return rowCountRef.current; 696 | }, [filesQuery.data?.totalFilesCount]); 697 | 698 | return ( 699 | <> 700 | ({ height: `calc(100dvh - ${theme.spacing(52)})` })} 702 | rows={filesQuery.data?.files} 703 | columns={columns} 704 | rowCount={rowCount} 705 | loading={filesQuery.isLoading} 706 | pageSizeOptions={[10, 25, 50, 100]} 707 | density="comfortable" 708 | paginationModel={paginationModel} 709 | paginationMode="server" 710 | onPaginationModelChange={setPaginationModel} 711 | onSortModelChange={(newSortModel) => setSortModel(newSortModel)} 712 | /> 713 | 714 | ); 715 | } 716 | ``` 717 | 718 | import it in filemanager below button base then show it (pagination works and sorting) but when upload something grid wont updated 719 | 720 | ```ts 721 | 722 | onSuccess: async () => { 723 | await queryClient.invalidateQueries({ queryKey: ["files"] }); 724 | }, 725 | ``` 726 | 727 | now when upload, it revalidates 728 | 729 | now show the final quick actions. we want to implement it 730 | 731 | ```ts useFileDeleteMutation 732 | import { httpClient } from "@/shared/httpClient"; 733 | import { useMutation, useQueryClient } from "@tanstack/react-query"; 734 | 735 | export function useFileDeleteMutation() { 736 | const queryClient = useQueryClient(); 737 | 738 | return useMutation({ 739 | mutationFn: async (fileIds: string[]) => { 740 | await httpClient.delete(`files`, { data: { fileIds } }); 741 | }, 742 | onSuccess: async () => { 743 | await queryClient.invalidateQueries({ queryKey: ["files"] }); 744 | }, 745 | }); 746 | } 747 | ``` 748 | 749 | ```ts FileQuickActions.tsx 750 | import DeleteForeverRoundedIcon from "@mui/icons-material/DeleteForeverRounded"; 751 | import DownloadRoundedIcon from "@mui/icons-material/DownloadRounded"; 752 | import MoreVertTwoToneIcon from "@mui/icons-material/MoreVertTwoTone"; 753 | import { 754 | Button, 755 | IconButton, 756 | Link, 757 | Popover, 758 | Stack, 759 | Typography, 760 | } from "@mui/material"; 761 | import { MouseEvent, useState } from "react"; 762 | import { useFileDeleteMutation } from "@/fileManager/hooks/useFileDeleteMutation"; 763 | import { FileDataGridRow } from "@/fileManager/types/fileDataGridRow"; 764 | import { useConfirm } from "@/shared/confirm/hooks/useConfirm"; 765 | 766 | type Props = FileDataGridRow; 767 | export function FileQuickActions({ id, filename }: Props) { 768 | const [anchorEl, setAnchorEl] = useState(null); 769 | const confirm = useConfirm(); 770 | 771 | const fileDeleteMutation = useFileDeleteMutation(); 772 | 773 | function handleClick(event: MouseEvent) { 774 | setAnchorEl(event.currentTarget); 775 | } 776 | 777 | function handleClose() { 778 | setAnchorEl(null); 779 | } 780 | 781 | function handleRemoveFiles() { 782 | confirm({ 783 | handleConfirm: () => { 784 | fileDeleteMutation.mutate([id]); 785 | }, 786 | }); 787 | } 788 | 789 | return ( 790 | <> 791 | 792 | 793 | 794 | 795 | 796 | 801 | 804 | 805 | 806 | 813 | 814 | 815 | 816 | ); 817 | } 818 | ``` 819 | 820 | import it in data grid 821 | 822 | ```tsx 823 | { 824 | field: "action", 825 | sortable: false, 826 | pinnable: false, 827 | type: "actions", 828 | renderCell: ({ row }) => , 829 | }, 830 | ``` 831 | 832 | show it 833 | 834 | show final project, we want select files then do some actions with them. so first of all we need to select files from our data grid then keep track of selected files specificalyy selected file ids 835 | 836 | ```ts 837 | 838 | selectedFileIds: string[]; 839 | 840 | updateSelectedFileIds: (ids: string[]) => void; 841 | 842 | updateSelectedFileIds: (ids) => 843 | set(() => ({ 844 | selectedFileIds: ids, 845 | })), 846 | 847 | ``` 848 | 849 | ```tsx datagrid 850 | const confirm = useConfirm(); 851 | const fileDeleteMutation = useFileDeleteMutation(); 852 | 853 | const selectedFileIds = useFileManagerStore((state) => state.selectedFileIds); 854 | const updateSelectedFileIds = useFileManagerStore( 855 | (state) => state.updateSelectedFileIds 856 | ); 857 | 858 | function handleRemoveFiles() { 859 | confirm({ 860 | handleConfirm: () => { 861 | fileDeleteMutation.mutate(selectedFileIds, { 862 | onSuccess: () => { 863 | updateSelectedFileIds([]); 864 | }, 865 | }); 866 | }, 867 | }); 868 | } 869 | 870 | function handleRowSelectionModelChange(ids: GridRowSelectionModel) { 871 | updateSelectedFileIds(ids.map((id) => id.toString())); 872 | } 873 | 874 | checkboxSelection; 875 | onRowSelectionModelChange = { handleRowSelectionModelChange }; 876 | rowSelectionModel = { selectedFileIds }; 877 | 878 | , 882 | actionFn: handleRemoveFiles, 883 | label: "Delete files", 884 | }, 885 | ]} 886 | ids={selectedFileIds} 887 | />; 888 | ``` 889 | -------------------------------------------------------------------------------- /src/App.tsx: -------------------------------------------------------------------------------- 1 | import { FileManager } from "@/fileManager/components/FileManager"; 2 | import { Topbar } from "@/shared/ui/Topbar"; 3 | import { Container } from "@mui/material"; 4 | 5 | export function App() { 6 | return ( 7 | <> 8 | 9 | 10 | 11 | 12 | 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /src/fileManager/components/FileManager.tsx: -------------------------------------------------------------------------------- 1 | import { FilesDataGrid } from "@/fileManager/components/FilesDataGrid"; 2 | import { UploadProgressCard } from "@/fileManager/components/UploadProgressCard"; 3 | import { useFileManagerStore } from "@/fileManager/hooks/useFileManagerStore"; 4 | import { useFileUploadMutation } from "@/fileManager/hooks/useFileUploadMutation"; 5 | import { useAutoAnimate } from "@formkit/auto-animate/react"; 6 | import FileUploadRoundedIcon from "@mui/icons-material/FileUploadRounded"; 7 | import { 8 | alpha, 9 | Box, 10 | ButtonBase, 11 | colors, 12 | Stack, 13 | Typography, 14 | } from "@mui/material"; 15 | import { useDropzone } from "react-dropzone"; 16 | 17 | export function FileManager() { 18 | const files = useFileManagerStore((state) => state.files); 19 | 20 | const [autoAnimateRef] = useAutoAnimate(); 21 | 22 | const fileUploadMutation = useFileUploadMutation(); 23 | 24 | function onDrop(acceptedFiles: File[]) { 25 | fileUploadMutation.mutate( 26 | acceptedFiles.map((item) => ({ 27 | file: item, 28 | id: `${item.name}${item.size}`, 29 | uploadProgress: 0, 30 | uploadStatus: "idle", 31 | })) 32 | ); 33 | } 34 | 35 | const { getRootProps, getInputProps } = useDropzone({ 36 | // accept: { 37 | // "image/*": [], 38 | // "video/*": [], 39 | // }, 40 | onDrop, 41 | maxFiles: 15, 42 | maxSize: 10_000_000_000, 43 | }); 44 | 45 | return ( 46 | <> 47 | Files 48 | 49 | Files and assets that have been uploaded as part of this project. 50 | 51 | ({ 53 | backgroundColor: alpha(colors.grey[500], 0.1), 54 | padding: 2, 55 | width: 1, 56 | borderRadius: `${theme.shape.borderRadius}px`, 57 | display: "flex", 58 | flexDirection: "column", 59 | gap: 2, 60 | marginBottom: 3, 61 | })} 62 | disableRipple 63 | {...getRootProps()} 64 | > 65 | 66 | 67 | 68 | 69 | 70 | Click to upload or drag and drop 71 | Max 10GB. 72 | 73 | 74 | {files.map((file) => ( 75 | 76 | 77 | 78 | ))} 79 | 80 | 81 | 82 | 83 | ); 84 | } 85 | -------------------------------------------------------------------------------- /src/fileManager/components/FileQuickActions.tsx: -------------------------------------------------------------------------------- 1 | import DeleteForeverRoundedIcon from "@mui/icons-material/DeleteForeverRounded"; 2 | import DownloadRoundedIcon from "@mui/icons-material/DownloadRounded"; 3 | import MoreVertTwoToneIcon from "@mui/icons-material/MoreVertTwoTone"; 4 | import { 5 | Button, 6 | IconButton, 7 | Link, 8 | Popover, 9 | Stack, 10 | Typography, 11 | } from "@mui/material"; 12 | import { MouseEvent, useState } from "react"; 13 | import { useFileDeleteMutation } from "@/fileManager/hooks/useFileDeleteMutation"; 14 | import { FileDataGridRow } from "@/fileManager/types/fileDataGridRow"; 15 | import { useConfirm } from "@/shared/confirm/hooks/useConfirm"; 16 | 17 | type Props = FileDataGridRow; 18 | export function FileQuickActions({ id, filename }: Props) { 19 | const [anchorEl, setAnchorEl] = useState(null); 20 | const confirm = useConfirm(); 21 | 22 | const fileDeleteMutation = useFileDeleteMutation(); 23 | 24 | function handleClick(event: MouseEvent) { 25 | setAnchorEl(event.currentTarget); 26 | } 27 | 28 | function handleClose() { 29 | setAnchorEl(null); 30 | } 31 | 32 | function handleRemoveFiles() { 33 | confirm({ 34 | handleConfirm: () => { 35 | fileDeleteMutation.mutate([id]); 36 | }, 37 | }); 38 | } 39 | 40 | return ( 41 | <> 42 | 43 | 44 | 45 | 46 | 47 | 52 | 55 | 56 | 57 | 64 | 65 | 66 | 67 | ); 68 | } 69 | -------------------------------------------------------------------------------- /src/fileManager/components/FileThumbnail.tsx: -------------------------------------------------------------------------------- 1 | import AudioFileRoundedIcon from "@mui/icons-material/AudioFileRounded"; 2 | import DescriptionRoundedIcon from "@mui/icons-material/DescriptionRounded"; 3 | import InsertDriveFileRoundedIcon from "@mui/icons-material/InsertDriveFileRounded"; 4 | 5 | import InsertPhotoRoundedIcon from "@mui/icons-material/InsertPhotoRounded"; 6 | import SmartDisplayRoundedIcon from "@mui/icons-material/SmartDisplayRounded"; 7 | 8 | function getFileType(extension: string) { 9 | switch (extension) { 10 | case "jpg": 11 | case "jpeg": 12 | case "png": 13 | case "gif": 14 | return "image"; 15 | case "mp4": 16 | case "mov": 17 | case "avi": 18 | case "mkv": 19 | return "video"; 20 | case "mp3": 21 | case "wav": 22 | return "audio"; 23 | case "pdf": 24 | case "doc": 25 | case "docx": 26 | case "txt": 27 | return "document"; 28 | default: 29 | return "file"; 30 | } 31 | } 32 | 33 | type FileThumbnailProps = Pick; 34 | 35 | export function FileThumbnail({ name }: FileThumbnailProps) { 36 | const extension = name.split(".").pop()?.toLowerCase(); 37 | const fileType = extension ? getFileType(extension) : "file"; 38 | 39 | switch (fileType) { 40 | case "image": 41 | return ; 42 | case "video": 43 | return ; 44 | case "audio": 45 | return ; 46 | case "document": 47 | return ; 48 | default: 49 | return ; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/fileManager/components/FilesDataGrid.tsx: -------------------------------------------------------------------------------- 1 | import { Stack, Typography } from "@mui/material"; 2 | 3 | import DeleteForeverRoundedIcon from "@mui/icons-material/DeleteForeverRounded"; 4 | import { 5 | DataGrid, 6 | GridColDef, 7 | GridRowSelectionModel, 8 | GridSortModel, 9 | } from "@mui/x-data-grid"; 10 | import { useMemo, useRef, useState } from "react"; 11 | import { FileDataGridRow } from "@/fileManager/types/fileDataGridRow"; 12 | import { FileThumbnail } from "@/fileManager/components/FileThumbnail"; 13 | import { convertByteToMegabyte } from "@/shared/utils"; 14 | import { FileQuickActions } from "@/fileManager/components/FileQuickActions"; 15 | import { useFileDeleteMutation } from "@/fileManager/hooks/useFileDeleteMutation"; 16 | import { useFileManagerStore } from "@/fileManager/hooks/useFileManagerStore"; 17 | import { useFilesQuery } from "@/fileManager/hooks/useFilesQuery"; 18 | import { BulkActions } from "@/shared/ui/BulkActions"; 19 | import { useConfirm } from "@/shared/confirm/hooks/useConfirm"; 20 | 21 | const columns: GridColDef[] = [ 22 | { 23 | field: "filename", 24 | headerName: "File Name", 25 | flex: 1, 26 | renderCell: ({ row }) => ( 27 | 35 | 36 | 37 | {row.filename} 38 | 39 | 40 | ), 41 | }, 42 | { 43 | field: "size", 44 | headerName: "Size", 45 | flex: 1, 46 | valueFormatter: (value) => convertByteToMegabyte(value), 47 | }, 48 | { 49 | field: "dateUploaded", 50 | headerName: "Date Uploaded", 51 | flex: 1, 52 | valueFormatter: (value) => new Date(value).toDateString(), 53 | }, 54 | { 55 | field: "action", 56 | sortable: false, 57 | pinnable: false, 58 | type: "actions", 59 | renderCell: ({ row }) => , 60 | }, 61 | ]; 62 | 63 | export function FilesDataGrid() { 64 | const [sortModel, setSortModel] = useState([ 65 | { field: "dateUploaded", sort: "desc" }, 66 | ]); 67 | const confirm = useConfirm(); 68 | 69 | const fileDeleteMutation = useFileDeleteMutation(); 70 | 71 | const selectedFileIds = useFileManagerStore((state) => state.selectedFileIds); 72 | const updateSelectedFileIds = useFileManagerStore( 73 | (state) => state.updateSelectedFileIds 74 | ); 75 | 76 | const [paginationModel, setPaginationModel] = useState({ 77 | page: 0, 78 | pageSize: 10, 79 | }); 80 | 81 | const filesQuery = useFilesQuery({ paginationModel, sortModel }); 82 | const rowCountRef = useRef(filesQuery.data?.totalFilesCount || 0); 83 | 84 | const rowCount = useMemo(() => { 85 | if (filesQuery.data?.totalFilesCount !== undefined) { 86 | rowCountRef.current = filesQuery.data.totalFilesCount; 87 | } 88 | return rowCountRef.current; 89 | }, [filesQuery.data?.totalFilesCount]); 90 | 91 | function handleRemoveFiles() { 92 | confirm({ 93 | handleConfirm: () => { 94 | fileDeleteMutation.mutate(selectedFileIds, { 95 | onSuccess: () => { 96 | updateSelectedFileIds([]); 97 | }, 98 | }); 99 | }, 100 | }); 101 | } 102 | 103 | function handleRowSelectionModelChange(ids: GridRowSelectionModel) { 104 | updateSelectedFileIds(ids.map((id) => id.toString())); 105 | } 106 | 107 | return ( 108 | <> 109 | ({ height: `calc(100dvh - ${theme.spacing(52)})` })} 111 | checkboxSelection 112 | onRowSelectionModelChange={handleRowSelectionModelChange} 113 | rowSelectionModel={selectedFileIds} 114 | rows={filesQuery.data?.files} 115 | columns={columns} 116 | rowCount={rowCount} 117 | loading={filesQuery.isLoading} 118 | pageSizeOptions={[10, 25, 50, 100]} 119 | density="comfortable" 120 | paginationModel={paginationModel} 121 | paginationMode="server" 122 | onPaginationModelChange={setPaginationModel} 123 | onSortModelChange={(newSortModel) => setSortModel(newSortModel)} 124 | /> 125 | , 129 | actionFn: handleRemoveFiles, 130 | label: "Delete files", 131 | }, 132 | ]} 133 | ids={selectedFileIds} 134 | /> 135 | 136 | ); 137 | } 138 | -------------------------------------------------------------------------------- /src/fileManager/components/UploadProgressCard.tsx: -------------------------------------------------------------------------------- 1 | import { FileThumbnail } from "@/fileManager/components/FileThumbnail"; 2 | import { useFileManagerStore } from "@/fileManager/hooks/useFileManagerStore"; 3 | import { ExtendedFile } from "@/fileManager/types/extendedFile"; 4 | import { convertByteToMegabyte } from "@/shared/utils"; 5 | import CloseRoundedIcon from "@mui/icons-material/CloseRounded"; 6 | import { 7 | Card, 8 | CardHeader, 9 | CircularProgress, 10 | IconButton, 11 | Stack, 12 | Typography, 13 | } from "@mui/material"; 14 | 15 | import { Box, LinearProgress } from "@mui/material"; 16 | import { useCallback, useEffect, useState } from "react"; 17 | 18 | type Props = ExtendedFile; 19 | export function UploadProgressCard({ 20 | file, 21 | id, 22 | uploadStatus, 23 | uploadProgress, 24 | }: Props) { 25 | const removeFile = useFileManagerStore((state) => state.removeFile); 26 | 27 | const [progress, setProgress] = useState(0); 28 | 29 | useEffect(() => { 30 | if (uploadStatus === "success") { 31 | let progressValue = 0; 32 | 33 | const interval = setInterval(() => { 34 | progressValue += 3; 35 | setProgress((prev) => prev + 3); 36 | if (progressValue >= 100) { 37 | removeFile(id); 38 | clearInterval(interval); 39 | } 40 | }, 50); 41 | return () => clearInterval(interval); 42 | } 43 | }, [id, removeFile, uploadStatus]); 44 | 45 | const getStatusColor = useCallback(() => { 46 | switch (uploadStatus) { 47 | case "success": 48 | return "success"; 49 | case "error": 50 | return "error"; 51 | default: 52 | return "info"; 53 | } 54 | }, [uploadStatus]); 55 | 56 | function handleRemove() { 57 | removeFile(id); 58 | } 59 | 60 | return ( 61 | e.stopPropagation()} 65 | > 66 | 69 | 76 | 84 | 85 | 86 | 87 | 88 | 89 | } 90 | avatar={} 91 | title={file.name} 92 | subheader={ 93 | 94 | 95 | {convertByteToMegabyte(file.size)} 96 | 97 | 98 | 99 | 100 | ({ 102 | height: theme.spacing(1), 103 | borderRadius: theme.shape.borderRadius, 104 | "& .MuiLinearProgress-bar": { 105 | borderRadius: theme.shape.borderRadius, 106 | }, 107 | })} 108 | variant="determinate" 109 | color={getStatusColor()} 110 | value={uploadProgress} 111 | aria-label={`Progress: ${uploadProgress ?? 0}%`} 112 | /> 113 | 114 | {`${Math.round( 115 | uploadProgress ?? 0 116 | )}%`} 117 | 118 | 119 | } 120 | disableTypography 121 | /> 122 | 123 | ); 124 | } 125 | -------------------------------------------------------------------------------- /src/fileManager/hooks/useFileDeleteMutation.ts: -------------------------------------------------------------------------------- 1 | import { httpClient } from "@/shared/httpClient"; 2 | import { useMutation, useQueryClient } from "@tanstack/react-query"; 3 | 4 | export function useFileDeleteMutation() { 5 | const queryClient = useQueryClient(); 6 | 7 | return useMutation({ 8 | mutationFn: async (fileIds: string[]) => { 9 | await httpClient.delete(`files`, { data: { fileIds } }); 10 | }, 11 | onSuccess: async () => { 12 | await queryClient.invalidateQueries({ queryKey: ["files"] }); 13 | }, 14 | }); 15 | } 16 | -------------------------------------------------------------------------------- /src/fileManager/hooks/useFileManagerStore.ts: -------------------------------------------------------------------------------- 1 | import { ExtendedFile } from "@/fileManager/types/extendedFile"; 2 | import { create } from "zustand"; 3 | 4 | type FileState = { 5 | files: ExtendedFile[]; 6 | selectedFileIds: string[]; 7 | }; 8 | 9 | type FileActions = { 10 | removeFile: (id: string) => void; 11 | appendFiles: (acceptedFiles: File[]) => void; 12 | updateUploadProgress: (id: string, uploadProgress: number) => void; 13 | updateUploadStatus: ( 14 | id: string, 15 | uploadStatus: ExtendedFile["uploadStatus"] 16 | ) => void; 17 | updateSelectedFileIds: (ids: string[]) => void; 18 | }; 19 | 20 | type FileSlice = FileState & FileActions; 21 | 22 | export const useFileManagerStore = create()((set) => ({ 23 | files: [], 24 | selectedFileIds: [], 25 | removeFile: (id) => 26 | set((state) => ({ 27 | files: state.files.filter((file) => file.id !== id), 28 | })), 29 | 30 | appendFiles: (acceptedFiles) => 31 | set((state) => { 32 | const notDuplicatedNewFiles: ExtendedFile[] = acceptedFiles 33 | .filter((file) => { 34 | const isDuplicate = state.files.some( 35 | (subItem) => subItem.id === `${file.name}${file.size}` 36 | ); 37 | return !isDuplicate; 38 | }) 39 | .map((file) => ({ 40 | file, 41 | id: `${file.name}${file.size}`, 42 | uploadStatus: "idle", 43 | uploadProgress: 0, 44 | })); 45 | 46 | return { 47 | files: [...state.files, ...notDuplicatedNewFiles], 48 | }; 49 | }), 50 | 51 | updateUploadProgress: (id, uploadProgress) => 52 | set((state) => ({ 53 | files: state.files.map((file) => 54 | file.id === id ? { ...file, uploadProgress } : file 55 | ), 56 | })), 57 | 58 | updateUploadStatus: (id, uploadStatus) => 59 | set((state) => ({ 60 | files: state.files.map((file) => 61 | file.id === id ? { ...file, uploadStatus } : file 62 | ), 63 | })), 64 | updateSelectedFileIds: (ids) => 65 | set(() => ({ 66 | selectedFileIds: ids, 67 | })), 68 | })); 69 | -------------------------------------------------------------------------------- /src/fileManager/hooks/useFileUploadMutation.ts: -------------------------------------------------------------------------------- 1 | import { useFileManagerStore } from "@/fileManager/hooks/useFileManagerStore"; 2 | import { ExtendedFile } from "@/fileManager/types/extendedFile"; 3 | import { httpClient } from "@/shared/httpClient"; 4 | import { useMutation, useQueryClient } from "@tanstack/react-query"; 5 | 6 | export function useFileUploadMutation() { 7 | const updateUploadProgress = useFileManagerStore( 8 | (state) => state.updateUploadProgress 9 | ); 10 | const updateUploadStatus = useFileManagerStore( 11 | (state) => state.updateUploadStatus 12 | ); 13 | const appendFiles = useFileManagerStore((state) => state.appendFiles); 14 | 15 | const queryClient = useQueryClient(); 16 | 17 | return useMutation({ 18 | mutationFn: async (files: ExtendedFile[]) => { 19 | const uploadPromises = files.map(async (file) => { 20 | if (file.uploadStatus === "idle") { 21 | updateUploadStatus(file.id, "pending"); 22 | 23 | const formData = new FormData(); 24 | formData.append("file", file.file); 25 | 26 | return httpClient 27 | .post(`${import.meta.env.VITE_API_URL}/upload`, formData, { 28 | headers: { 29 | "Content-Type": "multipart/form-data", 30 | }, 31 | onUploadProgress: (event) => { 32 | if (event.lengthComputable && event.total) { 33 | const percentComplete = Math.round( 34 | (event.loaded / event.total) * 100 35 | ); 36 | updateUploadProgress(file.id, percentComplete); 37 | } 38 | }, 39 | }) 40 | .then(() => { 41 | updateUploadStatus(file.id, "success"); 42 | }) 43 | .catch(() => { 44 | updateUploadStatus(file.id, "error"); 45 | }); 46 | } 47 | return Promise.resolve(); 48 | }); 49 | 50 | await Promise.all(uploadPromises); 51 | }, 52 | onMutate: (variables) => { 53 | appendFiles(variables.map((item) => item.file)); 54 | }, 55 | onSuccess: async () => { 56 | await queryClient.invalidateQueries({ queryKey: ["files"] }); 57 | }, 58 | }); 59 | } 60 | -------------------------------------------------------------------------------- /src/fileManager/hooks/useFilesQuery.ts: -------------------------------------------------------------------------------- 1 | import { GridPaginationModel } from "@mui/x-data-grid"; 2 | import { useQuery } from "@tanstack/react-query"; 3 | 4 | import { GridSortModel } from "@mui/x-data-grid"; 5 | import { FileDataGridRow } from "@/fileManager/types/fileDataGridRow"; 6 | import { httpClient } from "@/shared/httpClient"; 7 | 8 | export function useFilesQuery({ 9 | paginationModel, 10 | sortModel, 11 | }: { 12 | paginationModel: GridPaginationModel; 13 | sortModel: GridSortModel; 14 | }) { 15 | return useQuery({ 16 | queryKey: ["files", { paginationModel, sortModel }], 17 | queryFn: async () => { 18 | const sortField = 19 | sortModel.length > 0 ? sortModel[0].field : "dateUploaded"; 20 | const sortOrder = sortModel.length > 0 ? sortModel[0].sort : "asc"; 21 | 22 | type Response = { 23 | totalFilesCount: number; 24 | files: FileDataGridRow[]; 25 | }; 26 | 27 | const { data } = await httpClient.get(`/files`, { 28 | params: { 29 | page: paginationModel.page, 30 | pageSize: paginationModel.pageSize, 31 | sortField, 32 | sortOrder, 33 | }, 34 | }); 35 | 36 | return data; 37 | }, 38 | }); 39 | } 40 | -------------------------------------------------------------------------------- /src/fileManager/types/ExtendedFile.ts: -------------------------------------------------------------------------------- 1 | export type ExtendedFile = { 2 | file: File; 3 | id: string; 4 | uploadProgress: number; 5 | uploadStatus: "idle" | "pending" | "error" | "success"; 6 | }; 7 | -------------------------------------------------------------------------------- /src/fileManager/types/FileDataGridRow.ts: -------------------------------------------------------------------------------- 1 | export type FileDataGridRow = { 2 | id: string; 3 | filename: string; 4 | size: number; 5 | dateUploaded: string; 6 | }; 7 | -------------------------------------------------------------------------------- /src/main.tsx: -------------------------------------------------------------------------------- 1 | import { App } from "@/App"; 2 | import { ConfirmProvider } from "@/shared/confirm/components/ConfirmProvider"; 3 | import { theme } from "@/shared/theme"; 4 | import { CssBaseline, ThemeProvider } from "@mui/material"; 5 | import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; 6 | import { StrictMode } from "react"; 7 | import { createRoot } from "react-dom/client"; 8 | 9 | const queryClient = new QueryClient(); 10 | 11 | createRoot(document.getElementById("root")!).render( 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | ); 23 | -------------------------------------------------------------------------------- /src/shared/confirm/components/ConfirmProvider.tsx: -------------------------------------------------------------------------------- 1 | import { ReactNode, useState } from "react"; 2 | 3 | import Button from "@mui/material/Button"; 4 | import DialogActions from "@mui/material/DialogActions"; 5 | import DialogContent from "@mui/material/DialogContent"; 6 | import DialogTitle from "@mui/material/DialogTitle"; 7 | 8 | import { Dialog as MuiDialog } from "@mui/material"; 9 | import { 10 | ConfirmContext, 11 | ConfirmOptions, 12 | } from "@/shared/confirm/hooks/useConfirm"; 13 | 14 | type ConfirmProviderProps = { 15 | children: ReactNode; 16 | }; 17 | 18 | export function ConfirmProvider({ children }: ConfirmProviderProps) { 19 | const [open, setOpen] = useState(false); 20 | const [options, setOptions] = useState(); 21 | 22 | function confirm(optionsArg: ConfirmOptions) { 23 | return new Promise(() => { 24 | setOptions(optionsArg); 25 | setOpen(true); 26 | }); 27 | } 28 | 29 | function handleClose() { 30 | setOpen(false); 31 | } 32 | 33 | function handleConfirm() { 34 | options?.handleConfirm(); 35 | handleClose(); 36 | } 37 | 38 | return ( 39 | <> 40 | 41 | {children} 42 | 43 | 50 | Confirm 51 | Are you sure? 52 | 53 | 54 | 57 | 60 | 61 | 62 | 63 | ); 64 | } 65 | -------------------------------------------------------------------------------- /src/shared/confirm/hooks/useConfirm.ts: -------------------------------------------------------------------------------- 1 | import { createContext, useContext } from "react"; 2 | 3 | type ConfirmOptions = { 4 | handleConfirm: () => void; 5 | }; 6 | 7 | type ConfirmContextType = (options: ConfirmOptions) => Promise; 8 | 9 | const ConfirmContext = createContext(undefined); 10 | 11 | function useConfirm() { 12 | const context = useContext(ConfirmContext); 13 | 14 | if (context === undefined) { 15 | throw new Error("useConfirm must be used within a ConfirmProvider"); 16 | } 17 | return context; 18 | } 19 | 20 | export { useConfirm, ConfirmContext, type ConfirmOptions }; 21 | -------------------------------------------------------------------------------- /src/shared/httpClient.ts: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | 3 | export const httpClient = axios.create({ 4 | baseURL: import.meta.env.VITE_API_URL, 5 | headers: { 6 | "Content-Type": "application/json", 7 | }, 8 | }); 9 | -------------------------------------------------------------------------------- /src/shared/theme.ts: -------------------------------------------------------------------------------- 1 | import { createTheme } from "@mui/material"; 2 | 3 | export const theme = createTheme({ 4 | components: { 5 | MuiButton: { styleOverrides: { root: { textTransform: "none" } } }, 6 | MuiPopover: { defaultProps: { elevation: 1 } }, 7 | MuiCard: { defaultProps: { elevation: 0 } }, 8 | }, 9 | shape: { borderRadius: 16 }, 10 | colorSchemes: { 11 | dark: true, 12 | }, 13 | }); 14 | -------------------------------------------------------------------------------- /src/shared/ui/BulkActions.tsx: -------------------------------------------------------------------------------- 1 | import CloseRoundedIcon from "@mui/icons-material/CloseRounded"; 2 | 3 | import LayersOutlinedIcon from "@mui/icons-material/LayersOutlined"; 4 | import { 5 | Paper, 6 | SpeedDial, 7 | SpeedDialAction, 8 | SpeedDialIcon, 9 | Stack, 10 | SxProps, 11 | Typography, 12 | } from "@mui/material"; 13 | 14 | import { ReactNode, useRef } from "react"; 15 | import { Transition } from "react-transition-group"; 16 | 17 | type Action = { 18 | icon: ReactNode; 19 | label: string; 20 | actionFn: (ids: string[]) => void | Promise; 21 | }; 22 | 23 | type Props = { 24 | ids: string[]; 25 | actions: Action[]; 26 | }; 27 | export function BulkActions({ actions, ids }: Props) { 28 | const nodeRef = useRef(null); 29 | 30 | const duration = 300; 31 | 32 | const transitionStyles: { [k: string]: SxProps } = { 33 | entering: { opacity: 1, bottom: 20 }, 34 | entered: { opacity: 1, bottom: 20 }, 35 | exiting: { opacity: 0, bottom: -10 }, 36 | exited: { opacity: 0, bottom: -10 }, 37 | }; 38 | 39 | return ( 40 | 0} timeout={duration}> 41 | {(state) => ( 42 | 56 | 57 | {ids.length} Selected items 58 | ({ 61 | position: "absolute", 62 | bottom: theme.spacing(1), 63 | right: theme.spacing(2), 64 | ".MuiSpeedDialAction-staticTooltipLabel": { 65 | width: "max-content", 66 | }, 67 | })} 68 | icon={ 69 | } 71 | openIcon={} 72 | /> 73 | } 74 | > 75 | {actions.map((action) => ( 76 | action.actionFn(ids)} 81 | key={action.label} 82 | /> 83 | ))} 84 | 85 | 86 | 87 | )} 88 | 89 | ); 90 | } 91 | -------------------------------------------------------------------------------- /src/shared/ui/ThemeToggle.tsx: -------------------------------------------------------------------------------- 1 | import ContrastRoundedIcon from "@mui/icons-material/ContrastRounded"; 2 | import DarkModeRoundedIcon from "@mui/icons-material/DarkModeRounded"; 3 | import LightModeRoundedIcon from "@mui/icons-material/LightModeRounded"; 4 | import { MenuItem, Select, useColorScheme } from "@mui/material"; 5 | 6 | export function ThemeToggle() { 7 | const { mode, setMode } = useColorScheme(); 8 | 9 | if (!mode || !setMode) { 10 | return null; 11 | } 12 | 13 | return ( 14 | 35 | ); 36 | } 37 | -------------------------------------------------------------------------------- /src/shared/ui/Topbar.tsx: -------------------------------------------------------------------------------- 1 | import { ThemeToggle } from "@/shared/ui/ThemeToggle"; 2 | import { AppBar, Box, Toolbar, Typography } from "@mui/material"; 3 | 4 | export function Topbar() { 5 | return ( 6 | 7 | 8 | 9 | 10 | File manager 11 | 12 | 13 | 14 | 15 | 16 | 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /src/shared/utils.ts: -------------------------------------------------------------------------------- 1 | function convertByteToMegabyte(size: number) { 2 | return `${((size ?? 0) / 1000000).toFixed(2)} MB`; 3 | } 4 | 5 | export { convertByteToMegabyte }; 6 | -------------------------------------------------------------------------------- /src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | interface ImportMetaEnv { 4 | readonly VITE_API_URL: string; 5 | } 6 | 7 | interface ImportMeta { 8 | readonly env: ImportMetaEnv; 9 | } 10 | -------------------------------------------------------------------------------- /tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "isolatedModules": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | "jsx": "react-jsx", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "paths": { 22 | "@/*": ["./src/*"] 23 | }, 24 | "noFallthroughCasesInSwitch": true 25 | }, 26 | "include": ["src"] 27 | } 28 | -------------------------------------------------------------------------------- /tsconfig.app.tsbuildinfo: -------------------------------------------------------------------------------- 1 | {"root":["./src/app.tsx","./src/main.tsx","./src/vite-env.d.ts","./src/filemanager/components/filemanager.tsx","./src/filemanager/components/filequickactions.tsx","./src/filemanager/components/filethumbnail.tsx","./src/filemanager/components/filesdatagrid.tsx","./src/filemanager/components/uploadprogresscard.tsx","./src/filemanager/hooks/usefiledeletemutation.ts","./src/filemanager/hooks/usefilemanagerstore.ts","./src/filemanager/hooks/usefileuploadmutation.ts","./src/filemanager/hooks/usefilesquery.ts","./src/filemanager/types/extendedfile.ts","./src/filemanager/types/filedatagridrow.ts","./src/shared/httpclient.ts","./src/shared/theme.ts","./src/shared/utils.ts","./src/shared/confirm/components/confirmprovider.tsx","./src/shared/confirm/hooks/useconfirm.ts","./src/shared/ui/bulkactions.tsx","./src/shared/ui/themetoggle.tsx","./src/shared/ui/topbar.tsx"],"version":"5.6.2"} -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { "path": "./tsconfig.app.json" }, 5 | { "path": "./tsconfig.node.json" } 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "lib": ["ES2023"], 5 | "module": "ESNext", 6 | "skipLibCheck": true, 7 | 8 | /* Bundler mode */ 9 | "moduleResolution": "bundler", 10 | "allowImportingTsExtensions": true, 11 | "isolatedModules": true, 12 | "moduleDetection": "force", 13 | "noEmit": true, 14 | 15 | /* Linting */ 16 | "strict": true, 17 | "noUnusedLocals": true, 18 | "noUnusedParameters": true, 19 | "noFallthroughCasesInSwitch": true 20 | }, 21 | "include": ["vite.config.ts"] 22 | } 23 | -------------------------------------------------------------------------------- /tsconfig.node.tsbuildinfo: -------------------------------------------------------------------------------- 1 | {"root":["./vite.config.ts"],"version":"5.6.2"} -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import react from "@vitejs/plugin-react-swc"; 3 | import path from "path"; 4 | 5 | // https://vitejs.dev/config/ 6 | export default defineConfig({ 7 | resolve: { 8 | alias: { 9 | "@": path.resolve("./src"), 10 | }, 11 | }, 12 | plugins: [react()], 13 | }); 14 | --------------------------------------------------------------------------------