commit 9f4187480c7afb768fa741fd1b4cd2a49e2aa781 Author: Georgi Gardev Date: Sun Feb 9 18:36:59 2025 +0200 Initial commit: reimplement in react diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/README.md b/README.md new file mode 100644 index 0000000..452bc30 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# vertex + +An extensible start page diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..092408a --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,28 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import tseslint from 'typescript-eslint' + +export default tseslint.config( + { ignores: ['dist'] }, + { + extends: [js.configs.recommended, ...tseslint.configs.recommended], + files: ['**/*.{ts,tsx}'], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + plugins: { + 'react-hooks': reactHooks, + 'react-refresh': reactRefresh, + }, + rules: { + ...reactHooks.configs.recommended.rules, + 'react-refresh/only-export-components': [ + 'warn', + { allowConstantExport: true }, + ], + }, + }, +) diff --git a/index.html b/index.html new file mode 100644 index 0000000..d2c471f --- /dev/null +++ b/index.html @@ -0,0 +1,21 @@ + + + + + + + + + + + + vertex · gar.dev + + +
+ + + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..2b7092e --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3569 @@ +{ + "name": "vertex", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "vertex", + "version": "0.0.1", + "dependencies": { + "@mantine/core": "^7.16.3", + "@mantine/hooks": "^7.16.3", + "@mantine/modals": "^7.16.3", + "@tabler/icons-react": "^3.30.0", + "date-fns": "^4.1.0", + "jotai": "^2.11.3", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "reset.css": "^2.0.2", + "unsplash-js": "^7.0.19" + }, + "devDependencies": { + "@eslint/js": "^9.19.0", + "@modyfi/vite-plugin-yaml": "^1.1.0", + "@types/node": "^22.13.1", + "@types/react": "^19.0.8", + "@types/react-dom": "^19.0.3", + "@vitejs/plugin-react": "^4.3.4", + "eslint": "^9.19.0", + "eslint-plugin-react-hooks": "^5.0.0", + "eslint-plugin-react-refresh": "^0.4.18", + "globals": "^15.14.0", + "postcss": "^8.5.1", + "postcss-preset-mantine": "^1.17.0", + "postcss-simple-vars": "^7.0.1", + "typescript": "~5.7.2", + "typescript-eslint": "^8.22.0", + "vite": "^5.1.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz", + "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.8.tgz", + "integrity": "sha512-l+lkXCHS6tQEc5oUpK28xBOZ6+HwaH7YwoYQbLFiYb4nS2/l1tKnZEtEWkD0GuiYdvArf9qBS0XlQGXzPMsNqQ==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.8", + "@babel/helper-compilation-targets": "^7.26.5", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.7", + "@babel/parser": "^7.26.8", + "@babel/template": "^7.26.8", + "@babel/traverse": "^7.26.8", + "@babel/types": "^7.26.8", + "@types/gensync": "^1.0.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.8.tgz", + "integrity": "sha512-ef383X5++iZHWAXX0SXQR6ZyQhw/0KtTkrTz61WXRhFM6dhpHulO/RJz79L8S6ugZHJkOOkUrUdxgdF2YiPFnA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.26.8", + "@babel/types": "^7.26.8", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz", + "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.26.5", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz", + "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.26.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.7.tgz", + "integrity": "sha512-8NHiL98vsi0mbPQmYAGWwfcFaOy4j2HY49fXJCfuDcdE7fMIsH9a7GdaeXpIBsbT7307WU8KCMp5pUVDNL4f9A==", + "dev": true, + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.8.tgz", + "integrity": "sha512-TZIQ25pkSoaKEYYaHbbxkfL36GNsQ6iFiBbeuzAkLnXayKR1yP1zFe+NxuZWWsUyvt8icPU9CCq0sgWGXR1GEw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.26.8" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz", + "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz", + "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.26.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.7.tgz", + "integrity": "sha512-AOPI3D+a8dXnja+iwsUqGRjr1BbZIe771sXdapOtYI531gSqpi92vXivKcq2asu/DFpdl1ceFAKZyRzK2PCVcQ==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.8.tgz", + "integrity": "sha512-iNKaX3ZebKIsCvJ+0jd6embf+Aulaa3vNBqZ41kM7iTWjx5qzWKXGHiJUW3+nTpQ18SG11hdF8OAzKrpXkb96Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/parser": "^7.26.8", + "@babel/types": "^7.26.8" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.8.tgz", + "integrity": "sha512-nic9tRkjYH0oB2dzr/JoGIm+4Q6SuYeLEiIiZDwBscRMYFJ+tMAz98fuel9ZnbXViA2I0HVSSRRK8DW5fjXStA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.8", + "@babel/parser": "^7.26.8", + "@babel/template": "^7.26.8", + "@babel/types": "^7.26.8", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.8.tgz", + "integrity": "sha512-eUuWapzEGWFEpHFxgEaBG8e3n6S8L3MSu0oda755rOfabWPnh0Our1AozNFVUxGFIhbKgd1ksprsoDGMinTOTA==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", + "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", + "dev": true, + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.11.0.tgz", + "integrity": "sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", + "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.20.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.20.0.tgz", + "integrity": "sha512-iZA07H9io9Wn836aVTytRaNqh00Sad+EamwOVJT12GTLw1VGMFV/4JaME+JjLtr9fiGaoWgYnS54wrfWsSs4oQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz", + "integrity": "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==", + "dev": true, + "dependencies": { + "@eslint/core": "^0.10.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz", + "integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.6.9", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.9.tgz", + "integrity": "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==", + "dependencies": { + "@floating-ui/utils": "^0.2.9" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.13", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.13.tgz", + "integrity": "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.9" + } + }, + "node_modules/@floating-ui/react": { + "version": "0.26.28", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.28.tgz", + "integrity": "sha512-yORQuuAtVpiRjpMhdc0wJj06b9JFjrYF4qp96j++v2NBpbi6SEGF7donUJ3TMieerQ6qVkAv1tgr7L4r5roTqw==", + "dependencies": { + "@floating-ui/react-dom": "^2.1.2", + "@floating-ui/utils": "^0.2.8", + "tabbable": "^6.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.2.tgz", + "integrity": "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==", + "dependencies": { + "@floating-ui/dom": "^1.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz", + "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==" + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", + "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mantine/core": { + "version": "7.16.3", + "resolved": "https://registry.npmjs.org/@mantine/core/-/core-7.16.3.tgz", + "integrity": "sha512-cxhIpfd2i0Zmk9TKdejYAoIvWouMGhzK3OOX+VRViZ5HEjnTQCGl2h3db56ThqB6NfVPCno6BPbt5lwekTtmuQ==", + "dependencies": { + "@floating-ui/react": "^0.26.28", + "clsx": "^2.1.1", + "react-number-format": "^5.4.3", + "react-remove-scroll": "^2.6.2", + "react-textarea-autosize": "8.5.6", + "type-fest": "^4.27.0" + }, + "peerDependencies": { + "@mantine/hooks": "7.16.3", + "react": "^18.x || ^19.x", + "react-dom": "^18.x || ^19.x" + } + }, + "node_modules/@mantine/hooks": { + "version": "7.16.3", + "resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-7.16.3.tgz", + "integrity": "sha512-B94FBWk5Sc81tAjV+B3dGh/gKzfqzpzVC/KHyBRWOOyJRqeeRbI/FAaJo4zwppyQo1POSl5ArdyjtDRrRIj2SQ==", + "peerDependencies": { + "react": "^18.x || ^19.x" + } + }, + "node_modules/@mantine/modals": { + "version": "7.16.3", + "resolved": "https://registry.npmjs.org/@mantine/modals/-/modals-7.16.3.tgz", + "integrity": "sha512-BJuDzRugK6xLbuFTTo8NLJumVvVmSYsNVcEtmlXOWTE3NkDGktBXGKo8V1B0XfJ9/d/rZw7HCE0p4i76MtA+bQ==", + "peerDependencies": { + "@mantine/core": "7.16.3", + "@mantine/hooks": "7.16.3", + "react": "^18.x || ^19.x", + "react-dom": "^18.x || ^19.x" + } + }, + "node_modules/@modyfi/vite-plugin-yaml": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@modyfi/vite-plugin-yaml/-/vite-plugin-yaml-1.1.0.tgz", + "integrity": "sha512-L26xfzkSo1yamODCAtk/ipVlL6OEw2bcJ92zunyHu8zxi7+meV0zefA9xscRMDCsMY8xL3C3wi3DhMiPxcbxbw==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "5.1.0", + "js-yaml": "4.1.0", + "tosource": "2.0.0-alpha.3" + }, + "peerDependencies": { + "vite": "^3.2.7 || ^4.0.5 || ^5.0.5" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", + "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.6.tgz", + "integrity": "sha512-+GcCXtOQoWuC7hhX1P00LqjjIiS/iOouHXhMdiDSnq/1DGTox4SpUvO52Xm+div6+106r+TcvOeo/cxvyEyTgg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.6.tgz", + "integrity": "sha512-E8+2qCIjciYUnCa1AiVF1BkRgqIGW9KzJeesQqVfyRITGQN+dFuoivO0hnro1DjT74wXLRZ7QF8MIbz+luGaJA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.6.tgz", + "integrity": "sha512-z9Ib+OzqN3DZEjX7PDQMHEhtF+t6Mi2z/ueChQPLS/qUMKY7Ybn5A2ggFoKRNRh1q1T03YTQfBTQCJZiepESAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.6.tgz", + "integrity": "sha512-PShKVY4u0FDAR7jskyFIYVyHEPCPnIQY8s5OcXkdU8mz3Y7eXDJPdyM/ZWjkYdR2m0izD9HHWA8sGcXn+Qrsyg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.6.tgz", + "integrity": "sha512-YSwyOqlDAdKqs0iKuqvRHLN4SrD2TiswfoLfvYXseKbL47ht1grQpq46MSiQAx6rQEN8o8URtpXARCpqabqxGQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.6.tgz", + "integrity": "sha512-HEP4CgPAY1RxXwwL5sPFv6BBM3tVeLnshF03HMhJYCNc6kvSqBgTMmsEjb72RkZBAWIqiPUyF1JpEBv5XT9wKQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.6.tgz", + "integrity": "sha512-88fSzjC5xeH9S2Vg3rPgXJULkHcLYMkh8faix8DX4h4TIAL65ekwuQMA/g2CXq8W+NJC43V6fUpYZNjaX3+IIg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.6.tgz", + "integrity": "sha512-wM4ztnutBqYFyvNeR7Av+reWI/enK9tDOTKNF+6Kk2Q96k9bwhDDOlnCUNRPvromlVXo04riSliMBs/Z7RteEg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.6.tgz", + "integrity": "sha512-9RyprECbRa9zEjXLtvvshhw4CMrRa3K+0wcp3KME0zmBe1ILmvcVHnypZ/aIDXpRyfhSYSuN4EPdCCj5Du8FIA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.6.tgz", + "integrity": "sha512-qTmklhCTyaJSB05S+iSovfo++EwnIEZxHkzv5dep4qoszUMX5Ca4WM4zAVUMbfdviLgCSQOu5oU8YoGk1s6M9Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.6.tgz", + "integrity": "sha512-4Qmkaps9yqmpjY5pvpkfOerYgKNUGzQpFxV6rnS7c/JfYbDSU0y6WpbbredB5cCpLFGJEqYX40WUmxMkwhWCjw==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.6.tgz", + "integrity": "sha512-Zsrtux3PuaxuBTX/zHdLaFmcofWGzaWW1scwLU3ZbW/X+hSsFbz9wDIp6XvnT7pzYRl9MezWqEqKy7ssmDEnuQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.6.tgz", + "integrity": "sha512-aK+Zp+CRM55iPrlyKiU3/zyhgzWBxLVrw2mwiQSYJRobCURb781+XstzvA8Gkjg/hbdQFuDw44aUOxVQFycrAg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.6.tgz", + "integrity": "sha512-WoKLVrY9ogmaYPXwTH326+ErlCIgMmsoRSx6bO+l68YgJnlOXhygDYSZe/qbUJCSiCiZAQ+tKm88NcWuUXqOzw==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.6.tgz", + "integrity": "sha512-Sht4aFvmA4ToHd2vFzwMFaQCiYm2lDFho5rPcvPBT5pCdC+GwHG6CMch4GQfmWTQ1SwRKS0dhDYb54khSrjDWw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.6.tgz", + "integrity": "sha512-zmmpOQh8vXc2QITsnCiODCDGXFC8LMi64+/oPpPx5qz3pqv0s6x46ps4xoycfUiVZps5PFn1gksZzo4RGTKT+A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.6.tgz", + "integrity": "sha512-3/q1qUsO/tLqGBaD4uXsB6coVGB3usxw3qyeVb59aArCgedSF66MPdgRStUd7vbZOsko/CgVaY5fo2vkvPLWiA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.6.tgz", + "integrity": "sha512-oLHxuyywc6efdKVTxvc0135zPrRdtYVjtVD5GUm55I3ODxhU/PwkQFD97z16Xzxa1Fz0AEe4W/2hzRtd+IfpOA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.6.tgz", + "integrity": "sha512-0PVwmgzZ8+TZ9oGBmdZoQVXflbvuwzN/HRclujpl4N/q3i+y0lqLw8n1bXA8ru3sApDjlmONaNAuYr38y1Kr9w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@tabler/icons": { + "version": "3.30.0", + "resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-3.30.0.tgz", + "integrity": "sha512-c8OKLM48l00u9TFbh2qhSODMONIzML8ajtCyq95rW8vzkWcBrKRPM61tdkThz2j4kd5u17srPGIjqdeRUZdfdw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/codecalm" + } + }, + "node_modules/@tabler/icons-react": { + "version": "3.30.0", + "resolved": "https://registry.npmjs.org/@tabler/icons-react/-/icons-react-3.30.0.tgz", + "integrity": "sha512-9KZ9D1UNAyjlLkkYp2HBPHdf6lAJ2aelDqh8YYAnnmLF3xwprWKxxW8+zw5jlI0IwdfN4XFFuzqePkaw+DpIOg==", + "dependencies": { + "@tabler/icons": "3.30.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/codecalm" + }, + "peerDependencies": { + "react": ">= 16" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true + }, + "node_modules/@types/gensync": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/gensync/-/gensync-1.0.4.tgz", + "integrity": "sha512-C3YYeRQWp2fmq9OryX+FoDy8nXS6scQ7dPptD8LnFDAUNcKWJjXQKDNJD3HVm+kOUsXhTOkpi69vI4EuAr95bA==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "22.13.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.1.tgz", + "integrity": "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==", + "dev": true, + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "node_modules/@types/react": { + "version": "19.0.8", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.8.tgz", + "integrity": "sha512-9P/o1IGdfmQxrujGbIMDyYaaCykhLKc0NGCtYcECNUr9UAaDe4gwvV9bR6tvd5Br1SG0j+PBpbKr2UYY8CwqSw==", + "devOptional": true, + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.0.3.tgz", + "integrity": "sha512-0Knk+HJiMP/qOZgMyNFamlIjw9OFCsyC2ZbigmEEyXXixgre6IQpm/4V+r3qH4GC1JPvRJKInw+on2rV6YZLeA==", + "dev": true, + "peerDependencies": { + "@types/react": "^19.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.23.0.tgz", + "integrity": "sha512-vBz65tJgRrA1Q5gWlRfvoH+w943dq9K1p1yDBY2pc+a1nbBLZp7fB9+Hk8DaALUbzjqlMfgaqlVPT1REJdkt/w==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.23.0", + "@typescript-eslint/type-utils": "8.23.0", + "@typescript-eslint/utils": "8.23.0", + "@typescript-eslint/visitor-keys": "8.23.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.0.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.23.0.tgz", + "integrity": "sha512-h2lUByouOXFAlMec2mILeELUbME5SZRN/7R9Cw2RD2lRQQY08MWMM+PmVVKKJNK1aIwqTo9t/0CvOxwPbRIE2Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "8.23.0", + "@typescript-eslint/types": "8.23.0", + "@typescript-eslint/typescript-estree": "8.23.0", + "@typescript-eslint/visitor-keys": "8.23.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.23.0.tgz", + "integrity": "sha512-OGqo7+dXHqI7Hfm+WqkZjKjsiRtFUQHPdGMXzk5mYXhJUedO7e/Y7i8AK3MyLMgZR93TX4bIzYrfyVjLC+0VSw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.23.0", + "@typescript-eslint/visitor-keys": "8.23.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.23.0.tgz", + "integrity": "sha512-iIuLdYpQWZKbiH+RkCGc6iu+VwscP5rCtQ1lyQ7TYuKLrcZoeJVpcLiG8DliXVkUxirW/PWlmS+d6yD51L9jvA==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "8.23.0", + "@typescript-eslint/utils": "8.23.0", + "debug": "^4.3.4", + "ts-api-utils": "^2.0.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.23.0.tgz", + "integrity": "sha512-1sK4ILJbCmZOTt9k4vkoulT6/y5CHJ1qUYxqpF1K/DBAd8+ZUL4LlSCxOssuH5m4rUaaN0uS0HlVPvd45zjduQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.23.0.tgz", + "integrity": "sha512-LcqzfipsB8RTvH8FX24W4UUFk1bl+0yTOf9ZA08XngFwMg4Kj8A+9hwz8Cr/ZS4KwHrmo9PJiLZkOt49vPnuvQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.23.0", + "@typescript-eslint/visitor-keys": "8.23.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.0.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.23.0.tgz", + "integrity": "sha512-uB/+PSo6Exu02b5ZEiVtmY6RVYO7YU5xqgzTIVZwTHvvK3HsL8tZZHFaTLFtRG3CsV4A5mhOv+NZx5BlhXPyIA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.23.0", + "@typescript-eslint/types": "8.23.0", + "@typescript-eslint/typescript-estree": "8.23.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.23.0.tgz", + "integrity": "sha512-oWWhcWDLwDfu++BGTZcmXWqpwtkwb5o7fxUIGksMQQDSdPW9prsSnfIOZMlsj4vBOSrcnjIUZMiIjODgGosFhQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.23.0", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz", + "integrity": "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==", + "dev": true, + "dependencies": { + "@babel/core": "^7.26.0", + "@babel/plugin-transform-react-jsx-self": "^7.25.9", + "@babel/plugin-transform-react-jsx-source": "^7.25.9", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.14.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" + } + }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001699", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001699.tgz", + "integrity": "sha512-b+uH5BakXZ9Do9iK+CkDmctUSEqZl+SP056vc5usa0PL+ev5OHw003rZXcnjNDv3L8P5j6rwT6C0BPKSikW08w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "devOptional": true + }, + "node_modules/date-fns": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz", + "integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.96", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.96.tgz", + "integrity": "sha512-8AJUW6dh75Fm/ny8+kZKJzI1pgoE8bKLZlzDU2W1ENd+DXKJrx7I7l9hb8UWR4ojlnb5OlixMt00QWiYJoVw1w==", + "dev": true + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.20.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.20.0.tgz", + "integrity": "sha512-aL4F8167Hg4IvsW89ejnpTwx+B/UQRzJPGgbIOl+4XqffWsahVVsLEWoZvnrVuwpWmnRd7XeXmQI1zlKcFDteA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.0", + "@eslint/core": "^0.11.0", + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "9.20.0", + "@eslint/plugin-kit": "^0.2.5", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.1.0.tgz", + "integrity": "sha512-mpJRtPgHN2tNAvZ35AMfqeB3Xqeo273QxrHJsbBEPWODRM4r0yB6jfoROqKEYrOn27UtRPpcpHc2UqyBSuUNTw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.19.tgz", + "integrity": "sha512-eyy8pcr/YxSYjBoqIFSrlbn9i/xvxUFa8CjzAYo9cFjgGXqq1hyjihcpZvxRLalpaWmueWR81xn7vuKmAFijDQ==", + "dev": true, + "peerDependencies": { + "eslint": ">=8.40" + } + }, + "node_modules/eslint-scope": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "dev": true, + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz", + "integrity": "sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", + "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "15.14.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.14.0.tgz", + "integrity": "sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/jotai": { + "version": "2.11.3", + "resolved": "https://registry.npmjs.org/jotai/-/jotai-2.11.3.tgz", + "integrity": "sha512-B/PsewAQ0UOS5e2+TTWegUPQ3SCLPCjPY24LYUjfn2EorGlluTA2dFjVLgF1+xHLjK9Jit3y5mKHyMG3Xq/GZg==", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=17.0.0", + "react": ">=17.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + } + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz", + "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-mixins": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/postcss-mixins/-/postcss-mixins-9.0.4.tgz", + "integrity": "sha512-XVq5jwQJDRu5M1XGkdpgASqLk37OqkH4JCFDXl/Dn7janOJjCTEKL+36cnRVy7bMtoBzALfO7bV7nTIsFnUWLA==", + "dev": true, + "dependencies": { + "fast-glob": "^3.2.11", + "postcss-js": "^4.0.0", + "postcss-simple-vars": "^7.0.0", + "sugarss": "^4.0.1" + }, + "engines": { + "node": ">=14.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-preset-mantine": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/postcss-preset-mantine/-/postcss-preset-mantine-1.17.0.tgz", + "integrity": "sha512-ji1PMDBUf2Vsx/HE5faMSs1+ff6qE6YRulTr4Ja+6HD3gop8rSMTCYdpN7KrdsEg079kfBKkO/PaKhG9uR0zwQ==", + "dev": true, + "dependencies": { + "postcss-mixins": "^9.0.4", + "postcss-nested": "^6.0.1" + }, + "peerDependencies": { + "postcss": ">=8.0.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-simple-vars": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-simple-vars/-/postcss-simple-vars-7.0.1.tgz", + "integrity": "sha512-5GLLXaS8qmzHMOjVxqkk1TZPf1jMqesiI7qLhnlyERalG0sMbHIbJqrcnrpmZdKCLglHnRHoEBB61RtGTsj++A==", + "dev": true, + "engines": { + "node": ">=14.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.1" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/react": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz", + "integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz", + "integrity": "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==", + "dependencies": { + "scheduler": "^0.25.0" + }, + "peerDependencies": { + "react": "^19.0.0" + } + }, + "node_modules/react-number-format": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/react-number-format/-/react-number-format-5.4.3.tgz", + "integrity": "sha512-VCY5hFg/soBighAoGcdE+GagkJq0230qN6jcS5sp8wQX1qy1fYN/RX7/BXkrs0oyzzwqR8/+eSUrqXbGeywdUQ==", + "peerDependencies": { + "react": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-refresh": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", + "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-remove-scroll": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.3.tgz", + "integrity": "sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==", + "dependencies": { + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.3", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.3" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "dependencies": { + "react-style-singleton": "^2.2.2", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "dependencies": { + "get-nonce": "^1.0.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-textarea-autosize": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.5.6.tgz", + "integrity": "sha512-aT3ioKXMa8f6zHYGebhbdMD2L00tKeRX1zuVuDx9YQK/JLLRSaSxq3ugECEmUB9z2kvk6bFSIoRHLkkUv0RJiw==", + "dependencies": { + "@babel/runtime": "^7.20.13", + "use-composed-ref": "^1.3.0", + "use-latest": "^1.2.1" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/reset.css": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/reset.css/-/reset.css-2.0.2.tgz", + "integrity": "sha512-HG5RQLYcAxou3yw+Gnzwan1jJCbOcIBZjwoD/YLWuAd8kkuDI/ZqC0uRhY4ReKOOJaM1Y1kvwebHOwK4P8Sevg==" + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.6.tgz", + "integrity": "sha512-wc2cBWqJgkU3Iz5oztRkQbfVkbxoz5EhnCGOrnJvnLnQ7O0WhQUYyv18qQI79O8L7DdHrrlJNeCHd4VGpnaXKQ==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.34.6", + "@rollup/rollup-android-arm64": "4.34.6", + "@rollup/rollup-darwin-arm64": "4.34.6", + "@rollup/rollup-darwin-x64": "4.34.6", + "@rollup/rollup-freebsd-arm64": "4.34.6", + "@rollup/rollup-freebsd-x64": "4.34.6", + "@rollup/rollup-linux-arm-gnueabihf": "4.34.6", + "@rollup/rollup-linux-arm-musleabihf": "4.34.6", + "@rollup/rollup-linux-arm64-gnu": "4.34.6", + "@rollup/rollup-linux-arm64-musl": "4.34.6", + "@rollup/rollup-linux-loongarch64-gnu": "4.34.6", + "@rollup/rollup-linux-powerpc64le-gnu": "4.34.6", + "@rollup/rollup-linux-riscv64-gnu": "4.34.6", + "@rollup/rollup-linux-s390x-gnu": "4.34.6", + "@rollup/rollup-linux-x64-gnu": "4.34.6", + "@rollup/rollup-linux-x64-musl": "4.34.6", + "@rollup/rollup-win32-arm64-msvc": "4.34.6", + "@rollup/rollup-win32-ia32-msvc": "4.34.6", + "@rollup/rollup-win32-x64-msvc": "4.34.6", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/scheduler": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.25.0.tgz", + "integrity": "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/sugarss": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-4.0.1.tgz", + "integrity": "sha512-WCjS5NfuVJjkQzK10s8WOBY+hhDxxNt/N6ZaGwxFZ+wN3/lKKFSaaKUNecULcTTvE4urLcKaZFQD8vO0mOZujw==", + "dev": true, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.3.3" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tosource": { + "version": "2.0.0-alpha.3", + "resolved": "https://registry.npmjs.org/tosource/-/tosource-2.0.0-alpha.3.tgz", + "integrity": "sha512-KAB2lrSS48y91MzFPFuDg4hLbvDiyTjOVgaK7Erw+5AmZXNq4sFRVn8r6yxSLuNs15PaokrDRpS61ERY9uZOug==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-api-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz", + "integrity": "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==", + "dev": true, + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "4.34.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.34.0.tgz", + "integrity": "sha512-Qcg88ZJsJvRcUijtD6supagRSDf0y1FPZh4NroJpwRkoPYj6gGNidREwTgDuC0Pmq0PVAAzL8C8BZW7xhx5Q4A==", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.23.0.tgz", + "integrity": "sha512-/LBRo3HrXr5LxmrdYSOCvoAMm7p2jNizNfbIpCgvG4HMsnoprRUOce/+8VJ9BDYWW68rqIENE/haVLWPeFZBVQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.23.0", + "@typescript-eslint/parser": "8.23.0", + "@typescript-eslint/utils": "8.23.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true + }, + "node_modules/unsplash-js": { + "version": "7.0.19", + "resolved": "https://registry.npmjs.org/unsplash-js/-/unsplash-js-7.0.19.tgz", + "integrity": "sha512-j6qT2floy5Q2g2d939FJpwey1yw/GpQecFiSouyJtsHQPj3oqmqq3K4rI+GF8vU1zwGCT7ZwIGQd2dtCQLjYJw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", + "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/use-callback-ref": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-composed-ref": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.4.0.tgz", + "integrity": "sha512-djviaxuOOh7wkj0paeO1Q/4wMZ8Zrnag5H6yBvzN7AKKe8beOaED9SF5/ByLqsku8NP4zQqsvM2u3ew/tJK8/w==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-isomorphic-layout-effect": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.2.0.tgz", + "integrity": "sha512-q6ayo8DWoPZT0VdG4u3D3uxcgONP3Mevx2i2b0434cwWBoL+aelL1DzkXI6w3PhTZzUeR2kaVlZn70iCiseP6w==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-latest": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.3.0.tgz", + "integrity": "sha512-mhg3xdm9NaM8q+gLT8KryJPnRFOz1/5XPBhmDEVZK1webPzDjrPk7f/mbpeLqTgB9msytYWANxgALOCJKnLvcQ==", + "dependencies": { + "use-isomorphic-layout-effect": "^1.1.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/vite": { + "version": "5.4.14", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz", + "integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..9ba1ee5 --- /dev/null +++ b/package.json @@ -0,0 +1,41 @@ +{ + "name": "vertex", + "private": true, + "version": "0.0.1", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint ." + }, + "dependencies": { + "@mantine/core": "^7.16.3", + "@mantine/hooks": "^7.16.3", + "@mantine/modals": "^7.16.3", + "@tabler/icons-react": "^3.30.0", + "date-fns": "^4.1.0", + "jotai": "^2.11.3", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "reset.css": "^2.0.2", + "unsplash-js": "^7.0.19" + }, + "devDependencies": { + "@eslint/js": "^9.19.0", + "@modyfi/vite-plugin-yaml": "^1.1.0", + "@types/node": "^22.13.1", + "@types/react": "^19.0.8", + "@types/react-dom": "^19.0.3", + "@vitejs/plugin-react": "^4.3.4", + "eslint": "^9.19.0", + "eslint-plugin-react-hooks": "^5.0.0", + "eslint-plugin-react-refresh": "^0.4.18", + "globals": "^15.14.0", + "postcss": "^8.5.1", + "postcss-preset-mantine": "^1.17.0", + "postcss-simple-vars": "^7.0.1", + "typescript": "~5.7.2", + "typescript-eslint": "^8.22.0", + "vite": "^5.1.0" + } +} diff --git a/postcss.config.cjs b/postcss.config.cjs new file mode 100644 index 0000000..bfba0dd --- /dev/null +++ b/postcss.config.cjs @@ -0,0 +1,14 @@ +module.exports = { + plugins: { + 'postcss-preset-mantine': {}, + 'postcss-simple-vars': { + variables: { + 'mantine-breakpoint-xs': '36em', + 'mantine-breakpoint-sm': '48em', + 'mantine-breakpoint-md': '62em', + 'mantine-breakpoint-lg': '75em', + 'mantine-breakpoint-xl': '88em', + }, + }, + }, +}; diff --git a/public/font/weathericons-regular-webfont.eot b/public/font/weathericons-regular-webfont.eot new file mode 100644 index 0000000..330b7ec Binary files /dev/null and b/public/font/weathericons-regular-webfont.eot differ diff --git a/public/font/weathericons-regular-webfont.svg b/public/font/weathericons-regular-webfont.svg new file mode 100644 index 0000000..397d730 --- /dev/null +++ b/public/font/weathericons-regular-webfont.svg @@ -0,0 +1,257 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/font/weathericons-regular-webfont.ttf b/public/font/weathericons-regular-webfont.ttf new file mode 100644 index 0000000..948f0a5 Binary files /dev/null and b/public/font/weathericons-regular-webfont.ttf differ diff --git a/public/font/weathericons-regular-webfont.woff b/public/font/weathericons-regular-webfont.woff new file mode 100644 index 0000000..e0b2f94 Binary files /dev/null and b/public/font/weathericons-regular-webfont.woff differ diff --git a/public/font/weathericons-regular-webfont.woff2 b/public/font/weathericons-regular-webfont.woff2 new file mode 100644 index 0000000..bb0c19d Binary files /dev/null and b/public/font/weathericons-regular-webfont.woff2 differ diff --git a/public/vite.svg b/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/weather-icons.min.css b/public/weather-icons.min.css new file mode 100644 index 0000000..fc94dca --- /dev/null +++ b/public/weather-icons.min.css @@ -0,0 +1,1842 @@ +/*! + * Weather Icons 2.0.10 + * Updated November 1, 2020 + * Weather themed icons for Bootstrap + * Author - Erik Flowers - erik@helloerik.com + * Email: erik@helloerik.com + * Twitter: http://twitter.com/Erik_UX + * ------------------------------------------------------------------------------ + * Maintained at http://erikflowers.github.io/weather-icons + * + * License + * ------------------------------------------------------------------------------ + * - Font licensed under SIL OFL 1.1 - + * http://scripts.sil.org/OFL + * - CSS, SCSS and LESS are licensed under MIT License - + * http://opensource.org/licenses/mit-license.html + * - Documentation licensed under CC BY 3.0 - + * http://creativecommons.org/licenses/by/3.0/ + * - Inspired by and works great as a companion with Font Awesome + * "Font Awesome by Dave Gandy - http://fontawesome.io" + */ +@font-face { + font-family: 'weathericons'; + src: url('../font/weathericons-regular-webfont.eot'); + src: url('../font/weathericons-regular-webfont.eot?#iefix') format('embedded-opentype'), + url('../font/weathericons-regular-webfont.woff2') format('woff2'), + url('../font/weathericons-regular-webfont.woff') format('woff'), + url('../font/weathericons-regular-webfont.ttf') format('truetype'), + url('../font/weathericons-regular-webfont.svg#weather_iconsregular') format('svg'); + font-weight: normal; + font-style: normal; +} +.wi { + display: inline-block; + font-family: 'weathericons'; + font-style: normal; + font-weight: normal; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.wi-fw { + text-align: center; + width: 1.4em; +} +.wi-rotate-90 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); + -webkit-transform: rotate(90deg); + -ms-transform: rotate(90deg); + transform: rotate(90deg); +} +.wi-rotate-180 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2); + -webkit-transform: rotate(180deg); + -ms-transform: rotate(180deg); + transform: rotate(180deg); +} +.wi-rotate-270 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); + -webkit-transform: rotate(270deg); + -ms-transform: rotate(270deg); + transform: rotate(270deg); +} +.wi-flip-horizontal { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1); + -webkit-transform: scale(-1, 1); + -ms-transform: scale(-1, 1); + transform: scale(-1, 1); +} +.wi-flip-vertical { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1); + -webkit-transform: scale(1, -1); + -ms-transform: scale(1, -1); + transform: scale(1, -1); +} +.wi-day-sunny:before { + content: '\f00d'; +} +.wi-day-cloudy:before { + content: '\f002'; +} +.wi-day-cloudy-gusts:before { + content: '\f000'; +} +.wi-day-cloudy-windy:before { + content: '\f001'; +} +.wi-day-fog:before { + content: '\f003'; +} +.wi-day-hail:before { + content: '\f004'; +} +.wi-day-haze:before { + content: '\f0b6'; +} +.wi-day-lightning:before { + content: '\f005'; +} +.wi-day-rain:before { + content: '\f008'; +} +.wi-day-rain-mix:before { + content: '\f006'; +} +.wi-day-rain-wind:before { + content: '\f007'; +} +.wi-day-showers:before { + content: '\f009'; +} +.wi-day-sleet:before { + content: '\f0b2'; +} +.wi-day-sleet-storm:before { + content: '\f068'; +} +.wi-day-snow:before { + content: '\f00a'; +} +.wi-day-snow-thunderstorm:before { + content: '\f06b'; +} +.wi-day-snow-wind:before { + content: '\f065'; +} +.wi-day-sprinkle:before { + content: '\f00b'; +} +.wi-day-storm-showers:before { + content: '\f00e'; +} +.wi-day-sunny-overcast:before { + content: '\f00c'; +} +.wi-day-thunderstorm:before { + content: '\f010'; +} +.wi-day-windy:before { + content: '\f085'; +} +.wi-solar-eclipse:before { + content: '\f06e'; +} +.wi-hot:before { + content: '\f072'; +} +.wi-day-cloudy-high:before { + content: '\f07d'; +} +.wi-day-light-wind:before { + content: '\f0c4'; +} +.wi-night-clear:before { + content: '\f02e'; +} +.wi-night-alt-cloudy:before { + content: '\f086'; +} +.wi-night-alt-cloudy-gusts:before { + content: '\f022'; +} +.wi-night-alt-cloudy-windy:before { + content: '\f023'; +} +.wi-night-alt-hail:before { + content: '\f024'; +} +.wi-night-alt-lightning:before { + content: '\f025'; +} +.wi-night-alt-rain:before { + content: '\f028'; +} +.wi-night-alt-rain-mix:before { + content: '\f026'; +} +.wi-night-alt-rain-wind:before { + content: '\f027'; +} +.wi-night-alt-showers:before { + content: '\f029'; +} +.wi-night-alt-sleet:before { + content: '\f0b4'; +} +.wi-night-alt-sleet-storm:before { + content: '\f06a'; +} +.wi-night-alt-snow:before { + content: '\f02a'; +} +.wi-night-alt-snow-thunderstorm:before { + content: '\f06d'; +} +.wi-night-alt-snow-wind:before { + content: '\f067'; +} +.wi-night-alt-sprinkle:before { + content: '\f02b'; +} +.wi-night-alt-storm-showers:before { + content: '\f02c'; +} +.wi-night-alt-thunderstorm:before { + content: '\f02d'; +} +.wi-night-cloudy:before { + content: '\f031'; +} +.wi-night-cloudy-gusts:before { + content: '\f02f'; +} +.wi-night-cloudy-windy:before { + content: '\f030'; +} +.wi-night-fog:before { + content: '\f04a'; +} +.wi-night-hail:before { + content: '\f032'; +} +.wi-night-lightning:before { + content: '\f033'; +} +.wi-night-partly-cloudy:before { + content: '\f083'; +} +.wi-night-rain:before { + content: '\f036'; +} +.wi-night-rain-mix:before { + content: '\f034'; +} +.wi-night-rain-wind:before { + content: '\f035'; +} +.wi-night-showers:before { + content: '\f037'; +} +.wi-night-sleet:before { + content: '\f0b3'; +} +.wi-night-sleet-storm:before { + content: '\f069'; +} +.wi-night-snow:before { + content: '\f038'; +} +.wi-night-snow-thunderstorm:before { + content: '\f06c'; +} +.wi-night-snow-wind:before { + content: '\f066'; +} +.wi-night-sprinkle:before { + content: '\f039'; +} +.wi-night-storm-showers:before { + content: '\f03a'; +} +.wi-night-thunderstorm:before { + content: '\f03b'; +} +.wi-lunar-eclipse:before { + content: '\f070'; +} +.wi-stars:before { + content: '\f077'; +} +.wi-storm-showers:before { + content: '\f01d'; +} +.wi-thunderstorm:before { + content: '\f01e'; +} +.wi-night-alt-cloudy-high:before { + content: '\f07e'; +} +.wi-night-cloudy-high:before { + content: '\f080'; +} +.wi-night-alt-partly-cloudy:before { + content: '\f081'; +} +.wi-cloud:before { + content: '\f041'; +} +.wi-cloudy:before { + content: '\f013'; +} +.wi-cloudy-gusts:before { + content: '\f011'; +} +.wi-cloudy-windy:before { + content: '\f012'; +} +.wi-fog:before { + content: '\f014'; +} +.wi-hail:before { + content: '\f015'; +} +.wi-rain:before { + content: '\f019'; +} +.wi-rain-mix:before { + content: '\f017'; +} +.wi-rain-wind:before { + content: '\f018'; +} +.wi-showers:before { + content: '\f01a'; +} +.wi-sleet:before { + content: '\f0b5'; +} +.wi-snow:before { + content: '\f01b'; +} +.wi-sprinkle:before { + content: '\f01c'; +} +.wi-storm-showers:before { + content: '\f01d'; +} +.wi-thunderstorm:before { + content: '\f01e'; +} +.wi-snow-wind:before { + content: '\f064'; +} +.wi-snow:before { + content: '\f01b'; +} +.wi-smog:before { + content: '\f074'; +} +.wi-smoke:before { + content: '\f062'; +} +.wi-lightning:before { + content: '\f016'; +} +.wi-raindrops:before { + content: '\f04e'; +} +.wi-raindrop:before { + content: '\f078'; +} +.wi-dust:before { + content: '\f063'; +} +.wi-snowflake-cold:before { + content: '\f076'; +} +.wi-windy:before { + content: '\f021'; +} +.wi-strong-wind:before { + content: '\f050'; +} +.wi-sandstorm:before { + content: '\f082'; +} +.wi-earthquake:before { + content: '\f0c6'; +} +.wi-fire:before { + content: '\f0c7'; +} +.wi-flood:before { + content: '\f07c'; +} +.wi-meteor:before { + content: '\f071'; +} +.wi-tsunami:before { + content: '\f0c5'; +} +.wi-volcano:before { + content: '\f0c8'; +} +.wi-hurricane:before { + content: '\f073'; +} +.wi-tornado:before { + content: '\f056'; +} +.wi-small-craft-advisory:before { + content: '\f0cc'; +} +.wi-gale-warning:before { + content: '\f0cd'; +} +.wi-storm-warning:before { + content: '\f0ce'; +} +.wi-hurricane-warning:before { + content: '\f0cf'; +} +.wi-wind-direction:before { + content: '\f0b1'; +} +.wi-alien:before { + content: '\f075'; +} +.wi-celsius:before { + content: '\f03c'; +} +.wi-fahrenheit:before { + content: '\f045'; +} +.wi-degrees:before { + content: '\f042'; +} +.wi-thermometer:before { + content: '\f055'; +} +.wi-thermometer-exterior:before { + content: '\f053'; +} +.wi-thermometer-internal:before { + content: '\f054'; +} +.wi-cloud-down:before { + content: '\f03d'; +} +.wi-cloud-up:before { + content: '\f040'; +} +.wi-cloud-refresh:before { + content: '\f03e'; +} +.wi-horizon:before { + content: '\f047'; +} +.wi-horizon-alt:before { + content: '\f046'; +} +.wi-sunrise:before { + content: '\f051'; +} +.wi-sunset:before { + content: '\f052'; +} +.wi-moonrise:before { + content: '\f0c9'; +} +.wi-moonset:before { + content: '\f0ca'; +} +.wi-refresh:before { + content: '\f04c'; +} +.wi-refresh-alt:before { + content: '\f04b'; +} +.wi-umbrella:before { + content: '\f084'; +} +.wi-barometer:before { + content: '\f079'; +} +.wi-humidity:before { + content: '\f07a'; +} +.wi-na:before { + content: '\f07b'; +} +.wi-train:before { + content: '\f0cb'; +} +.wi-moon-new:before { + content: '\f095'; +} +.wi-moon-waxing-crescent-1:before { + content: '\f096'; +} +.wi-moon-waxing-crescent-2:before { + content: '\f097'; +} +.wi-moon-waxing-crescent-3:before { + content: '\f098'; +} +.wi-moon-waxing-crescent-4:before { + content: '\f099'; +} +.wi-moon-waxing-crescent-5:before { + content: '\f09a'; +} +.wi-moon-waxing-crescent-6:before { + content: '\f09b'; +} +.wi-moon-first-quarter:before { + content: '\f09c'; +} +.wi-moon-waxing-gibbous-1:before { + content: '\f09d'; +} +.wi-moon-waxing-gibbous-2:before { + content: '\f09e'; +} +.wi-moon-waxing-gibbous-3:before { + content: '\f09f'; +} +.wi-moon-waxing-gibbous-4:before { + content: '\f0a0'; +} +.wi-moon-waxing-gibbous-5:before { + content: '\f0a1'; +} +.wi-moon-waxing-gibbous-6:before { + content: '\f0a2'; +} +.wi-moon-full:before { + content: '\f0a3'; +} +.wi-moon-waning-gibbous-1:before { + content: '\f0a4'; +} +.wi-moon-waning-gibbous-2:before { + content: '\f0a5'; +} +.wi-moon-waning-gibbous-3:before { + content: '\f0a6'; +} +.wi-moon-waning-gibbous-4:before { + content: '\f0a7'; +} +.wi-moon-waning-gibbous-5:before { + content: '\f0a8'; +} +.wi-moon-waning-gibbous-6:before { + content: '\f0a9'; +} +.wi-moon-third-quarter:before { + content: '\f0aa'; +} +.wi-moon-waning-crescent-1:before { + content: '\f0ab'; +} +.wi-moon-waning-crescent-2:before { + content: '\f0ac'; +} +.wi-moon-waning-crescent-3:before { + content: '\f0ad'; +} +.wi-moon-waning-crescent-4:before { + content: '\f0ae'; +} +.wi-moon-waning-crescent-5:before { + content: '\f0af'; +} +.wi-moon-waning-crescent-6:before { + content: '\f0b0'; +} +.wi-moon-alt-new:before { + content: '\f0eb'; +} +.wi-moon-alt-waxing-crescent-1:before { + content: '\f0d0'; +} +.wi-moon-alt-waxing-crescent-2:before { + content: '\f0d1'; +} +.wi-moon-alt-waxing-crescent-3:before { + content: '\f0d2'; +} +.wi-moon-alt-waxing-crescent-4:before { + content: '\f0d3'; +} +.wi-moon-alt-waxing-crescent-5:before { + content: '\f0d4'; +} +.wi-moon-alt-waxing-crescent-6:before { + content: '\f0d5'; +} +.wi-moon-alt-first-quarter:before { + content: '\f0d6'; +} +.wi-moon-alt-waxing-gibbous-1:before { + content: '\f0d7'; +} +.wi-moon-alt-waxing-gibbous-2:before { + content: '\f0d8'; +} +.wi-moon-alt-waxing-gibbous-3:before { + content: '\f0d9'; +} +.wi-moon-alt-waxing-gibbous-4:before { + content: '\f0da'; +} +.wi-moon-alt-waxing-gibbous-5:before { + content: '\f0db'; +} +.wi-moon-alt-waxing-gibbous-6:before { + content: '\f0dc'; +} +.wi-moon-alt-full:before { + content: '\f0dd'; +} +.wi-moon-alt-waning-gibbous-1:before { + content: '\f0de'; +} +.wi-moon-alt-waning-gibbous-2:before { + content: '\f0df'; +} +.wi-moon-alt-waning-gibbous-3:before { + content: '\f0e0'; +} +.wi-moon-alt-waning-gibbous-4:before { + content: '\f0e1'; +} +.wi-moon-alt-waning-gibbous-5:before { + content: '\f0e2'; +} +.wi-moon-alt-waning-gibbous-6:before { + content: '\f0e3'; +} +.wi-moon-alt-third-quarter:before { + content: '\f0e4'; +} +.wi-moon-alt-waning-crescent-1:before { + content: '\f0e5'; +} +.wi-moon-alt-waning-crescent-2:before { + content: '\f0e6'; +} +.wi-moon-alt-waning-crescent-3:before { + content: '\f0e7'; +} +.wi-moon-alt-waning-crescent-4:before { + content: '\f0e8'; +} +.wi-moon-alt-waning-crescent-5:before { + content: '\f0e9'; +} +.wi-moon-alt-waning-crescent-6:before { + content: '\f0ea'; +} +.wi-moon-0:before { + content: '\f095'; +} +.wi-moon-1:before { + content: '\f096'; +} +.wi-moon-2:before { + content: '\f097'; +} +.wi-moon-3:before { + content: '\f098'; +} +.wi-moon-4:before { + content: '\f099'; +} +.wi-moon-5:before { + content: '\f09a'; +} +.wi-moon-6:before { + content: '\f09b'; +} +.wi-moon-7:before { + content: '\f09c'; +} +.wi-moon-8:before { + content: '\f09d'; +} +.wi-moon-9:before { + content: '\f09e'; +} +.wi-moon-10:before { + content: '\f09f'; +} +.wi-moon-11:before { + content: '\f0a0'; +} +.wi-moon-12:before { + content: '\f0a1'; +} +.wi-moon-13:before { + content: '\f0a2'; +} +.wi-moon-14:before { + content: '\f0a3'; +} +.wi-moon-15:before { + content: '\f0a4'; +} +.wi-moon-16:before { + content: '\f0a5'; +} +.wi-moon-17:before { + content: '\f0a6'; +} +.wi-moon-18:before { + content: '\f0a7'; +} +.wi-moon-19:before { + content: '\f0a8'; +} +.wi-moon-20:before { + content: '\f0a9'; +} +.wi-moon-21:before { + content: '\f0aa'; +} +.wi-moon-22:before { + content: '\f0ab'; +} +.wi-moon-23:before { + content: '\f0ac'; +} +.wi-moon-24:before { + content: '\f0ad'; +} +.wi-moon-25:before { + content: '\f0ae'; +} +.wi-moon-26:before { + content: '\f0af'; +} +.wi-moon-27:before { + content: '\f0b0'; +} +.wi-time-1:before { + content: '\f08a'; +} +.wi-time-2:before { + content: '\f08b'; +} +.wi-time-3:before { + content: '\f08c'; +} +.wi-time-4:before { + content: '\f08d'; +} +.wi-time-5:before { + content: '\f08e'; +} +.wi-time-6:before { + content: '\f08f'; +} +.wi-time-7:before { + content: '\f090'; +} +.wi-time-8:before { + content: '\f091'; +} +.wi-time-9:before { + content: '\f092'; +} +.wi-time-10:before { + content: '\f093'; +} +.wi-time-11:before { + content: '\f094'; +} +.wi-time-12:before { + content: '\f089'; +} +.wi-direction-up:before { + content: '\f058'; +} +.wi-direction-up-right:before { + content: '\f057'; +} +.wi-direction-right:before { + content: '\f04d'; +} +.wi-direction-down-right:before { + content: '\f088'; +} +.wi-direction-down:before { + content: '\f044'; +} +.wi-direction-down-left:before { + content: '\f043'; +} +.wi-direction-left:before { + content: '\f048'; +} +.wi-direction-up-left:before { + content: '\f087'; +} +.wi-wind-beaufort-0:before { + content: '\f0b7'; +} +.wi-wind-beaufort-1:before { + content: '\f0b8'; +} +.wi-wind-beaufort-2:before { + content: '\f0b9'; +} +.wi-wind-beaufort-3:before { + content: '\f0ba'; +} +.wi-wind-beaufort-4:before { + content: '\f0bb'; +} +.wi-wind-beaufort-5:before { + content: '\f0bc'; +} +.wi-wind-beaufort-6:before { + content: '\f0bd'; +} +.wi-wind-beaufort-7:before { + content: '\f0be'; +} +.wi-wind-beaufort-8:before { + content: '\f0bf'; +} +.wi-wind-beaufort-9:before { + content: '\f0c0'; +} +.wi-wind-beaufort-10:before { + content: '\f0c1'; +} +.wi-wind-beaufort-11:before { + content: '\f0c2'; +} +.wi-wind-beaufort-12:before { + content: '\f0c3'; +} +.wi-yahoo-0:before { + content: '\f056'; +} +.wi-yahoo-1:before { + content: '\f00e'; +} +.wi-yahoo-2:before { + content: '\f073'; +} +.wi-yahoo-3:before { + content: '\f01e'; +} +.wi-yahoo-4:before { + content: '\f01e'; +} +.wi-yahoo-5:before { + content: '\f017'; +} +.wi-yahoo-6:before { + content: '\f017'; +} +.wi-yahoo-7:before { + content: '\f017'; +} +.wi-yahoo-8:before { + content: '\f015'; +} +.wi-yahoo-9:before { + content: '\f01a'; +} +.wi-yahoo-10:before { + content: '\f015'; +} +.wi-yahoo-11:before { + content: '\f01a'; +} +.wi-yahoo-12:before { + content: '\f01a'; +} +.wi-yahoo-13:before { + content: '\f01b'; +} +.wi-yahoo-14:before { + content: '\f00a'; +} +.wi-yahoo-15:before { + content: '\f064'; +} +.wi-yahoo-16:before { + content: '\f01b'; +} +.wi-yahoo-17:before { + content: '\f015'; +} +.wi-yahoo-18:before { + content: '\f017'; +} +.wi-yahoo-19:before { + content: '\f063'; +} +.wi-yahoo-20:before { + content: '\f014'; +} +.wi-yahoo-21:before { + content: '\f021'; +} +.wi-yahoo-22:before { + content: '\f062'; +} +.wi-yahoo-23:before { + content: '\f050'; +} +.wi-yahoo-24:before { + content: '\f050'; +} +.wi-yahoo-25:before { + content: '\f076'; +} +.wi-yahoo-26:before { + content: '\f013'; +} +.wi-yahoo-27:before { + content: '\f031'; +} +.wi-yahoo-28:before { + content: '\f002'; +} +.wi-yahoo-29:before { + content: '\f031'; +} +.wi-yahoo-30:before { + content: '\f002'; +} +.wi-yahoo-31:before { + content: '\f02e'; +} +.wi-yahoo-32:before { + content: '\f00d'; +} +.wi-yahoo-33:before { + content: '\f083'; +} +.wi-yahoo-34:before { + content: '\f00c'; +} +.wi-yahoo-35:before { + content: '\f017'; +} +.wi-yahoo-36:before { + content: '\f072'; +} +.wi-yahoo-37:before { + content: '\f00e'; +} +.wi-yahoo-38:before { + content: '\f00e'; +} +.wi-yahoo-39:before { + content: '\f00e'; +} +.wi-yahoo-40:before { + content: '\f01a'; +} +.wi-yahoo-41:before { + content: '\f064'; +} +.wi-yahoo-42:before { + content: '\f01b'; +} +.wi-yahoo-43:before { + content: '\f064'; +} +.wi-yahoo-44:before { + content: '\f00c'; +} +.wi-yahoo-45:before { + content: '\f00e'; +} +.wi-yahoo-46:before { + content: '\f01b'; +} +.wi-yahoo-47:before { + content: '\f00e'; +} +.wi-yahoo-3200:before { + content: '\f077'; +} +.wi-forecast-io-clear-day:before { + content: '\f00d'; +} +.wi-forecast-io-clear-night:before { + content: '\f02e'; +} +.wi-forecast-io-rain:before { + content: '\f019'; +} +.wi-forecast-io-snow:before { + content: '\f01b'; +} +.wi-forecast-io-sleet:before { + content: '\f0b5'; +} +.wi-forecast-io-wind:before { + content: '\f050'; +} +.wi-forecast-io-fog:before { + content: '\f014'; +} +.wi-forecast-io-cloudy:before { + content: '\f013'; +} +.wi-forecast-io-partly-cloudy-day:before { + content: '\f002'; +} +.wi-forecast-io-partly-cloudy-night:before { + content: '\f031'; +} +.wi-forecast-io-hail:before { + content: '\f015'; +} +.wi-forecast-io-thunderstorm:before { + content: '\f01e'; +} +.wi-forecast-io-tornado:before { + content: '\f056'; +} +.wi-wmo4680-0:before, +.wi-wmo4680-00:before { + content: '\f055'; +} +.wi-wmo4680-1:before, +.wi-wmo4680-01:before { + content: '\f013'; +} +.wi-wmo4680-2:before, +.wi-wmo4680-02:before { + content: '\f055'; +} +.wi-wmo4680-3:before, +.wi-wmo4680-03:before { + content: '\f013'; +} +.wi-wmo4680-4:before, +.wi-wmo4680-04:before { + content: '\f014'; +} +.wi-wmo4680-5:before, +.wi-wmo4680-05:before { + content: '\f014'; +} +.wi-wmo4680-10:before { + content: '\f014'; +} +.wi-wmo4680-11:before { + content: '\f014'; +} +.wi-wmo4680-12:before { + content: '\f016'; +} +.wi-wmo4680-18:before { + content: '\f050'; +} +.wi-wmo4680-20:before { + content: '\f014'; +} +.wi-wmo4680-21:before { + content: '\f017'; +} +.wi-wmo4680-22:before { + content: '\f017'; +} +.wi-wmo4680-23:before { + content: '\f019'; +} +.wi-wmo4680-24:before { + content: '\f01b'; +} +.wi-wmo4680-25:before { + content: '\f015'; +} +.wi-wmo4680-26:before { + content: '\f01e'; +} +.wi-wmo4680-27:before { + content: '\f063'; +} +.wi-wmo4680-28:before { + content: '\f063'; +} +.wi-wmo4680-29:before { + content: '\f063'; +} +.wi-wmo4680-30:before { + content: '\f014'; +} +.wi-wmo4680-31:before { + content: '\f014'; +} +.wi-wmo4680-32:before { + content: '\f014'; +} +.wi-wmo4680-33:before { + content: '\f014'; +} +.wi-wmo4680-34:before { + content: '\f014'; +} +.wi-wmo4680-35:before { + content: '\f014'; +} +.wi-wmo4680-40:before { + content: '\f017'; +} +.wi-wmo4680-41:before { + content: '\f01c'; +} +.wi-wmo4680-42:before { + content: '\f019'; +} +.wi-wmo4680-43:before { + content: '\f01c'; +} +.wi-wmo4680-44:before { + content: '\f019'; +} +.wi-wmo4680-45:before { + content: '\f015'; +} +.wi-wmo4680-46:before { + content: '\f015'; +} +.wi-wmo4680-47:before { + content: '\f01b'; +} +.wi-wmo4680-48:before { + content: '\f01b'; +} +.wi-wmo4680-50:before { + content: '\f01c'; +} +.wi-wmo4680-51:before { + content: '\f01c'; +} +.wi-wmo4680-52:before { + content: '\f019'; +} +.wi-wmo4680-53:before { + content: '\f019'; +} +.wi-wmo4680-54:before { + content: '\f076'; +} +.wi-wmo4680-55:before { + content: '\f076'; +} +.wi-wmo4680-56:before { + content: '\f076'; +} +.wi-wmo4680-57:before { + content: '\f01c'; +} +.wi-wmo4680-58:before { + content: '\f019'; +} +.wi-wmo4680-60:before { + content: '\f01c'; +} +.wi-wmo4680-61:before { + content: '\f01c'; +} +.wi-wmo4680-62:before { + content: '\f019'; +} +.wi-wmo4680-63:before { + content: '\f019'; +} +.wi-wmo4680-64:before { + content: '\f015'; +} +.wi-wmo4680-65:before { + content: '\f015'; +} +.wi-wmo4680-66:before { + content: '\f015'; +} +.wi-wmo4680-67:before { + content: '\f017'; +} +.wi-wmo4680-68:before { + content: '\f017'; +} +.wi-wmo4680-70:before { + content: '\f01b'; +} +.wi-wmo4680-71:before { + content: '\f01b'; +} +.wi-wmo4680-72:before { + content: '\f01b'; +} +.wi-wmo4680-73:before { + content: '\f01b'; +} +.wi-wmo4680-74:before { + content: '\f076'; +} +.wi-wmo4680-75:before { + content: '\f076'; +} +.wi-wmo4680-76:before { + content: '\f076'; +} +.wi-wmo4680-77:before { + content: '\f01b'; +} +.wi-wmo4680-78:before { + content: '\f076'; +} +.wi-wmo4680-80:before { + content: '\f019'; +} +.wi-wmo4680-81:before { + content: '\f01c'; +} +.wi-wmo4680-82:before { + content: '\f019'; +} +.wi-wmo4680-83:before { + content: '\f019'; +} +.wi-wmo4680-84:before { + content: '\f01d'; +} +.wi-wmo4680-85:before { + content: '\f017'; +} +.wi-wmo4680-86:before { + content: '\f017'; +} +.wi-wmo4680-87:before { + content: '\f017'; +} +.wi-wmo4680-89:before { + content: '\f015'; +} +.wi-wmo4680-90:before { + content: '\f016'; +} +.wi-wmo4680-91:before { + content: '\f01d'; +} +.wi-wmo4680-92:before { + content: '\f01e'; +} +.wi-wmo4680-93:before { + content: '\f01e'; +} +.wi-wmo4680-94:before { + content: '\f016'; +} +.wi-wmo4680-95:before { + content: '\f01e'; +} +.wi-wmo4680-96:before { + content: '\f01e'; +} +.wi-wmo4680-99:before { + content: '\f056'; +} +.wi-owm-200:before { + content: '\f01e'; +} +.wi-owm-201:before { + content: '\f01e'; +} +.wi-owm-202:before { + content: '\f01e'; +} +.wi-owm-210:before { + content: '\f016'; +} +.wi-owm-211:before { + content: '\f016'; +} +.wi-owm-212:before { + content: '\f016'; +} +.wi-owm-221:before { + content: '\f016'; +} +.wi-owm-230:before { + content: '\f01e'; +} +.wi-owm-231:before { + content: '\f01e'; +} +.wi-owm-232:before { + content: '\f01e'; +} +.wi-owm-300:before { + content: '\f01c'; +} +.wi-owm-301:before { + content: '\f01c'; +} +.wi-owm-302:before { + content: '\f019'; +} +.wi-owm-310:before { + content: '\f017'; +} +.wi-owm-311:before { + content: '\f019'; +} +.wi-owm-312:before { + content: '\f019'; +} +.wi-owm-313:before { + content: '\f01a'; +} +.wi-owm-314:before { + content: '\f019'; +} +.wi-owm-321:before { + content: '\f01c'; +} +.wi-owm-500:before { + content: '\f01c'; +} +.wi-owm-501:before { + content: '\f019'; +} +.wi-owm-502:before { + content: '\f019'; +} +.wi-owm-503:before { + content: '\f019'; +} +.wi-owm-504:before { + content: '\f019'; +} +.wi-owm-511:before { + content: '\f017'; +} +.wi-owm-520:before { + content: '\f01a'; +} +.wi-owm-521:before { + content: '\f01a'; +} +.wi-owm-522:before { + content: '\f01a'; +} +.wi-owm-531:before { + content: '\f01d'; +} +.wi-owm-600:before { + content: '\f01b'; +} +.wi-owm-601:before { + content: '\f01b'; +} +.wi-owm-602:before { + content: '\f0b5'; +} +.wi-owm-611:before { + content: '\f017'; +} +.wi-owm-612:before { + content: '\f017'; +} +.wi-owm-615:before { + content: '\f017'; +} +.wi-owm-616:before { + content: '\f017'; +} +.wi-owm-620:before { + content: '\f017'; +} +.wi-owm-621:before { + content: '\f01b'; +} +.wi-owm-622:before { + content: '\f01b'; +} +.wi-owm-701:before { + content: '\f014'; +} +.wi-owm-711:before { + content: '\f062'; +} +.wi-owm-721:before { + content: '\f0b6'; +} +.wi-owm-731:before { + content: '\f063'; +} +.wi-owm-741:before { + content: '\f014'; +} +.wi-owm-761:before { + content: '\f063'; +} +.wi-owm-762:before { + content: '\f063'; +} +.wi-owm-771:before { + content: '\f011'; +} +.wi-owm-781:before { + content: '\f056'; +} +.wi-owm-800:before { + content: '\f00d'; +} +.wi-owm-801:before { + content: '\f041'; +} +.wi-owm-802:before { + content: '\f041'; +} +.wi-owm-803:before { + content: '\f013'; +} +.wi-owm-804:before { + content: '\f013'; +} +.wi-owm-900:before { + content: '\f056'; +} +.wi-owm-901:before { + content: '\f01d'; +} +.wi-owm-902:before { + content: '\f073'; +} +.wi-owm-903:before { + content: '\f076'; +} +.wi-owm-904:before { + content: '\f072'; +} +.wi-owm-905:before { + content: '\f021'; +} +.wi-owm-906:before { + content: '\f015'; +} +.wi-owm-957:before { + content: '\f050'; +} +.wi-owm-day-200:before { + content: '\f010'; +} +.wi-owm-day-201:before { + content: '\f010'; +} +.wi-owm-day-202:before { + content: '\f010'; +} +.wi-owm-day-210:before { + content: '\f005'; +} +.wi-owm-day-211:before { + content: '\f005'; +} +.wi-owm-day-212:before { + content: '\f005'; +} +.wi-owm-day-221:before { + content: '\f005'; +} +.wi-owm-day-230:before { + content: '\f010'; +} +.wi-owm-day-231:before { + content: '\f010'; +} +.wi-owm-day-232:before { + content: '\f010'; +} +.wi-owm-day-300:before { + content: '\f00b'; +} +.wi-owm-day-301:before { + content: '\f00b'; +} +.wi-owm-day-302:before { + content: '\f008'; +} +.wi-owm-day-310:before { + content: '\f008'; +} +.wi-owm-day-311:before { + content: '\f008'; +} +.wi-owm-day-312:before { + content: '\f008'; +} +.wi-owm-day-313:before { + content: '\f008'; +} +.wi-owm-day-314:before { + content: '\f008'; +} +.wi-owm-day-321:before { + content: '\f00b'; +} +.wi-owm-day-500:before { + content: '\f00b'; +} +.wi-owm-day-501:before { + content: '\f008'; +} +.wi-owm-day-502:before { + content: '\f008'; +} +.wi-owm-day-503:before { + content: '\f008'; +} +.wi-owm-day-504:before { + content: '\f008'; +} +.wi-owm-day-511:before { + content: '\f006'; +} +.wi-owm-day-520:before { + content: '\f009'; +} +.wi-owm-day-521:before { + content: '\f009'; +} +.wi-owm-day-522:before { + content: '\f009'; +} +.wi-owm-day-531:before { + content: '\f00e'; +} +.wi-owm-day-600:before { + content: '\f00a'; +} +.wi-owm-day-601:before { + content: '\f0b2'; +} +.wi-owm-day-602:before { + content: '\f00a'; +} +.wi-owm-day-611:before { + content: '\f006'; +} +.wi-owm-day-612:before { + content: '\f006'; +} +.wi-owm-day-615:before { + content: '\f006'; +} +.wi-owm-day-616:before { + content: '\f006'; +} +.wi-owm-day-620:before { + content: '\f006'; +} +.wi-owm-day-621:before { + content: '\f00a'; +} +.wi-owm-day-622:before { + content: '\f00a'; +} +.wi-owm-day-701:before { + content: '\f003'; +} +.wi-owm-day-711:before { + content: '\f062'; +} +.wi-owm-day-721:before { + content: '\f0b6'; +} +.wi-owm-day-731:before { + content: '\f063'; +} +.wi-owm-day-741:before { + content: '\f003'; +} +.wi-owm-day-761:before { + content: '\f063'; +} +.wi-owm-day-762:before { + content: '\f063'; +} +.wi-owm-day-781:before { + content: '\f056'; +} +.wi-owm-day-800:before { + content: '\f00d'; +} +.wi-owm-day-801:before { + content: '\f002'; +} +.wi-owm-day-802:before { + content: '\f002'; +} +.wi-owm-day-803:before { + content: '\f013'; +} +.wi-owm-day-804:before { + content: '\f013'; +} +.wi-owm-day-900:before { + content: '\f056'; +} +.wi-owm-day-902:before { + content: '\f073'; +} +.wi-owm-day-903:before { + content: '\f076'; +} +.wi-owm-day-904:before { + content: '\f072'; +} +.wi-owm-day-906:before { + content: '\f004'; +} +.wi-owm-day-957:before { + content: '\f050'; +} +.wi-owm-night-200:before { + content: '\f02d'; +} +.wi-owm-night-201:before { + content: '\f02d'; +} +.wi-owm-night-202:before { + content: '\f02d'; +} +.wi-owm-night-210:before { + content: '\f025'; +} +.wi-owm-night-211:before { + content: '\f025'; +} +.wi-owm-night-212:before { + content: '\f025'; +} +.wi-owm-night-221:before { + content: '\f025'; +} +.wi-owm-night-230:before { + content: '\f02d'; +} +.wi-owm-night-231:before { + content: '\f02d'; +} +.wi-owm-night-232:before { + content: '\f02d'; +} +.wi-owm-night-300:before { + content: '\f02b'; +} +.wi-owm-night-301:before { + content: '\f02b'; +} +.wi-owm-night-302:before { + content: '\f028'; +} +.wi-owm-night-310:before { + content: '\f028'; +} +.wi-owm-night-311:before { + content: '\f028'; +} +.wi-owm-night-312:before { + content: '\f028'; +} +.wi-owm-night-313:before { + content: '\f028'; +} +.wi-owm-night-314:before { + content: '\f028'; +} +.wi-owm-night-321:before { + content: '\f02b'; +} +.wi-owm-night-500:before { + content: '\f02b'; +} +.wi-owm-night-501:before { + content: '\f028'; +} +.wi-owm-night-502:before { + content: '\f028'; +} +.wi-owm-night-503:before { + content: '\f028'; +} +.wi-owm-night-504:before { + content: '\f028'; +} +.wi-owm-night-511:before { + content: '\f026'; +} +.wi-owm-night-520:before { + content: '\f029'; +} +.wi-owm-night-521:before { + content: '\f029'; +} +.wi-owm-night-522:before { + content: '\f029'; +} +.wi-owm-night-531:before { + content: '\f02c'; +} +.wi-owm-night-600:before { + content: '\f02a'; +} +.wi-owm-night-601:before { + content: '\f0b4'; +} +.wi-owm-night-602:before { + content: '\f02a'; +} +.wi-owm-night-611:before { + content: '\f026'; +} +.wi-owm-night-612:before { + content: '\f026'; +} +.wi-owm-night-615:before { + content: '\f026'; +} +.wi-owm-night-616:before { + content: '\f026'; +} +.wi-owm-night-620:before { + content: '\f026'; +} +.wi-owm-night-621:before { + content: '\f02a'; +} +.wi-owm-night-622:before { + content: '\f02a'; +} +.wi-owm-night-701:before { + content: '\f04a'; +} +.wi-owm-night-711:before { + content: '\f062'; +} +.wi-owm-night-721:before { + content: '\f0b6'; +} +.wi-owm-night-731:before { + content: '\f063'; +} +.wi-owm-night-741:before { + content: '\f04a'; +} +.wi-owm-night-761:before { + content: '\f063'; +} +.wi-owm-night-762:before { + content: '\f063'; +} +.wi-owm-night-781:before { + content: '\f056'; +} +.wi-owm-night-800:before { + content: '\f02e'; +} +.wi-owm-night-801:before { + content: '\f081'; +} +.wi-owm-night-802:before { + content: '\f086'; +} +.wi-owm-night-803:before { + content: '\f013'; +} +.wi-owm-night-804:before { + content: '\f013'; +} +.wi-owm-night-900:before { + content: '\f056'; +} +.wi-owm-night-902:before { + content: '\f073'; +} +.wi-owm-night-903:before { + content: '\f076'; +} +.wi-owm-night-904:before { + content: '\f072'; +} +.wi-owm-night-906:before { + content: '\f024'; +} +.wi-owm-night-957:before { + content: '\f050'; +} +.wi-wu-chanceflurries:before { + content: '\f064'; +} +.wi-wu-chancerain:before { + content: '\f019'; +} +.wi-wu-chancesleat:before { + content: '\f0b5'; +} +.wi-wu-chancesnow:before { + content: '\f01b'; +} +.wi-wu-chancetstorms:before { + content: '\f01e'; +} +.wi-wu-clear:before { + content: '\f00d'; +} +.wi-wu-cloudy:before { + content: '\f002'; +} +.wi-wu-flurries:before { + content: '\f064'; +} +.wi-wu-hazy:before { + content: '\f0b6'; +} +.wi-wu-mostlycloudy:before { + content: '\f002'; +} +.wi-wu-mostlysunny:before { + content: '\f00d'; +} +.wi-wu-partlycloudy:before { + content: '\f002'; +} +.wi-wu-partlysunny:before { + content: '\f00d'; +} +.wi-wu-rain:before { + content: '\f01a'; +} +.wi-wu-sleat:before { + content: '\f0b5'; +} +.wi-wu-snow:before { + content: '\f01b'; +} +.wi-wu-sunny:before { + content: '\f00d'; +} +.wi-wu-tstorms:before { + content: '\f01e'; +} +.wi-wu-unknown:before { + content: '\f00d'; +} /*# sourceMappingURL=weather-icons.min.css.map */ diff --git a/src/api/get-app-icon.ts b/src/api/get-app-icon.ts new file mode 100644 index 0000000..e0e9dc0 --- /dev/null +++ b/src/api/get-app-icon.ts @@ -0,0 +1,9 @@ +const ICON_SOURCES: Record string> = { + 'homelab-svg-assets': (icon) => + `https://raw.githubusercontent.com/loganmarchione/homelab-svg-assets/main/assets/${icon}.svg`, + 'dashboard-icons': (icon) => + `https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/png/${icon}.png`, +}; + +export const getAppIcon = (icon: string, source: string = 'homelab-svg-assets') => + ICON_SOURCES[source](icon); diff --git a/src/api/get-apps.ts b/src/api/get-apps.ts new file mode 100644 index 0000000..d6c057a --- /dev/null +++ b/src/api/get-apps.ts @@ -0,0 +1,17 @@ +import { useEffect, useMemo, useState } from 'react'; +import { CategoryDefinition } from '~/types'; + +async function getCategories(): Promise { + return await import('../../data/apps.yml').then((m) => m.default.categories); +} + +export function useCategories() { + const [categories, setCategories] = useState([]); + + useEffect(() => { + getCategories().then(setCategories); + }, []); + + const apps = useMemo(() => categories.flatMap((c) => c.apps), [categories]); + return { categories, apps }; +} diff --git a/src/api/get-search-providers.ts b/src/api/get-search-providers.ts new file mode 100644 index 0000000..79960e1 --- /dev/null +++ b/src/api/get-search-providers.ts @@ -0,0 +1,16 @@ +import { useEffect, useState } from 'react'; +import { SearchProvider } from '~/types'; + +async function getSearchProviders(): Promise { + return await import('../../data/search-providers.yml').then((m) => m.default.providers); +} + +export function useSearchProviders() { + const [searchProviders, setSearchProviders] = useState([]); + + useEffect(() => { + getSearchProviders().then(setSearchProviders); + }, []); + + return searchProviders; +} diff --git a/src/api/open-weather.ts b/src/api/open-weather.ts new file mode 100644 index 0000000..6daf726 --- /dev/null +++ b/src/api/open-weather.ts @@ -0,0 +1,32 @@ +import { useEffect, useState } from 'react'; +import { WeatherData } from '~/types'; + +function fetchWeather(): Promise { + const lat = import.meta.env.VITE_OPEN_WEATHER_LAT; + const lon = import.meta.env.VITE_OPEN_WEATHER_LON; + const appId = import.meta.env.VITE_OPEN_WEATHER_KEY; + + return fetch( + `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${appId}&units=metric` + ) + .then((res) => res.json()) + .then((data) => ({ + ...data.weather[0], + ...data.main, + visibility: data.visibility, + wind_speed: data.wind.speed, + wind_deg: data.wind.deg, + sunrise: data.sys.sunrise, + sunset: data.sys.sunset, + })); +} + +export function useWeather() { + const [weather, setWeather] = useState(null); + + useEffect(() => { + fetchWeather().then(setWeather); + }, []); + + return weather; +} diff --git a/src/api/unsplash.ts b/src/api/unsplash.ts new file mode 100644 index 0000000..0b87f25 --- /dev/null +++ b/src/api/unsplash.ts @@ -0,0 +1,12 @@ +import { createApi } from 'unsplash-js'; + +const UNSPLASH_ACCESS_KEY = import.meta.env.VITE_UNSPLASH_ACCESS_KEY; + +const unsplashApi = createApi({ accessKey: UNSPLASH_ACCESS_KEY, fetch }); + +export const getRandomBackground = (query = 'dark wallpaper') => { + return unsplashApi.photos.getRandom({ + count: 20, + query: query.length === 0 ? 'dark wallpaper' : query, + }); +}; diff --git a/src/app.tsx b/src/app.tsx new file mode 100644 index 0000000..d15328c --- /dev/null +++ b/src/app.tsx @@ -0,0 +1,12 @@ +import { MantineProvider } from '@mantine/core'; +import { Background as BackgroundComponent } from '~/components/ui/background'; +import { IndexPage } from './pages/index-page'; + +export function App() { + return ( + + + + + ); +} diff --git a/src/assets/react.svg b/src/assets/react.svg new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ b/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/atoms.ts b/src/atoms.ts new file mode 100644 index 0000000..9e6fff4 --- /dev/null +++ b/src/atoms.ts @@ -0,0 +1,85 @@ +import { atomWithStorage } from 'jotai/utils'; +import { Background, BackgroundStorage } from './types'; +import { random } from './lib/math'; +import { atom } from 'jotai'; + +// export const showImageDetailsAtom = atomWithStorage('vertex-show-image-details', false); + +// export const showLocationsAtom = atomWithStorage('vertex-show-locations', false); + +// export const viewAsTableAtom = atomWithStorage('vertex-view-as-table', false); + +// export const useSavedBackgroundsAtom = atomWithStorage('vertex-saved-backgrounds', false); + +// export const unsplashQueryAtom = atomWithStorage('vertex-unsplash-query', ''); + +export type Settings = { + showImageDetails: boolean; + showLocations: boolean; + viewAsTable: boolean; + useSavedBackgrounds: boolean; + unsplashQuery: string; +}; + +export const settingsAtom = atomWithStorage('vertex-settings', { + showLocations: false, + showImageDetails: false, + viewAsTable: false, + useSavedBackgrounds: false, + unsplashQuery: '', +}); + +export const backgroundsAtom = atomWithStorage('vertex-backgrounds', { + fetched_at: 0, + backgrounds: [], +}); + +export const favoriteBackgroundsAtom = atomWithStorage( + 'vertex-favorite-backgrounds', + [] +); + +export const backgroundIndexAtom = atom(random(19)); +export const favoritedBackgroundIndexAtom = atom(0); + +export const currentBackgroundAtom = atom((get) => { + if (get(settingsAtom).useSavedBackgrounds) { + return get(favoriteBackgroundsAtom)[get(favoritedBackgroundIndexAtom)]; + } else { + return get(backgroundsAtom).backgrounds[get(backgroundIndexAtom)]; + } +}); + +export const onNextBackgroundAtom = atom(null, (get, set) => { + if (get(settingsAtom).useSavedBackgrounds) { + set(favoritedBackgroundIndexAtom, (prev) => (prev + 1) % get(favoriteBackgroundsAtom).length); + } else { + set(backgroundIndexAtom, (prev) => (prev + 1) % 20); + } +}); + +export const isCurrentBackgroundFavoriteAtom = atom((get) => { + const favoriteBackgrounds = get(favoriteBackgroundsAtom); + const currentBackground = get(currentBackgroundAtom); + return Boolean(favoriteBackgrounds.find((b) => b.id === currentBackground?.id)); +}); + +export const onFavoriteBackgroundAtom = atom(null, (get, set) => { + const currentBackground = get(currentBackgroundAtom); + if (!currentBackground) { + return; + } + + set(favoriteBackgroundsAtom, (prev) => { + if (prev.find((background) => background.id === currentBackground.id)) { + return prev; + } + return [...prev, currentBackground!]; + }); +}); + +export const onUnfavoriteCurrentBackgroundAtom = atom(null, (get, set) => { + const currentBackground = get(currentBackgroundAtom); + set(favoriteBackgroundsAtom, (prev) => prev.filter((b) => b.id !== currentBackground.id)); + set(onNextBackgroundAtom); +}); diff --git a/src/components/apps/app-button.module.css b/src/components/apps/app-button.module.css new file mode 100644 index 0000000..b7953b5 --- /dev/null +++ b/src/components/apps/app-button.module.css @@ -0,0 +1,70 @@ +.App { + position: relative; + overflow: hidden; + backdrop-filter: var(--bg-blur); + color: var(--color-text); + border-radius: var(--border-radius-default); + cursor: pointer; + + background-color: var(--color-bg-dark); + transition: background-color var(--transition-duration-default) var(--transition-fn); +} + +.App:hover, +.Box:focus-within { + background-color: var(--color-bg-darker); +} + +.App > a { + display: flex; + flex-direction: column; + justify-content: space-between; + color: var(--color-text); + gap: 12px; + width: 150px; + height: 150px; + padding: 1rem; + text-decoration: none; + + &:hover { + text-decoration: none; + } +} + +.Icon { + width: 36px; + max-height: 54px; + padding: 4px; +} + +.Icon.Bordered { + background-color: rgba(255, 255, 255, 0.9); + border-radius: 0.5rem; +} + +.Url { + font-size: 85%; + color: var(--color-secondary); +} + +.Text { + display: flex; + flex-direction: column; + gap: 0.3rem; + align-items: flex-start; +} + +.Name { + line-height: 1.3; + font-weight: bold; +} + +.Index { + position: absolute; + bottom: -30px; + right: -5px; + font-size: 100px; + color: rgba(255, 255, 255, 0.3); + letter-spacing: -4px; + font-family: var(--font-accent); +} diff --git a/src/components/apps/app-button.tsx b/src/components/apps/app-button.tsx new file mode 100644 index 0000000..3ce2776 --- /dev/null +++ b/src/components/apps/app-button.tsx @@ -0,0 +1,38 @@ +import { useAtomValue } from 'jotai'; +import { getAppIcon } from '~/api/get-app-icon'; +import { settingsAtom } from '~/atoms'; +import { AppDefinition } from '~/types'; +import style from './app-button.module.css'; +import { Anchor } from '@mantine/core'; + +export type AppButtonProps = AppDefinition; + +export function AppButton({ + name, + url, + location, + icon, + icon_source, + icon_border, + shortcut, +}: AppButtonProps) { + const { showLocations } = useAtomValue(settingsAtom); + + return ( +
+ +
+ {name} + {url.split('://')[1].split('/')[0]} + {showLocations && location && {location}} +
+ {name} + {shortcut && {shortcut}} +
+
+ ); +} diff --git a/src/components/apps/app-list.module.css b/src/components/apps/app-list.module.css new file mode 100644 index 0000000..00f4c89 --- /dev/null +++ b/src/components/apps/app-list.module.css @@ -0,0 +1,26 @@ +.AppListWrap { + width: 100%; +} + +.Header { + display: flex; + align-items: center; + gap: max(1vw, 1rem); + margin-bottom: 1rem; + padding-bottom: 8px; + font-size: clamp(1.3rem, 1.8vw, 3rem); + text-shadow: var(--text-shadow-default); +} + +.Close { + font-size: 1.4rem; + cursor: pointer; + color: var(--color-secondary); +} + +.AppList { + display: flex; + gap: clamp(.5rem, 1vw, 2rem); + margin: 0 auto 2rem; + flex-wrap: wrap; +} diff --git a/src/components/apps/app-list.tsx b/src/components/apps/app-list.tsx new file mode 100644 index 0000000..3a6d0e6 --- /dev/null +++ b/src/components/apps/app-list.tsx @@ -0,0 +1,27 @@ +import { AppDefinition } from '~/types'; +import { AppButton } from './app-button'; + +import style from './app-list.module.css'; + +type AppListProps = { + category: string; + apps: AppDefinition[]; + onReset?: () => void; +}; +export function AppList({ category, apps, onReset }: AppListProps) { + return ( +
+

+ {category} + + × + +

+
+ {apps.length > 0 + ? apps.map((app) => ) + : 'No apps found'} +
+
+ ); +} diff --git a/src/components/ui/background.module.css b/src/components/ui/background.module.css new file mode 100644 index 0000000..89650b3 --- /dev/null +++ b/src/components/ui/background.module.css @@ -0,0 +1,42 @@ +.Background, .Overlay { + position: absolute; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + z-index: -1; +} + +.Background { + background-size: cover; + object-fit: cover; + user-select: none; +} + +.Overlay { + pointer-events: none; + + opacity: 0; + transition: opacity var(--transition-duration-bg) var(--transition-fn); +} + +.Overlay.Pending { + opacity: 1; +} + +.Overlay img { + position: absolute; + object-fit: cover; + width: 100vw; + height: 100vh; +} + +.Overlay .Black { + position: absolute; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + backdrop-filter: var(--bg-blur-lg); + background-color: rgba(0, 0, 0, 0.4); +} diff --git a/src/components/ui/background.tsx b/src/components/ui/background.tsx new file mode 100644 index 0000000..3d8ccdd --- /dev/null +++ b/src/components/ui/background.tsx @@ -0,0 +1,33 @@ +import { useAtomValue } from 'jotai'; +import { useEffect, useState } from 'react'; +import { currentBackgroundAtom } from '~/atoms'; +import { loadImage } from '~/lib/load-image'; +import style from './background.module.css'; + +export function Background() { + const currentBackground = useAtomValue(currentBackgroundAtom); + + const [isLoading, setIsLoading] = useState(true); + + useEffect(() => { + if (!currentBackground) { + return; + } + + if (currentBackground.urls.full) { + loadImage(currentBackground.urls.full).then(() => { + setTimeout(() => setIsLoading(false), 300); + }); + } + }, [currentBackground]); + + return ( + <> + +
+ +
+
+ + ); +} diff --git a/src/components/ui/sidebar.module.css b/src/components/ui/sidebar.module.css new file mode 100644 index 0000000..2e7de51 --- /dev/null +++ b/src/components/ui/sidebar.module.css @@ -0,0 +1,148 @@ +.Sidebar { + flex-shrink: 0; + display: flex; + flex-direction: column; + align-items: flex-end; + justify-content: space-between; + height: 100vh; + width: max(25vw, 180px); + padding-bottom: 1.5rem; + + backdrop-filter: var(--bg-blur-lg); + background-color: rgba(0, 0, 0, 0.3); + + opacity: 1; + transition: opacity var(--transition-duration-slow) var(--transition-fn); +} + +.Sidebar.Loading { + opacity: 0; +} + +.MenuWrapper { + height: 100%; + display: flex; + align-items: center; +} + +.Menu { + display: flex; + flex-direction: column; + text-align: right; + gap: clamp(0.5rem, 1vw, 0.5rem); + font-size: clamp(1.3rem, 1.8vw, 3rem); +} + +.Menu li { + position: relative; + cursor: pointer; + text-shadow: var(--text-shadow-default); + padding: clamp(0.5rem, 1vw, 1.5rem) 1.5rem; + + opacity: 1; + transform: translateY(0); + transition: opacity var(--transition-duration-default) var(--transition-fn), + transform var(--transition-duration-default) var(--transition-fn); +} + +.Sidebar.Loading .Menu li { + opacity: 0; + transform: translateY(-1rem); +} + +.Sidebar .Menu li:nth-child(2) { + transition-delay: 0.2s; +} +.Sidebar .Menu li:nth-child(3) { + transition-delay: 0.3s; +} +.Sidebar .Menu li:nth-child(4) { + transition-delay: 0.4s; +} +.Sidebar .Menu li:nth-child(5) { + transition-delay: 0.5s; +} +.Sidebar .Menu li:nth-child(6) { + transition-delay: 0.6s; +} +.Sidebar .Menu li:nth-child(7) { + transition-delay: 0.7s; +} +.Sidebar .Menu li:nth-child(8) { + transition-delay: 0.8s; +} + +.Menu li::after { + position: absolute; + right: 0; + top: 0; + content: ''; + width: 3px; + display: block; + background-color: var(--color-text); + border-radius: var(--border-radius-default); + + height: 0; + transition: height var(--transition-duration-slow) var(--transition-fn); +} + +.Menu li:hover::after, +.Menu li.Active::after { + height: 100%; +} + +.SettingsWrapper { + display: flex; + align-items: center; + gap: 0.7rem; + margin-right: 1.5rem; + align-self: flex-end; + + opacity: 1; + transform: translateY(0); + transition: opacity var(--transition-duration-default) var(--transition-fn), + transform var(--transition-duration-default) var(--transition-fn); + transition-delay: 1s; +} + +.Sidebar.Loading .SettingsWrapper { + opacity: 0; + transform: translateY(1rem); +} + +.SettingsWrapper > * { + cursor: pointer; + outline: 0; +} + +@media (max-width: 600px) { + .Sidebar { + width: 100%; + height: 100px; + } + + .Menu { + flex-direction: row; + flex-wrap: wrap; + align-items: center; + justify-content: center; + gap: 0.5rem; + } + + .Menu li { + padding: 0.5rem 1rem; + } + + .Menu li::after { + left: 0; + bottom: 1px; + width: 0; + height: 3px; + } + + .Menu li:hover::after, + .Menu li.Active::after { + width: 100%; + height: 3px; + } +} diff --git a/src/components/ui/sidebar.tsx b/src/components/ui/sidebar.tsx new file mode 100644 index 0000000..e68d29c --- /dev/null +++ b/src/components/ui/sidebar.tsx @@ -0,0 +1,54 @@ +import { Tooltip } from '@mantine/core'; +import { IconImageInPicture } from '@tabler/icons-react'; +import { useSetAtom } from 'jotai'; +import { useEffect, useState } from 'react'; +import { onNextBackgroundAtom } from '~/atoms'; +import { FavoriteBackground } from '../widgets/favorite-background'; +import { Settings } from '../widgets/settings'; +import style from './sidebar.module.css'; + +type SidebarProps = { + categories?: string[]; + activeCategory?: string | null; + selectCategory: (category: string, mode: 'permanent' | 'temporary') => void; +}; + +export function Sidebar({ categories, activeCategory, selectCategory }: SidebarProps) { + const isActive = (category: string) => activeCategory === category; + + const onNextBackground = useSetAtom(onNextBackgroundAtom); + + const [isInitialLoading, setIsInitialLoading] = useState(true); + + useEffect(() => { + setTimeout(() => setIsInitialLoading(false), 200); + }, []); + + return ( +
+
+
    + {categories?.map((category) => ( +
  • selectCategory(category, 'permanent')} + onMouseEnter={() => selectCategory(category, 'temporary')} + > + {category} +
  • + ))} +
+
+
+ + onNextBackground()} /> + + + + + +
+
+ ); +} diff --git a/src/components/widgets/current-image-widget.module.css b/src/components/widgets/current-image-widget.module.css new file mode 100644 index 0000000..eff3099 --- /dev/null +++ b/src/components/widgets/current-image-widget.module.css @@ -0,0 +1,21 @@ +.CurrentBackground { + position: absolute; + bottom: 1rem; + right: 1rem; + padding: 1rem 1.5rem; + line-height: 1.5rem; + backdrop-filter: var(--bg-blur); + background-color: var(--color-bg-dark); + border-radius: var(--border-radius-default); + + opacity: 1; + transform: translateY(0); + transition: opacity var(--transition-duration-slow) var(--transition-fn), + transform var(--transition-duration-slow) var(--transition-fn); + transition-delay: 1s; +} + +.CurrentBackground.Loading { + opacity: 0; + transform: translateY(8rem); +} diff --git a/src/components/widgets/current-image-widget.tsx b/src/components/widgets/current-image-widget.tsx new file mode 100644 index 0000000..e4a1dd0 --- /dev/null +++ b/src/components/widgets/current-image-widget.tsx @@ -0,0 +1,24 @@ +import { useAtomValue } from 'jotai'; +import { JSX } from 'react'; +import { currentBackgroundAtom } from '~/atoms'; +import style from './current-image-widget.module.css'; + +type CurrentImageWidgetProps = { + loading: boolean; +}; + +export function CurrentImageWidget({ loading }: CurrentImageWidgetProps): JSX.Element { + const currentBackground = useAtomValue(currentBackgroundAtom); + + return ( +
+ + {currentBackground?.description?.slice(0, 60) || + currentBackground?.alt_description?.slice(0, 60) || + 'Unnamed'} + +
+ {currentBackground?.location.name} +
+ ); +} diff --git a/src/components/widgets/date-widget.module.css b/src/components/widgets/date-widget.module.css new file mode 100644 index 0000000..27f62b4 --- /dev/null +++ b/src/components/widgets/date-widget.module.css @@ -0,0 +1,24 @@ +.DateWidget { + display: flex; + flex-direction: column; + height: 100%; + font-family: var(--font-accent); + letter-spacing: -2px; + text-shadow: var(--text-shadow-lg); + font-weight: bold; +} + +.Date { + font-size: clamp(2.5rem, 3.5vw, 5.5rem); + margin-bottom: max(1vw, 1rem); + line-height: 1.1; +} + +.Time { + font-size: clamp(1.5rem, 2vw, 2.8rem); + text-shadow: var(--text-shadow-default); +} + +.Logo { + color: var(--color-secondary); +} diff --git a/src/components/widgets/date-widget.tsx b/src/components/widgets/date-widget.tsx new file mode 100644 index 0000000..2297600 --- /dev/null +++ b/src/components/widgets/date-widget.tsx @@ -0,0 +1,21 @@ +import { useEffect, useState } from 'react'; +import { getDate, getTime } from '~/lib/date'; + +import style from './date-widget.module.css'; + +export function DateWidget() { + const [time, setTime] = useState(getTime()); + + useEffect(() => { + setInterval(() => setTime(getTime()), 1000); + }, []); + + return ( +
+

{getDate()}

+

+ {time} · gar.dev +

+
+ ); +} diff --git a/src/components/widgets/favorite-background.tsx b/src/components/widgets/favorite-background.tsx new file mode 100644 index 0000000..b1f13be --- /dev/null +++ b/src/components/widgets/favorite-background.tsx @@ -0,0 +1,28 @@ +import { Tooltip } from '@mantine/core'; +import { IconStar, IconStarFilled } from '@tabler/icons-react'; +import { useAtomValue, useSetAtom } from 'jotai'; +import { + isCurrentBackgroundFavoriteAtom, + onFavoriteBackgroundAtom, + onUnfavoriteCurrentBackgroundAtom, +} from '~/atoms'; + +export function FavoriteBackground() { + const isCurrentBackgroundFavorite = useAtomValue(isCurrentBackgroundFavoriteAtom); + const favoriteBackground = useSetAtom(onFavoriteBackgroundAtom); + const unfavoriteBackground = useSetAtom(onUnfavoriteCurrentBackgroundAtom); + + if (!isCurrentBackgroundFavorite) { + return ( + + + + ); + } else { + return ( + + + + ); + } +} diff --git a/src/components/widgets/search-widget.module.css b/src/components/widgets/search-widget.module.css new file mode 100644 index 0000000..f7374c5 --- /dev/null +++ b/src/components/widgets/search-widget.module.css @@ -0,0 +1,48 @@ +.SearchBar { + display: flex; + align-items: center; + gap: 2px; + width: clamp(300px, 40vw, 600px); + margin-bottom: 4px; +} + +.Provider, +.Search { + padding-inline: 20px; + height: 40px; + line-height: 40px; + border: 0; + border-bottom: 2px solid var(--color-bg-dark); + backdrop-filter: var(--bg-blur); + background-color: var(--color-bg-dark); +} + +.Provider { + font-family: var(--font-accent); + text-align: center; + text-transform: uppercase; + border-top-right-radius: 0.5rem; + border-bottom-right-radius: 0.5rem; +} + +.Search { + flex-grow: 1; + color: var(--color-text); + outline: 0; + + transition: border-color var(--transition-duration-default) var(--transition-fn); +} + +.Search:focus-within { + border-color: var(--color-text); +} + +.Search::placeholder { + color: var(--color-text); + user-select: none; +} + +.Hint { + font-size: 85%; + color: var(--color-secondary); +} diff --git a/src/components/widgets/search-widget.tsx b/src/components/widgets/search-widget.tsx new file mode 100644 index 0000000..d1f3e56 --- /dev/null +++ b/src/components/widgets/search-widget.tsx @@ -0,0 +1,74 @@ +import { useMemo } from 'react'; +import { SearchProvider } from '~/types'; + +import style from './search-widget.module.css'; + +type SearchWidgetProps = { + term: string; + setTerm: (term: string) => void; + providers: SearchProvider[]; + onOpenApp: () => void; + canOpenApp: boolean; +}; + +export function SearchWidget({ + term, + setTerm, + providers, + onOpenApp, + canOpenApp, +}: SearchWidgetProps) { + const defaultProvider = useMemo( + () => providers?.find((provider) => provider.default) ?? providers?.[0], + [providers] + ); + + const activeProvider = useMemo(() => { + if (!term.startsWith('!')) { + return defaultProvider; + } + + const prefix = term.slice(1); + const provider = providers?.find( + (provider) => provider.prefix === prefix || provider.prefix === prefix.split(' ')[0] + ); + + return provider || defaultProvider; + }, [term, defaultProvider, providers]); + + const searchTerm = () => { + return term.startsWith('!') ? term.split(`!${activeProvider?.prefix} `)[1] : term; + }; + + const onKeyPress = (e: React.KeyboardEvent) => { + e.stopPropagation(); + if (canOpenApp && e.shiftKey && e.key === 'Enter') { + onOpenApp(); + return; + } + + if (e.key === 'Enter') { + window.open(`${activeProvider?.url}${searchTerm()}`, '_blank', 'noreferrer'); + setTerm(''); + } + }; + + return ( +
+
+ setTerm(e.target.value)} + onKeyDown={onKeyPress} + /> +
{activeProvider?.name}
+
+ {canOpenApp && Press Shift+Enter to open first result} +
+ ); +} diff --git a/src/components/widgets/settings.tsx b/src/components/widgets/settings.tsx new file mode 100644 index 0000000..a959e9d --- /dev/null +++ b/src/components/widgets/settings.tsx @@ -0,0 +1,71 @@ +import { Badge, Button, Checkbox, Flex, Modal, TextInput, Tooltip } from '@mantine/core'; +import { useDisclosure } from '@mantine/hooks'; +import { IconSettings, IconTrash } from '@tabler/icons-react'; +import { useAtom, useAtomValue } from 'jotai'; +import { favoriteBackgroundsAtom, settingsAtom } from '~/atoms'; + +type SettingsProps = { + className?: string; +}; + +export function Settings(props: SettingsProps) { + const [isOpen, { open, close }] = useDisclosure(); + + const [appSettings, setAppSettings] = useAtom(settingsAtom); + const favoriteBackgrounds = useAtomValue(favoriteBackgroundsAtom); + + return ( +
+ + + + + + + + setAppSettings((prev) => ({ ...prev, showImageDetails: e.target.checked })) + } + /> + + setAppSettings((prev) => ({ ...prev, showLocations: e.target.checked })) + } + /> + + Use favorited backgrounds {favoriteBackgrounds.length} + + } + checked={appSettings.useSavedBackgrounds} + onChange={(e) => + setAppSettings((prev) => ({ ...prev, useSavedBackgrounds: e.target.checked })) + } + /> + + e.stopPropagation()} + onChange={(e) => setAppSettings((prev) => ({ ...prev, unsplashQuery: e.target.value }))} + /> + + + +
+ ); +} diff --git a/src/components/widgets/weather-widget.module.css b/src/components/widgets/weather-widget.module.css new file mode 100644 index 0000000..7d69dcb --- /dev/null +++ b/src/components/widgets/weather-widget.module.css @@ -0,0 +1,54 @@ +.Weather { + flex-grow: 1; + max-width: 300px; + min-width: 200px; + height: 200px; + padding: 30px; + display: flex; + flex-direction: column; + gap: 0.5rem; + border-radius: var(--border-radius-default); + + backdrop-filter: var(--bg-blur); + background-color: var(--color-bg-dark); + + opacity: 1; + transform: translateY(0); + transition: opacity var(--transition-duration-slow) var(--transition-fn), + transform var(--transition-duration-slow) var(--transition-fn); +} + +.Weather.Loading { + opacity: 0; + transform: translateY(-1rem); +} + +.FeelsLike { + display: flex; + flex-direction: column; + gap: 0.5rem; + margin-left: 0.5rem; + font-size: 1.3rem; + color: var(--color-text); +} + +.FeelsLike :last-child { + font-size: 1rem; + color: var(--color-secondary); +} + +.Delimiter { + border-bottom: 1px solid var(--color-secondary); + padding-bottom: 1.2rem; + margin-bottom: 0.8rem; +} + +.WeatherLine { + display: flex; + gap: 0.3rem; + align-items: center; +} + +.WeatherIcon { + font-size: 2.4rem; +} diff --git a/src/components/widgets/weather-widget.tsx b/src/components/widgets/weather-widget.tsx new file mode 100644 index 0000000..98408ea --- /dev/null +++ b/src/components/widgets/weather-widget.tsx @@ -0,0 +1,58 @@ +import { useEffect, useMemo, useState } from 'react'; +// import { HiSolidArrowDown, HiSolidArrowUp } from 'solid-icons/hi'; +// import { WiHumidity, WiSunrise, WiSunset } from 'solid-icons/wi'; +import { useWeather } from '~/api/open-weather'; +import { getTime } from '~/lib/date'; +import { + IconChevronDown, + IconChevronUp, + IconDroplet, + IconSunrise, + IconSunset, +} from '@tabler/icons-react'; + +import style from './weather-widget.module.css'; +import { Box } from '@mantine/core'; + +export function WeatherWidget() { + const weather = useWeather(); + + const [isLoading, setIsLoading] = useState(true); + + useEffect(() => { + if (weather && isLoading === true) { + setTimeout(() => setIsLoading(false), 200); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [weather]); + + const sunrise = useMemo(() => getTime((weather?.sunrise ?? 0) * 1000), [weather]); + const sunset = useMemo(() => getTime((weather?.sunset ?? 0) * 1000), [weather]); + + if (!weather || isLoading) { + return
Loading...
; + } + + return ( +
+
+ +
+ {weather.feels_like}° + {weather.main} +
+
+
+ + {weather.temp_min}° {weather.temp_max} + ° + + {weather.humidity}%
+
+ + {sunrise} + {sunset} + +
+ ); +} diff --git a/src/config.ts b/src/config.ts new file mode 100644 index 0000000..d9dce92 --- /dev/null +++ b/src/config.ts @@ -0,0 +1 @@ +export const BACKGROUND_FETCH_MINS = 60; diff --git a/src/lib/array.ts b/src/lib/array.ts new file mode 100644 index 0000000..3e34567 --- /dev/null +++ b/src/lib/array.ts @@ -0,0 +1,12 @@ +import { random } from './math'; + +export function sample(list: T[]): T | undefined { + if (list.length === 0) { + return undefined; + } + + if (list.length === 1) { + return list[0]; + } + return list[random(list.length - 1)]; +} diff --git a/src/lib/date.ts b/src/lib/date.ts new file mode 100644 index 0000000..703d0f5 --- /dev/null +++ b/src/lib/date.ts @@ -0,0 +1,5 @@ +import { format } from 'date-fns'; + +export const getDate = () => format(new Date(), 'EEEE, dd MMM yyyy'); + +export const getTime = (time: Date | number = new Date()) => format(time, 'HH:mm:ss'); diff --git a/src/lib/load-image.ts b/src/lib/load-image.ts new file mode 100644 index 0000000..60df848 --- /dev/null +++ b/src/lib/load-image.ts @@ -0,0 +1,8 @@ +export function loadImage(url: string): Promise { + return new Promise((resolve, reject) => { + const img = new Image(); + img.onload = () => resolve(img); + img.onerror = () => reject(); + img.src = url; + }); +} diff --git a/src/lib/math.ts b/src/lib/math.ts new file mode 100644 index 0000000..77ca159 --- /dev/null +++ b/src/lib/math.ts @@ -0,0 +1 @@ +export const random = (n: number) => Math.floor(Math.random() * n) + 1; diff --git a/src/lib/use-active-category.ts b/src/lib/use-active-category.ts new file mode 100644 index 0000000..e4962b2 --- /dev/null +++ b/src/lib/use-active-category.ts @@ -0,0 +1,29 @@ +import { useCallback, useState } from 'react'; + +export function useActiveCategory() { + const [activeCategory, setActiveCategory] = useState(null); + const [timeout, storeTimeout] = useState(null); + + const selectCategory = useCallback( + (category: string, mode: 'permanent' | 'temporary') => { + setActiveCategory(category); + if (timeout) { + clearTimeout(timeout); + } + + if (mode === 'temporary') { + storeTimeout(setTimeout(() => setActiveCategory(null), 3000)); + } + }, + [timeout] + ); + + const resetCategory = useCallback(() => { + setActiveCategory(null); + if (timeout) { + clearTimeout(timeout); + } + }, [timeout]); + + return { activeCategory, selectCategory, resetCategory }; +} diff --git a/src/main.tsx b/src/main.tsx new file mode 100644 index 0000000..9c11a7b --- /dev/null +++ b/src/main.tsx @@ -0,0 +1,13 @@ +import { StrictMode } from 'react'; +import { createRoot } from 'react-dom/client'; +import { App } from './app'; + +import '@mantine/core/styles.css'; +import 'reset.css'; +import './styles/index.css'; + +createRoot(document.getElementById('root')!).render( + + + +); diff --git a/src/pages/index-page.module.css b/src/pages/index-page.module.css new file mode 100644 index 0000000..9e8bf5d --- /dev/null +++ b/src/pages/index-page.module.css @@ -0,0 +1,65 @@ +.SidebarPage { + display: flex; +} + +@media (max-width: 600px) { + .SidebarPage { + flex-direction: column; + } +} + +.ContentWrapper { + display: flex; + align-items: flex-start; + gap: 2rem; + height: 100vh; + width: 100%; + overflow: scroll; + padding: 0 clamp(1rem, 10vw, 10rem); +} + +.Widgets { + display: flex; + flex-direction: column; + gap: 2rem; + width: 100%; + margin-top: calc(50vh - 240px); +} + +.MainWidgets { + display: flex; + flex-direction: column; + gap: 2rem; + + opacity: 1; + transform: translateY(0); + transition: opacity var(--transition-duration-slow) var(--transition-fn), + transform var(--transition-duration-slow) var(--transition-fn); +} + +.Loading .MainWidgets { + opacity: 0; + transform: translateY(-1rem); +} + +.CurrentBackground { + position: absolute; + bottom: 1rem; + right: 1rem; + padding: 1rem 1.5rem; + line-height: 1.5rem; + backdrop-filter: var(--bg-blur); + background-color: var(--color-bg-dark); + border-radius: var(--border-radius-default); + + opacity: 1; + transform: translateY(0); + transition: opacity var(--transition-duration-slow) var(--transition-fn), + transform var(--transition-duration-slow) var(--transition-fn); + transition-delay: 1s; +} + +.Loading .CurrentBackground { + opacity: 1; + transform: translateY(4.5rem); +} diff --git a/src/pages/index-page.tsx b/src/pages/index-page.tsx new file mode 100644 index 0000000..49cc793 --- /dev/null +++ b/src/pages/index-page.tsx @@ -0,0 +1,151 @@ +import { useAtom, useAtomValue, useSetAtom } from 'jotai'; +import { useEffect, useMemo, useState } from 'react'; +import { useCategories } from '~/api/get-apps'; +import { useSearchProviders } from '~/api/get-search-providers'; +import { getRandomBackground } from '~/api/unsplash'; +import { backgroundsAtom, onNextBackgroundAtom, settingsAtom } from '~/atoms'; +import { AppList } from '~/components/apps/app-list'; +import { Sidebar } from '~/components/ui/sidebar'; +import { DateWidget } from '~/components/widgets/date-widget'; +import { SearchWidget } from '~/components/widgets/search-widget'; +import { BACKGROUND_FETCH_MINS } from '~/config'; +import { useActiveCategory } from '~/lib/use-active-category'; +import { Background } from '~/types'; + +import { CurrentImageWidget } from '~/components/widgets/current-image-widget'; +import { WeatherWidget } from '~/components/widgets/weather-widget'; +import style from './index-page.module.css'; + +export function IndexPage() { + const searchProviders = useSearchProviders(); + const [searchTerm, setSearchTerm] = useState(''); + const shouldSearchLocally = searchTerm && !searchTerm.startsWith('!'); + + const { showImageDetails, unsplashQuery } = useAtomValue(settingsAtom); + + const [backgrounds, setBackgrounds] = useAtom(backgroundsAtom); + const onNextBackground = useSetAtom(onNextBackgroundAtom); + + useEffect(() => { + const shouldFetch = + backgrounds.backgrounds.length === 0 || + backgrounds.fetched_at < new Date().getTime() - 1000 * 60 * BACKGROUND_FETCH_MINS; + + if (shouldFetch) { + getRandomBackground(unsplashQuery).then((r) => + setBackgrounds({ + fetched_at: new Date().getTime(), + backgrounds: (r?.response as Background[]) ?? null, + }) + ); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const { categories, apps } = useCategories(); + + const { activeCategory, selectCategory, resetCategory } = useActiveCategory(); + const activeCategoryDef = categories?.find((c) => c.name === activeCategory); + + const searchResults = useMemo(() => { + if (!shouldSearchLocally) { + return []; + } + + return ( + apps?.filter( + (app) => + app.name.toLowerCase().includes(searchTerm.toLowerCase()) || + app.url.toLowerCase().includes(searchTerm.toLowerCase()) + ) ?? [] + ); + }, [apps, searchTerm, shouldSearchLocally]); + + const [isInitialLoading, setIsInitialLoading] = useState(true); + useEffect(() => { + setTimeout(() => setIsInitialLoading(false), 200); + }, []); + + useEffect(() => { + parent.addEventListener('keydown', handleKeypress); + + return () => { + parent.removeEventListener('keydown', handleKeypress); + }; + }); + + function handleKeypress(e: KeyboardEvent) { + switch (e.key) { + case 'ArrowRight': { + if (document.activeElement?.id !== 'search') { + onNextBackground(); + } + break; + } + case 'Escape': { + document.getElementById('search')?.blur(); + resetCategory(); + setSearchTerm(''); + break; + } + case '/': { + document.getElementById('search')?.focus(); + e.preventDefault(); + break; + } + default: { + if (document.activeElement?.id !== 'search') { + const app = apps?.find((app) => app.shortcut === e.key); + + if (app) { + window.open(app.url); + } + } + } + } + } + + return ( +
+ c.name)} + selectCategory={selectCategory} + activeCategory={activeCategory} + /> +
+
+ {activeCategory ? ( + + ) : ( + <> +
+ + 0} + onOpenApp={() => window.open(searchResults[0].url)} + /> +
+ {shouldSearchLocally ? ( + setSearchTerm('')} + /> + ) : ( + + )} + + )} +
+
+ {showImageDetails && } +
+ ); +} diff --git a/src/styles/index.css b/src/styles/index.css new file mode 100644 index 0000000..7d15176 --- /dev/null +++ b/src/styles/index.css @@ -0,0 +1,83 @@ +:root { + --color-text: #eee; + --color-secondary: #ddd; + --color-bg-dark: rgba(0, 0, 0, 0.6); + --color-bg-darker: rgba(0, 0, 0, 0.9); + + --bg-blur: blur(10px); + --bg-blur-lg: blur(20px); + + --text-shadow-default: 1px 1px 7px #000; + --text-shadow-lg: 1px 1px 12px #000; + + --border-radius-default: 0.75rem; + + --font-default: 'Helvetica Neue', sans-serif; + --font-accent: 'Nova Mono', monospace; + + --transition-fn: ease; + --transition-duration-default: 0.2s; + --transition-duration-slow: 0.5s; + --transition-duration-bg: 1s; +} + +::selection { + color: white; + background-color: black; +} + +body { + font-family: var(--font-default); +} + +html, +main { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body, +main { + color: var(--color-text); +} + +.scroll-wrapper { + height: 100vh; + overflow: scroll; +} + +main { + margin: 0 auto; +} + +strong { + font-weight: bold; +} + +table { + width: 100%; + background-color: rgba(30, 30, 30, 0.85); + backdrop-filter: var(--bg-blur); + border: 2px solid rgba(30, 30, 30, 1); + color: var(--color-text); +} + +th { + text-align: left; + font-weight: bold; +} + +th, +td { + padding: 1rem 1.5rem; +} + +tr { + border-bottom: 1px solid black; +} + +a:hover, +a:focus { + text-decoration: underline; +} diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..963e28f --- /dev/null +++ b/src/types.ts @@ -0,0 +1,48 @@ +import { Random } from 'unsplash-js/dist/methods/photos/types'; + +export type CategoryDefinition = { + name: string; + apps: AppDefinition[]; +}; + +export type AppDefinition = { + name: string; + url: string; + icon: string; + icon_source?: string; + icon_border?: boolean; + tags: string; + location?: string; + shortcut?: string; +}; + +export type SearchProvider = { + name: string; + prefix: string; + url: string; + default?: boolean; +}; + +export type WeatherData = { + id: string; + main: string; + description: string; + icon: string; + temp: number; + feels_like: number; + temp_min: number; + temp_max: number; + pressure: number; + humidity: number; + visibility: number; + wind_speed: number; + wind_deg: number; + sunrise: number; + sunset: number; +}; + +export type Background = Random; +export type BackgroundStorage = { + fetched_at: number; + backgrounds: Background[]; +}; diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/tsconfig.app.json b/tsconfig.app.json new file mode 100644 index 0000000..fa2a0f7 --- /dev/null +++ b/tsconfig.app.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true, + "baseUrl": ".", + "paths": { + "~/*": ["src/*"], + }, + "types": [ + "@modyfi/vite-plugin-yaml/modules" + ] + }, + "include": ["src"] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..1ffef60 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/tsconfig.node.json b/tsconfig.node.json new file mode 100644 index 0000000..54bb9c2 --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2022", + "lib": ["ES2023"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true, + }, + "include": ["vite.config.ts"] +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..d9d5172 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,16 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; +import ViteYaml from '@modyfi/vite-plugin-yaml'; +import path from 'path'; + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [react(), ViteYaml()], + resolve: { + alias: { + '~': path.resolve(__dirname, './src/'), + // /esm/icons/index.mjs only exports the icons statically, so no separate chunks are created + '@tabler/icons-react': '@tabler/icons-react/dist/esm/icons/index.mjs', + }, + }, +});