diff --git a/.prettierignore b/.prettierignore index c496620..a3c484e 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,3 +2,4 @@ src-tauri/target dist pnpm-lock.yaml src/routeTree.gen.ts +*.ts.timestamp* diff --git a/.prettierrc b/.prettierrc index 106f500..8e00646 100644 --- a/.prettierrc +++ b/.prettierrc @@ -4,5 +4,9 @@ "singleQuote": true, "tabWidth": 2, "trailingComma": "none", - "plugins": ["prettier-plugin-tailwindcss", "prettier-plugin-organize-imports"] + "plugins": [ + "prettier-plugin-organize-imports", + "prettier-plugin-tailwindcss" + ], + "tailwindFunctions": ["clsx"] } diff --git a/CHANGELOG.txt b/CHANGELOG.txt index f106719..d43f50b 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,4 +1,5 @@ -OverBuddy has been updated to the latest Overwatch patch. -- Added the Porsche crossover event background. -- Fixed an issue during setup. -- Currently applied background now reflects configuration changes. \ No newline at end of file +OverBuddy has been updated! +- Added a new error screen and updated setup error resolution steps. +- Improved error handling and reliability with backups to Battle.net configuration. +- Enhanced styling and animation quality. +- Fixed various issues and made improvements. \ No newline at end of file diff --git a/README.md b/README.md index 55951e3..a30c489 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@

OverBuddy

Elevate your Overwatch™ 2 experience by customizing your in-game menu background with ease.

-

Current Version: 1.1.2

+

Current Version: 1.2.0

Download · diff --git a/package.json b/package.json index 819896f..684a3ae 100644 --- a/package.json +++ b/package.json @@ -2,42 +2,48 @@ "name": "overbuddy", "author": "Kirill Tregubov", "private": true, - "version": "1.1.2", + "version": "1.2.0", "type": "module", "scripts": { "dev": "vite", "build": "tsc && vite build", "preview": "vite preview", "tauri": "tauri", - "format": "prettier . --write" + "format": "prettier . --write", + "update": "tsx scripts/update.ts" }, "dependencies": { - "@tanstack/react-query": "^5.36.0", - "@tanstack/react-router": "^1.32.5", - "@tauri-apps/api": "^1.5.5", + "@tanstack/react-query": "^5.40.0", + "@tanstack/react-router": "^1.34.7", + "@tauri-apps/api": "^1.5.6", "clsx": "^2.1.1", - "framer-motion": "^11.2.0", - "lucide-react": "^0.378.0", + "framer-motion": "^11.2.9", + "lucide-react": "^0.381.0", "react": "^18.3.1", "react-dom": "^18.3.1", "sonner": "^1.4.41", + "tailwind-easing-gradients": "^1.0.2", "zod": "^3.23.8" }, "devDependencies": { - "@tanstack/router-vite-plugin": "^1.32.2", + "@tanstack/router-vite-plugin": "^1.34.8", "@tauri-apps/cli": "^1.5.14", - "@types/node": "^20.12.12", - "@types/react": "^18.3.2", + "@total-typescript/ts-reset": "^0.5.1", + "@types/node": "^20.12.13", + "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", - "@vitejs/plugin-react": "^4.2.1", + "@vitejs/plugin-react": "^4.3.0", "autoprefixer": "^10.4.19", "postcss": "^8.4.38", "prettier": "^3.2.5", "prettier-plugin-organize-imports": "^3.2.4", - "prettier-plugin-tailwindcss": "^0.5.14", + "prettier-plugin-tailwindcss": "^0.6.0", + "readline-sync": "^1.4.10", + "semver": "^7.6.2", "tailwindcss": "^3.4.3", + "tsx": "^4.11.0", "typescript": "^5.4.5", - "vite": "^5.2.11", + "vite": "^5.2.12", "vite-plugin-package-version": "^1.1.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 503eb95..1ff756d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,23 +9,23 @@ importers: .: dependencies: '@tanstack/react-query': - specifier: ^5.36.0 - version: 5.36.0(react@18.3.1) + specifier: ^5.40.0 + version: 5.40.0(react@18.3.1) '@tanstack/react-router': - specifier: ^1.32.5 - version: 1.32.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^1.34.7 + version: 1.34.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@tauri-apps/api': - specifier: ^1.5.5 - version: 1.5.5 + specifier: ^1.5.6 + version: 1.5.6 clsx: specifier: ^2.1.1 version: 2.1.1 framer-motion: - specifier: ^11.2.0 - version: 11.2.0(@emotion/is-prop-valid@1.2.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^11.2.9 + version: 11.2.9(@emotion/is-prop-valid@1.2.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) lucide-react: - specifier: ^0.378.0 - version: 0.378.0(react@18.3.1) + specifier: ^0.381.0 + version: 0.381.0(react@18.3.1) react: specifier: ^18.3.1 version: 18.3.1 @@ -35,28 +35,34 @@ importers: sonner: specifier: ^1.4.41 version: 1.4.41(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + tailwind-easing-gradients: + specifier: ^1.0.2 + version: 1.0.2 zod: specifier: ^3.23.8 version: 3.23.8 devDependencies: '@tanstack/router-vite-plugin': - specifier: ^1.32.2 - version: 1.32.2(vite@5.2.11(@types/node@20.12.12)) + specifier: ^1.34.8 + version: 1.34.8(vite@5.2.12(@types/node@20.12.13)) '@tauri-apps/cli': specifier: ^1.5.14 version: 1.5.14 + '@total-typescript/ts-reset': + specifier: ^0.5.1 + version: 0.5.1 '@types/node': - specifier: ^20.12.12 - version: 20.12.12 + specifier: ^20.12.13 + version: 20.12.13 '@types/react': - specifier: ^18.3.2 - version: 18.3.2 + specifier: ^18.3.3 + version: 18.3.3 '@types/react-dom': specifier: ^18.3.0 version: 18.3.0 '@vitejs/plugin-react': - specifier: ^4.2.1 - version: 4.2.1(vite@5.2.11(@types/node@20.12.12)) + specifier: ^4.3.0 + version: 4.3.0(vite@5.2.12(@types/node@20.12.13)) autoprefixer: specifier: ^10.4.19 version: 10.4.19(postcss@8.4.38) @@ -70,20 +76,29 @@ importers: specifier: ^3.2.4 version: 3.2.4(prettier@3.2.5)(typescript@5.4.5) prettier-plugin-tailwindcss: - specifier: ^0.5.14 - version: 0.5.14(prettier-plugin-organize-imports@3.2.4(prettier@3.2.5)(typescript@5.4.5))(prettier@3.2.5) + specifier: ^0.6.0 + version: 0.6.0(prettier-plugin-organize-imports@3.2.4(prettier@3.2.5)(typescript@5.4.5))(prettier@3.2.5) + readline-sync: + specifier: ^1.4.10 + version: 1.4.10 + semver: + specifier: ^7.6.2 + version: 7.6.2 tailwindcss: specifier: ^3.4.3 - version: 3.4.3 + version: 3.4.3(ts-node@10.9.2(@types/node@20.12.13)(typescript@5.4.5)) + tsx: + specifier: ^4.11.0 + version: 4.11.0 typescript: specifier: ^5.4.5 version: 5.4.5 vite: - specifier: ^5.2.11 - version: 5.2.11(@types/node@20.12.12) + specifier: ^5.2.12 + version: 5.2.12(@types/node@20.12.13) vite-plugin-package-version: specifier: ^1.1.0 - version: 1.1.0(vite@5.2.11(@types/node@20.12.12)) + version: 1.1.0(vite@5.2.12(@types/node@20.12.13)) packages: @@ -95,161 +110,165 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@babel/code-frame@7.24.2': - resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==} + '@babel/code-frame@7.24.6': + resolution: {integrity: sha512-ZJhac6FkEd1yhG2AHOmfcXG4ceoLltoCVJjN5XsWN9BifBQr+cHJbWi0h68HZuSORq+3WtJ2z0hwF2NG1b5kcA==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.24.4': - resolution: {integrity: sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==} + '@babel/compat-data@7.24.6': + resolution: {integrity: sha512-aC2DGhBq5eEdyXWqrDInSqQjO0k8xtPRf5YylULqx8MCd6jBtzqfta/3ETMRpuKIc5hyswfO80ObyA1MvkCcUQ==} engines: {node: '>=6.9.0'} - '@babel/core@7.24.5': - resolution: {integrity: sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA==} + '@babel/core@7.24.6': + resolution: {integrity: sha512-qAHSfAdVyFmIvl0VHELib8xar7ONuSHrE2hLnsaWkYNTI68dmi1x8GYDhJjMI/e7XWal9QBlZkwbOnkcw7Z8gQ==} engines: {node: '>=6.9.0'} - '@babel/generator@7.24.5': - resolution: {integrity: sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA==} + '@babel/generator@7.24.6': + resolution: {integrity: sha512-S7m4eNa6YAPJRHmKsLHIDJhNAGNKoWNiWefz1MBbpnt8g9lvMDl1hir4P9bo/57bQEmuwEhnRU/AMWsD0G/Fbg==} engines: {node: '>=6.9.0'} - '@babel/helper-annotate-as-pure@7.22.5': - resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} + '@babel/helper-annotate-as-pure@7.24.6': + resolution: {integrity: sha512-DitEzDfOMnd13kZnDqns1ccmftwJTS9DMkyn9pYTxulS7bZxUxpMly3Nf23QQ6NwA4UB8lAqjbqWtyvElEMAkg==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.23.6': - resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} + '@babel/helper-compilation-targets@7.24.6': + resolution: {integrity: sha512-VZQ57UsDGlX/5fFA7GkVPplZhHsVc+vuErWgdOiysI9Ksnw0Pbbd6pnPiR/mmJyKHgyIW0c7KT32gmhiF+cirg==} engines: {node: '>=6.9.0'} - '@babel/helper-create-class-features-plugin@7.24.5': - resolution: {integrity: sha512-uRc4Cv8UQWnE4NXlYTIIdM7wfFkOqlFztcC/gVXDKohKoVB3OyonfelUBaJzSwpBntZ2KYGF/9S7asCHsXwW6g==} + '@babel/helper-create-class-features-plugin@7.24.6': + resolution: {integrity: sha512-djsosdPJVZE6Vsw3kk7IPRWethP94WHGOhQTc67SNXE0ZzMhHgALw8iGmYS0TD1bbMM0VDROy43od7/hN6WYcA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-environment-visitor@7.22.20': - resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} + '@babel/helper-environment-visitor@7.24.6': + resolution: {integrity: sha512-Y50Cg3k0LKLMjxdPjIl40SdJgMB85iXn27Vk/qbHZCFx/o5XO3PSnpi675h1KEmmDb6OFArfd5SCQEQ5Q4H88g==} engines: {node: '>=6.9.0'} - '@babel/helper-function-name@7.23.0': - resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} + '@babel/helper-function-name@7.24.6': + resolution: {integrity: sha512-xpeLqeeRkbxhnYimfr2PC+iA0Q7ljX/d1eZ9/inYbmfG2jpl8Lu3DyXvpOAnrS5kxkfOWJjioIMQsaMBXFI05w==} engines: {node: '>=6.9.0'} - '@babel/helper-hoist-variables@7.22.5': - resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} + '@babel/helper-hoist-variables@7.24.6': + resolution: {integrity: sha512-SF/EMrC3OD7dSta1bLJIlrsVxwtd0UpjRJqLno6125epQMJ/kyFmpTT4pbvPbdQHzCHg+biQ7Syo8lnDtbR+uA==} engines: {node: '>=6.9.0'} - '@babel/helper-member-expression-to-functions@7.24.5': - resolution: {integrity: sha512-4owRteeihKWKamtqg4JmWSsEZU445xpFRXPEwp44HbgbxdWlUV1b4Agg4lkA806Lil5XM/e+FJyS0vj5T6vmcA==} + '@babel/helper-member-expression-to-functions@7.24.6': + resolution: {integrity: sha512-OTsCufZTxDUsv2/eDXanw/mUZHWOxSbEmC3pP8cgjcy5rgeVPWWMStnv274DV60JtHxTk0adT0QrCzC4M9NWGg==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.24.3': - resolution: {integrity: sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==} + '@babel/helper-module-imports@7.24.6': + resolution: {integrity: sha512-a26dmxFJBF62rRO9mmpgrfTLsAuyHk4e1hKTUkD/fcMfynt8gvEKwQPQDVxWhca8dHoDck+55DFt42zV0QMw5g==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.24.5': - resolution: {integrity: sha512-9GxeY8c2d2mdQUP1Dye0ks3VDyIMS98kt/llQ2nUId8IsWqTF0l1LkSX0/uP7l7MCDrzXS009Hyhe2gzTiGW8A==} + '@babel/helper-module-transforms@7.24.6': + resolution: {integrity: sha512-Y/YMPm83mV2HJTbX1Qh2sjgjqcacvOlhbzdCCsSlblOKjSYmQqEbO6rUniWQyRo9ncyfjT8hnUjlG06RXDEmcA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-optimise-call-expression@7.22.5': - resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} + '@babel/helper-optimise-call-expression@7.24.6': + resolution: {integrity: sha512-3SFDJRbx7KuPRl8XDUr8O7GAEB8iGyWPjLKJh/ywP/Iy9WOmEfMrsWbaZpvBu2HSYn4KQygIsz0O7m8y10ncMA==} engines: {node: '>=6.9.0'} - '@babel/helper-plugin-utils@7.24.5': - resolution: {integrity: sha512-xjNLDopRzW2o6ba0gKbkZq5YWEBaK3PCyTOY1K2P/O07LGMhMqlMXPxwN4S5/RhWuCobT8z0jrlKGlYmeR1OhQ==} + '@babel/helper-plugin-utils@7.24.6': + resolution: {integrity: sha512-MZG/JcWfxybKwsA9N9PmtF2lOSFSEMVCpIRrbxccZFLJPrJciJdG/UhSh5W96GEteJI2ARqm5UAHxISwRDLSNg==} engines: {node: '>=6.9.0'} - '@babel/helper-replace-supers@7.24.1': - resolution: {integrity: sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==} + '@babel/helper-replace-supers@7.24.6': + resolution: {integrity: sha512-mRhfPwDqDpba8o1F8ESxsEkJMQkUF8ZIWrAc0FtWhxnjfextxMWxr22RtFizxxSYLjVHDeMgVsRq8BBZR2ikJQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-simple-access@7.24.5': - resolution: {integrity: sha512-uH3Hmf5q5n7n8mz7arjUlDOCbttY/DW4DYhE6FUsjKJ/oYC1kQQUvwEQWxRwUpX9qQKRXeqLwWxrqilMrf32sQ==} + '@babel/helper-simple-access@7.24.6': + resolution: {integrity: sha512-nZzcMMD4ZhmB35MOOzQuiGO5RzL6tJbsT37Zx8M5L/i9KSrukGXWTjLe1knIbb/RmxoJE9GON9soq0c0VEMM5g==} engines: {node: '>=6.9.0'} - '@babel/helper-skip-transparent-expression-wrappers@7.22.5': - resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==} + '@babel/helper-skip-transparent-expression-wrappers@7.24.6': + resolution: {integrity: sha512-jhbbkK3IUKc4T43WadP96a27oYti9gEf1LdyGSP2rHGH77kwLwfhO7TgwnWvxxQVmke0ImmCSS47vcuxEMGD3Q==} engines: {node: '>=6.9.0'} - '@babel/helper-split-export-declaration@7.24.5': - resolution: {integrity: sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==} + '@babel/helper-split-export-declaration@7.24.6': + resolution: {integrity: sha512-CvLSkwXGWnYlF9+J3iZUvwgAxKiYzK3BWuo+mLzD/MDGOZDj7Gq8+hqaOkMxmJwmlv0iu86uH5fdADd9Hxkymw==} engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.24.1': - resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==} + '@babel/helper-string-parser@7.24.6': + resolution: {integrity: sha512-WdJjwMEkmBicq5T9fm/cHND3+UlFa2Yj8ALLgmoSQAJZysYbBjw+azChSGPN4DSPLXOcooGRvDwZWMcF/mLO2Q==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.24.5': - resolution: {integrity: sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==} + '@babel/helper-validator-identifier@7.24.6': + resolution: {integrity: sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.23.5': - resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} + '@babel/helper-validator-option@7.24.6': + resolution: {integrity: sha512-Jktc8KkF3zIkePb48QO+IapbXlSapOW9S+ogZZkcO6bABgYAxtZcjZ/O005111YLf+j4M84uEgwYoidDkXbCkQ==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.24.5': - resolution: {integrity: sha512-CiQmBMMpMQHwM5m01YnrM6imUG1ebgYJ+fAIW4FZe6m4qHTPaRHti+R8cggAwkdz4oXhtO4/K9JWlh+8hIfR2Q==} + '@babel/helpers@7.24.6': + resolution: {integrity: sha512-V2PI+NqnyFu1i0GyTd/O/cTpxzQCYioSkUIRmgo7gFEHKKCg5w46+r/A6WeUR1+P3TeQ49dspGPNd/E3n9AnnA==} engines: {node: '>=6.9.0'} - '@babel/highlight@7.24.5': - resolution: {integrity: sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw==} + '@babel/highlight@7.24.6': + resolution: {integrity: sha512-2YnuOp4HAk2BsBrJJvYCbItHx0zWscI1C3zgWkz+wDyD9I7GIVrfnLyrR4Y1VR+7p+chAEcrgRQYZAGIKMV7vQ==} engines: {node: '>=6.9.0'} - '@babel/parser@7.24.5': - resolution: {integrity: sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==} + '@babel/parser@7.24.6': + resolution: {integrity: sha512-eNZXdfU35nJC2h24RznROuOpO94h6x8sg9ju0tT9biNtLZ2vuP8SduLqqV+/8+cebSLV9SJEAN5Z3zQbJG/M+Q==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/plugin-syntax-jsx@7.24.1': - resolution: {integrity: sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==} + '@babel/plugin-syntax-jsx@7.24.6': + resolution: {integrity: sha512-lWfvAIFNWMlCsU0DRUun2GpFwZdGTukLaHJqRh1JRb80NdAP5Sb1HDHB5X9P9OtgZHQl089UzQkpYlBq2VTPRw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-typescript@7.24.1': - resolution: {integrity: sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==} + '@babel/plugin-syntax-typescript@7.24.6': + resolution: {integrity: sha512-TzCtxGgVTEJWWwcYwQhCIQ6WaKlo80/B+Onsk4RRCcYqpYGFcG9etPW94VToGte5AAcxRrhjPUFvUS3Y2qKi4A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx-self@7.24.5': - resolution: {integrity: sha512-RtCJoUO2oYrYwFPtR1/jkoBEcFuI1ae9a9IMxeyAVa3a1Ap4AnxmyIKG2b2FaJKqkidw/0cxRbWN+HOs6ZWd1w==} + '@babel/plugin-transform-react-jsx-self@7.24.6': + resolution: {integrity: sha512-FfZfHXtQ5jYPQsCRyLpOv2GeLIIJhs8aydpNh39vRDjhD411XcfWDni5i7OjP/Rs8GAtTn7sWFFELJSHqkIxYg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx-source@7.24.1': - resolution: {integrity: sha512-1v202n7aUq4uXAieRTKcwPzNyphlCuqHHDcdSNc+vdhoTEZcFMh+L5yZuCmGaIO7bs1nJUNfHB89TZyoL48xNA==} + '@babel/plugin-transform-react-jsx-source@7.24.6': + resolution: {integrity: sha512-BQTBCXmFRreU3oTUXcGKuPOfXAGb1liNY4AvvFKsOBAJ89RKcTsIrSsnMYkj59fNa66OFKnSa4AJZfy5Y4B9WA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx@7.23.4': - resolution: {integrity: sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==} + '@babel/plugin-transform-react-jsx@7.24.6': + resolution: {integrity: sha512-pCtPHhpRZHfwdA5G1Gpk5mIzMA99hv0R8S/Ket50Rw+S+8hkt3wBWqdqHaPw0CuUYxdshUgsPiLQ5fAs4ASMhw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typescript@7.24.5': - resolution: {integrity: sha512-E0VWu/hk83BIFUWnsKZ4D81KXjN5L3MobvevOHErASk9IPwKHOkTgvqzvNo1yP/ePJWqqK2SpUR5z+KQbl6NVw==} + '@babel/plugin-transform-typescript@7.24.6': + resolution: {integrity: sha512-H0i+hDLmaYYSt6KU9cZE0gb3Cbssa/oxWis7PX4ofQzbvsfix9Lbh8SRk7LCPDlLWJHUiFeHU0qRRpF/4Zv7mQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/template@7.24.0': - resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==} + '@babel/template@7.24.6': + resolution: {integrity: sha512-3vgazJlLwNXi9jhrR1ef8qiB65L1RK90+lEQwv4OxveHnqC3BfmnHdgySwRLzf6akhlOYenT+b7AfWq+a//AHw==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.24.5': - resolution: {integrity: sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA==} + '@babel/traverse@7.24.6': + resolution: {integrity: sha512-OsNjaJwT9Zn8ozxcfoBc+RaHdj3gFmCmYoQLUII1o6ZrUwku0BMg80FoOTPx+Gi6XhcQxAYE4xyjPTo4SxEQqw==} engines: {node: '>=6.9.0'} - '@babel/types@7.24.5': - resolution: {integrity: sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==} + '@babel/types@7.24.6': + resolution: {integrity: sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ==} engines: {node: '>=6.9.0'} + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + '@emotion/is-prop-valid@1.2.2': resolution: {integrity: sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==} @@ -416,6 +435,9 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -432,83 +454,83 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@rollup/rollup-android-arm-eabi@4.17.2': - resolution: {integrity: sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==} + '@rollup/rollup-android-arm-eabi@4.18.0': + resolution: {integrity: sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.17.2': - resolution: {integrity: sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==} + '@rollup/rollup-android-arm64@4.18.0': + resolution: {integrity: sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.17.2': - resolution: {integrity: sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==} + '@rollup/rollup-darwin-arm64@4.18.0': + resolution: {integrity: sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.17.2': - resolution: {integrity: sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==} + '@rollup/rollup-darwin-x64@4.18.0': + resolution: {integrity: sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==} cpu: [x64] os: [darwin] - '@rollup/rollup-linux-arm-gnueabihf@4.17.2': - resolution: {integrity: sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==} + '@rollup/rollup-linux-arm-gnueabihf@4.18.0': + resolution: {integrity: sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.17.2': - resolution: {integrity: sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==} + '@rollup/rollup-linux-arm-musleabihf@4.18.0': + resolution: {integrity: sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.17.2': - resolution: {integrity: sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==} + '@rollup/rollup-linux-arm64-gnu@4.18.0': + resolution: {integrity: sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.17.2': - resolution: {integrity: sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==} + '@rollup/rollup-linux-arm64-musl@4.18.0': + resolution: {integrity: sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.17.2': - resolution: {integrity: sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==} + '@rollup/rollup-linux-powerpc64le-gnu@4.18.0': + resolution: {integrity: sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.17.2': - resolution: {integrity: sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==} + '@rollup/rollup-linux-riscv64-gnu@4.18.0': + resolution: {integrity: sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.17.2': - resolution: {integrity: sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==} + '@rollup/rollup-linux-s390x-gnu@4.18.0': + resolution: {integrity: sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.17.2': - resolution: {integrity: sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==} + '@rollup/rollup-linux-x64-gnu@4.18.0': + resolution: {integrity: sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.17.2': - resolution: {integrity: sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==} + '@rollup/rollup-linux-x64-musl@4.18.0': + resolution: {integrity: sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.17.2': - resolution: {integrity: sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==} + '@rollup/rollup-win32-arm64-msvc@4.18.0': + resolution: {integrity: sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.17.2': - resolution: {integrity: sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==} + '@rollup/rollup-win32-ia32-msvc@4.18.0': + resolution: {integrity: sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.17.2': - resolution: {integrity: sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==} + '@rollup/rollup-win32-x64-msvc@4.18.0': + resolution: {integrity: sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==} cpu: [x64] os: [win32] @@ -516,16 +538,16 @@ packages: resolution: {integrity: sha512-rahAZXlR879P7dngDH7BZwGYiODA9D5Hqo6nUHn9GAURcqZU5IW0ZiT54dPtV5EPES7muZZmknReYueDHs7FFQ==} engines: {node: '>=12'} - '@tanstack/query-core@5.36.0': - resolution: {integrity: sha512-B5BD3pg/mztDR36i77hGcyySKKeYrbM5mnogOROTBi1SUml5ByRK7PGUUl16vvubvQC+mSnqziFG/VIy/DE3FQ==} + '@tanstack/query-core@5.40.0': + resolution: {integrity: sha512-eD8K8jsOIq0Z5u/QbvOmfvKKE/XC39jA7yv4hgpl/1SRiU+J8QCIwgM/mEHuunQsL87dcvnHqSVLmf9pD4CiaA==} - '@tanstack/react-query@5.36.0': - resolution: {integrity: sha512-BATvtM0rohwg7pRHUnxgeDiwLWRGZ8OM/4y8LImHVpecQWoH6Uhytu3Z8YV6V7hQ1sMQBFcUrGE1/e4MxR6YiA==} + '@tanstack/react-query@5.40.0': + resolution: {integrity: sha512-iv/W0Axc4aXhFzkrByToE1JQqayxTPNotCoSCnarR/A1vDIHaoKpg7FTIfP3Ev2mbKn1yrxq0ZKYUdLEJxs6Tg==} peerDependencies: react: ^18.0.0 - '@tanstack/react-router@1.32.5': - resolution: {integrity: sha512-3W8db+P2KAJRY+zwxDzVUS99SFbs0wT8/je8yS1i3OExXm9BRCPD8EQX8+wk3EDxrEJ0SYjkGExutzSb7m58jA==} + '@tanstack/react-router@1.34.7': + resolution: {integrity: sha512-iS3cFdoKCobYIO4I2I6gw52tylY0kep+MXra3sblFNgKL11kKsfiaO4cYNRqiNg98DEJjboGq+KTXopDMhr07A==} engines: {node: '>=12'} peerDependencies: react: '>=16.8' @@ -537,19 +559,19 @@ packages: react: '>=16' react-dom: '>=16' - '@tanstack/router-generator@1.32.2': - resolution: {integrity: sha512-x/IZSAoqjzfBA4B3VI5kjp7Uu+6JMYvrM827LwG/EhEt+/SXTFgy5IFwK6huFRz/pkExy68pFDyA5vp8ghCHeA==} + '@tanstack/router-generator@1.34.8': + resolution: {integrity: sha512-xi0otLis4zQ8lYVgvNfUTDHKnboL2swXpHcLiG+bKYDihPnw4r3qRO0ULGsqV1n/w6yZAaQ2tZwvZ7Zf0G2pPg==} engines: {node: '>=12'} - '@tanstack/router-vite-plugin@1.32.2': - resolution: {integrity: sha512-1djQJlCyPIWai1SvaBCoWuJoanzgcyywLPzPVYB//kXn/iLde1xBunQT09vTJk5EXt1amqQ82htS6z3ECM0Z0g==} + '@tanstack/router-vite-plugin@1.34.8': + resolution: {integrity: sha512-FZRl7GVda/1NMEbnalXhYI2e9Qe8MduxXRNZ2cJMYgPR/FxMiao+XQAN+mTD4OoMxJ8gKY+IshgRxCc3xwu6bA==} engines: {node: '>=12'} '@tanstack/store@0.1.3': resolution: {integrity: sha512-GnolmC8Fr4mvsHE1fGQmR3Nm0eBO3KnZjDU0a+P3TeQNM/dDscFGxtA7p31NplQNW3KwBw4t1RVFmz0VeKLxcw==} - '@tauri-apps/api@1.5.5': - resolution: {integrity: sha512-Jgwj8BK/9YXZNzcqVDk1Al7+u5V9sWrZ8MhV41A1AKgJaicHuqlkc/qdx06sNDXvc+qprTPpBAaqnt891qOUIQ==} + '@tauri-apps/api@1.5.6': + resolution: {integrity: sha512-LH5ToovAHnDVe5Qa9f/+jW28I6DeMhos8bNDtBOmmnaDpPmJmYLyHdeDblAWWWYc7KKRDg9/66vMuKyq0WIeFA==} engines: {node: '>= 14.6.0', npm: '>= 6.6.0', yarn: '>= 1.19.1'} '@tauri-apps/cli-darwin-arm64@1.5.14': @@ -617,6 +639,21 @@ packages: engines: {node: '>= 10'} hasBin: true + '@total-typescript/ts-reset@0.5.1': + resolution: {integrity: sha512-AqlrT8YA1o7Ff5wPfMOL0pvL+1X+sw60NN6CcOCqs658emD6RfiXhF7Gu9QcfKBH7ELY2nInLhKSCWVoNL70MQ==} + + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -626,14 +663,14 @@ packages: '@types/babel__template@7.4.4': resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - '@types/babel__traverse@7.20.5': - resolution: {integrity: sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==} + '@types/babel__traverse@7.20.6': + resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - '@types/node@20.12.12': - resolution: {integrity: sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==} + '@types/node@20.12.13': + resolution: {integrity: sha512-gBGeanV41c1L171rR7wjbMiEpEI/l5XFQdLLfhr/REwpgDy/4U8y89+i8kRiLzDyZdOkXh+cRaTetUnCYutoXA==} '@types/prop-types@15.7.12': resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==} @@ -641,15 +678,24 @@ packages: '@types/react-dom@18.3.0': resolution: {integrity: sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==} - '@types/react@18.3.2': - resolution: {integrity: sha512-Btgg89dAnqD4vV7R3hlwOxgqobUQKgx3MmrQRi0yYbs/P0ym8XozIAlkqVilPqHQwXs4e9Tf63rrCgl58BcO4w==} + '@types/react@18.3.3': + resolution: {integrity: sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==} - '@vitejs/plugin-react@4.2.1': - resolution: {integrity: sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==} + '@vitejs/plugin-react@4.3.0': + resolution: {integrity: sha512-KcEbMsn4Dpk+LIbHMj7gDPRKaTMStxxWRkRmxsg/jVdFdJCZWt1SchZcf0M4t8lIKdwwMsEyzhrcOXRrDPtOBw==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: vite: ^4.2.0 || ^5.0.0 + acorn-walk@8.3.2: + resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} + engines: {node: '>=0.4.0'} + + acorn@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + engines: {node: '>=0.4.0'} + hasBin: true + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -677,6 +723,9 @@ packages: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + arg@5.0.2: resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} @@ -697,8 +746,8 @@ packages: brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - braces@3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} browserslist@4.23.0: @@ -710,8 +759,8 @@ packages: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} - caniuse-lite@1.0.30001618: - resolution: {integrity: sha512-p407+D1tIkDvsEAPS22lJxLQQaG8OTBEqo0KhzfABGk0TU4juBNDSfH0hyAp/HRyx+M8L17z/ltyhxh27FTfQg==} + caniuse-lite@1.0.30001625: + resolution: {integrity: sha512-4KE9N2gcRH+HQhpeiRZXd+1niLB/XNLAhSy4z7fI8EzcbcPoAqjNInxVHTiTwWfTIV4w096XG8OtCOCQQKPv3w==} chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} @@ -721,6 +770,9 @@ packages: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} + chroma-js@2.4.2: + resolution: {integrity: sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A==} + clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} @@ -745,6 +797,9 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -769,14 +824,21 @@ packages: didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + dlv@1.1.3: resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + easing-coordinates@2.0.2: + resolution: {integrity: sha512-uQpJaLQX2CKVnN27YvN4sL4pXyEFGAv00y4zgrC46H0EBHrDhJc/8OsT2CQ5/6yz6+d+u8ACGd9bo4v83FNVlg==} + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - electron-to-chromium@1.4.769: - resolution: {integrity: sha512-bZu7p623NEA2rHTc9K1vykl57ektSPQYFFqQir8BOYf6EKOB+yIsbFB9Kpm7Cgt6tsLr9sRkqfqSZUw7LP1XxQ==} + electron-to-chromium@1.4.787: + resolution: {integrity: sha512-d0EFmtLPjctczO3LogReyM2pbBiiZbnsKnGF+cdZhsYzHm/A0GV7W94kqzLD8SN4O3f3iHlgLUChqghgyznvCQ==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -804,8 +866,8 @@ packages: fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} - fill-range@7.0.1: - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} foreground-child@3.1.1: @@ -815,8 +877,8 @@ packages: fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} - framer-motion@11.2.0: - resolution: {integrity: sha512-LRfLVPEwtO9IXJCAsWvtj3XZxrdZDcTxNNkZEq30aQ8p7/wimfUkDy67TDWdtzPiyKDkqOHDhaQC6XVrQ4Fh7A==} + framer-motion@11.2.9: + resolution: {integrity: sha512-gfxNSkp4dC3vpy2hGNQK3K9bNOKwfasqOhrqvmZzYxCPSJ9Tpv/9JlCkeCMgFdKefgPr8+JiouGjVmaDzu750w==} peerDependencies: '@emotion/is-prop-valid': '*' react: ^18.0.0 @@ -841,6 +903,9 @@ packages: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} + get-tsconfig@4.7.5: + resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -849,8 +914,8 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} - glob@10.3.15: - resolution: {integrity: sha512-0c6RlJt1TICLyvJYIApxb8GsXoai0KUP7AxKKAtsYXdgJR1mGEUa7DgwShbdk1nly0PYoZj01xd4hzbq3fsjpw==} + glob@10.4.1: + resolution: {integrity: sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==} engines: {node: '>=16 || 14 >=14.18'} hasBin: true @@ -892,8 +957,8 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - jackspeak@2.3.6: - resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} + jackspeak@3.1.2: + resolution: {integrity: sha512-kWmLKn2tRtfYMF/BakihVVRzBKOxz4gJMiL2Rj91WnAB5TPZumSH99R/Yf1qE1u4uRimvCSJfm6hnxohXeEXjQ==} engines: {node: '>=14'} jiti@1.21.0: @@ -935,25 +1000,28 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - lucide-react@0.378.0: - resolution: {integrity: sha512-u6EPU8juLUk9ytRcyapkWI18epAv3RU+6+TC23ivjR0e+glWKBobFeSgRwOIJihzktILQuy6E0E80P2jVTDR5g==} + lucide-react@0.381.0: + resolution: {integrity: sha512-cft0ywFfHkGprX5pwKyS9jme/ksh9eYAHSZqFRKN0XGp70kia4uqZOTPB+i+O51cqiJlvGLqzMGWnMHaeJTs3g==} peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + micromatch@4.0.7: + resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} engines: {node: '>=8.6'} minimatch@9.0.4: resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} engines: {node: '>=16 || 14 >=14.17'} - minipass@7.1.1: - resolution: {integrity: sha512-UZ7eQ+h8ywIRAW1hIEl2AqdwzJucU/Kp59+8kkZeSvafXhZjul247BvIJjEVFVeON6d7lM46XX1HXCduKAS8VA==} + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} ms@2.1.2: @@ -1042,8 +1110,8 @@ packages: peerDependencies: postcss: ^8.2.14 - postcss-selector-parser@6.0.16: - resolution: {integrity: sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==} + postcss-selector-parser@6.1.0: + resolution: {integrity: sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==} engines: {node: '>=4'} postcss-value-parser@4.2.0: @@ -1066,8 +1134,8 @@ packages: '@volar/vue-typescript': optional: true - prettier-plugin-tailwindcss@0.5.14: - resolution: {integrity: sha512-Puaz+wPUAhFp8Lo9HuciYKM2Y2XExESjeT+9NQoVFXZsPPnc9VYss2SpxdQ6vbatmt8/4+SN0oe0I1cPDABg9Q==} + prettier-plugin-tailwindcss@0.6.0: + resolution: {integrity: sha512-l5F3iG54XbOq/2DOPP/YA+c6VE3/qXrcBccntq2v7PSxtEc+J6SwsuTyDHxoFK1+jAlcU/hECBfzn6MON6ENBg==} engines: {node: '>=14.21.3'} peerDependencies: '@ianvs/prettier-plugin-sort-imports': '*' @@ -1126,6 +1194,9 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + ramda@0.26.1: + resolution: {integrity: sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ==} + react-dom@18.3.1: resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} peerDependencies: @@ -1146,6 +1217,13 @@ packages: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} + readline-sync@1.4.10: + resolution: {integrity: sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==} + engines: {node: '>= 0.8.0'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + resolve@1.22.8: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true @@ -1154,8 +1232,8 @@ packages: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rollup@4.17.2: - resolution: {integrity: sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==} + rollup@4.18.0: + resolution: {integrity: sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -1169,6 +1247,11 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true + semver@7.6.2: + resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} + engines: {node: '>=10'} + hasBin: true + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -1220,6 +1303,9 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + tailwind-easing-gradients@1.0.2: + resolution: {integrity: sha512-q4NNbxoCsQP8kL/i+kOD43Bdyvz/Ok/nC98jLOc6l8H7x3LbV2HK9hvSnB/fwK8jp6FNfFBUmHuiCa0QV5rG2A==} + tailwindcss@3.4.3: resolution: {integrity: sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==} engines: {node: '>=14.0.0'} @@ -1249,9 +1335,28 @@ packages: ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + tsx@4.11.0: + resolution: {integrity: sha512-vzGGELOgAupsNVssAmZjbUDfdm/pWP4R+Kg8TVdsonxbXk0bEpE1qh0yV6/QxUVXaVlNemgcPajGdJJ82n3stg==} + engines: {node: '>=18.0.0'} + hasBin: true + typescript@5.4.5: resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} engines: {node: '>=14.17'} @@ -1274,13 +1379,16 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + vite-plugin-package-version@1.1.0: resolution: {integrity: sha512-TPoFZXNanzcaKCIrC3e2L/TVRkkRLB6l4RPN/S7KbG7rWfyLcCEGsnXvxn6qR7fyZwXalnnSN/I9d6pSFjHpEA==} peerDependencies: vite: '>=2.0.0-beta.69' - vite@5.2.11: - resolution: {integrity: sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==} + vite@5.2.12: + resolution: {integrity: sha512-/gC8GxzxMK5ntBwb48pR32GGhENnjtY30G4A0jemunsBkiEZFw60s8InGpN8gkhHEkjnRK1aSAxeQgwvFhUHAA==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -1328,6 +1436,10 @@ packages: engines: {node: '>= 14'} hasBin: true + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + zod@3.23.8: resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} @@ -1340,25 +1452,25 @@ snapshots: '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 - '@babel/code-frame@7.24.2': + '@babel/code-frame@7.24.6': dependencies: - '@babel/highlight': 7.24.5 + '@babel/highlight': 7.24.6 picocolors: 1.0.1 - '@babel/compat-data@7.24.4': {} + '@babel/compat-data@7.24.6': {} - '@babel/core@7.24.5': + '@babel/core@7.24.6': dependencies: '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.24.2 - '@babel/generator': 7.24.5 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-module-transforms': 7.24.5(@babel/core@7.24.5) - '@babel/helpers': 7.24.5 - '@babel/parser': 7.24.5 - '@babel/template': 7.24.0 - '@babel/traverse': 7.24.5 - '@babel/types': 7.24.5 + '@babel/code-frame': 7.24.6 + '@babel/generator': 7.24.6 + '@babel/helper-compilation-targets': 7.24.6 + '@babel/helper-module-transforms': 7.24.6(@babel/core@7.24.6) + '@babel/helpers': 7.24.6 + '@babel/parser': 7.24.6 + '@babel/template': 7.24.6 + '@babel/traverse': 7.24.6 + '@babel/types': 7.24.6 convert-source-map: 2.0.0 debug: 4.3.4 gensync: 1.0.0-beta.2 @@ -1367,180 +1479,182 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/generator@7.24.5': + '@babel/generator@7.24.6': dependencies: - '@babel/types': 7.24.5 + '@babel/types': 7.24.6 '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 jsesc: 2.5.2 - '@babel/helper-annotate-as-pure@7.22.5': + '@babel/helper-annotate-as-pure@7.24.6': dependencies: - '@babel/types': 7.24.5 + '@babel/types': 7.24.6 - '@babel/helper-compilation-targets@7.23.6': + '@babel/helper-compilation-targets@7.24.6': dependencies: - '@babel/compat-data': 7.24.4 - '@babel/helper-validator-option': 7.23.5 + '@babel/compat-data': 7.24.6 + '@babel/helper-validator-option': 7.24.6 browserslist: 4.23.0 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.24.5(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-member-expression-to-functions': 7.24.5 - '@babel/helper-optimise-call-expression': 7.22.5 - '@babel/helper-replace-supers': 7.24.1(@babel/core@7.24.5) - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/helper-split-export-declaration': 7.24.5 + '@babel/helper-create-class-features-plugin@7.24.6(@babel/core@7.24.6)': + dependencies: + '@babel/core': 7.24.6 + '@babel/helper-annotate-as-pure': 7.24.6 + '@babel/helper-environment-visitor': 7.24.6 + '@babel/helper-function-name': 7.24.6 + '@babel/helper-member-expression-to-functions': 7.24.6 + '@babel/helper-optimise-call-expression': 7.24.6 + '@babel/helper-replace-supers': 7.24.6(@babel/core@7.24.6) + '@babel/helper-skip-transparent-expression-wrappers': 7.24.6 + '@babel/helper-split-export-declaration': 7.24.6 semver: 6.3.1 - '@babel/helper-environment-visitor@7.22.20': {} + '@babel/helper-environment-visitor@7.24.6': {} - '@babel/helper-function-name@7.23.0': + '@babel/helper-function-name@7.24.6': dependencies: - '@babel/template': 7.24.0 - '@babel/types': 7.24.5 + '@babel/template': 7.24.6 + '@babel/types': 7.24.6 - '@babel/helper-hoist-variables@7.22.5': + '@babel/helper-hoist-variables@7.24.6': dependencies: - '@babel/types': 7.24.5 + '@babel/types': 7.24.6 - '@babel/helper-member-expression-to-functions@7.24.5': + '@babel/helper-member-expression-to-functions@7.24.6': dependencies: - '@babel/types': 7.24.5 + '@babel/types': 7.24.6 - '@babel/helper-module-imports@7.24.3': + '@babel/helper-module-imports@7.24.6': dependencies: - '@babel/types': 7.24.5 + '@babel/types': 7.24.6 - '@babel/helper-module-transforms@7.24.5(@babel/core@7.24.5)': + '@babel/helper-module-transforms@7.24.6(@babel/core@7.24.6)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-module-imports': 7.24.3 - '@babel/helper-simple-access': 7.24.5 - '@babel/helper-split-export-declaration': 7.24.5 - '@babel/helper-validator-identifier': 7.24.5 + '@babel/core': 7.24.6 + '@babel/helper-environment-visitor': 7.24.6 + '@babel/helper-module-imports': 7.24.6 + '@babel/helper-simple-access': 7.24.6 + '@babel/helper-split-export-declaration': 7.24.6 + '@babel/helper-validator-identifier': 7.24.6 - '@babel/helper-optimise-call-expression@7.22.5': + '@babel/helper-optimise-call-expression@7.24.6': dependencies: - '@babel/types': 7.24.5 + '@babel/types': 7.24.6 - '@babel/helper-plugin-utils@7.24.5': {} + '@babel/helper-plugin-utils@7.24.6': {} - '@babel/helper-replace-supers@7.24.1(@babel/core@7.24.5)': + '@babel/helper-replace-supers@7.24.6(@babel/core@7.24.6)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-member-expression-to-functions': 7.24.5 - '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/core': 7.24.6 + '@babel/helper-environment-visitor': 7.24.6 + '@babel/helper-member-expression-to-functions': 7.24.6 + '@babel/helper-optimise-call-expression': 7.24.6 - '@babel/helper-simple-access@7.24.5': + '@babel/helper-simple-access@7.24.6': dependencies: - '@babel/types': 7.24.5 + '@babel/types': 7.24.6 - '@babel/helper-skip-transparent-expression-wrappers@7.22.5': + '@babel/helper-skip-transparent-expression-wrappers@7.24.6': dependencies: - '@babel/types': 7.24.5 + '@babel/types': 7.24.6 - '@babel/helper-split-export-declaration@7.24.5': + '@babel/helper-split-export-declaration@7.24.6': dependencies: - '@babel/types': 7.24.5 + '@babel/types': 7.24.6 - '@babel/helper-string-parser@7.24.1': {} + '@babel/helper-string-parser@7.24.6': {} - '@babel/helper-validator-identifier@7.24.5': {} + '@babel/helper-validator-identifier@7.24.6': {} - '@babel/helper-validator-option@7.23.5': {} + '@babel/helper-validator-option@7.24.6': {} - '@babel/helpers@7.24.5': + '@babel/helpers@7.24.6': dependencies: - '@babel/template': 7.24.0 - '@babel/traverse': 7.24.5 - '@babel/types': 7.24.5 - transitivePeerDependencies: - - supports-color + '@babel/template': 7.24.6 + '@babel/types': 7.24.6 - '@babel/highlight@7.24.5': + '@babel/highlight@7.24.6': dependencies: - '@babel/helper-validator-identifier': 7.24.5 + '@babel/helper-validator-identifier': 7.24.6 chalk: 2.4.2 js-tokens: 4.0.0 picocolors: 1.0.1 - '@babel/parser@7.24.5': + '@babel/parser@7.24.6': dependencies: - '@babel/types': 7.24.5 + '@babel/types': 7.24.6 - '@babel/plugin-syntax-jsx@7.24.1(@babel/core@7.24.5)': + '@babel/plugin-syntax-jsx@7.24.6(@babel/core@7.24.6)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.24.6 + '@babel/helper-plugin-utils': 7.24.6 - '@babel/plugin-syntax-typescript@7.24.1(@babel/core@7.24.5)': + '@babel/plugin-syntax-typescript@7.24.6(@babel/core@7.24.6)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.24.6 + '@babel/helper-plugin-utils': 7.24.6 - '@babel/plugin-transform-react-jsx-self@7.24.5(@babel/core@7.24.5)': + '@babel/plugin-transform-react-jsx-self@7.24.6(@babel/core@7.24.6)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.24.6 + '@babel/helper-plugin-utils': 7.24.6 - '@babel/plugin-transform-react-jsx-source@7.24.1(@babel/core@7.24.5)': + '@babel/plugin-transform-react-jsx-source@7.24.6(@babel/core@7.24.6)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.24.6 + '@babel/helper-plugin-utils': 7.24.6 - '@babel/plugin-transform-react-jsx@7.23.4(@babel/core@7.24.5)': + '@babel/plugin-transform-react-jsx@7.24.6(@babel/core@7.24.6)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-module-imports': 7.24.3 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.24.5) - '@babel/types': 7.24.5 + '@babel/core': 7.24.6 + '@babel/helper-annotate-as-pure': 7.24.6 + '@babel/helper-module-imports': 7.24.6 + '@babel/helper-plugin-utils': 7.24.6 + '@babel/plugin-syntax-jsx': 7.24.6(@babel/core@7.24.6) + '@babel/types': 7.24.6 - '@babel/plugin-transform-typescript@7.24.5(@babel/core@7.24.5)': + '@babel/plugin-transform-typescript@7.24.6(@babel/core@7.24.6)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.24.5(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 - '@babel/plugin-syntax-typescript': 7.24.1(@babel/core@7.24.5) + '@babel/core': 7.24.6 + '@babel/helper-annotate-as-pure': 7.24.6 + '@babel/helper-create-class-features-plugin': 7.24.6(@babel/core@7.24.6) + '@babel/helper-plugin-utils': 7.24.6 + '@babel/plugin-syntax-typescript': 7.24.6(@babel/core@7.24.6) - '@babel/template@7.24.0': + '@babel/template@7.24.6': dependencies: - '@babel/code-frame': 7.24.2 - '@babel/parser': 7.24.5 - '@babel/types': 7.24.5 + '@babel/code-frame': 7.24.6 + '@babel/parser': 7.24.6 + '@babel/types': 7.24.6 - '@babel/traverse@7.24.5': + '@babel/traverse@7.24.6': dependencies: - '@babel/code-frame': 7.24.2 - '@babel/generator': 7.24.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-split-export-declaration': 7.24.5 - '@babel/parser': 7.24.5 - '@babel/types': 7.24.5 + '@babel/code-frame': 7.24.6 + '@babel/generator': 7.24.6 + '@babel/helper-environment-visitor': 7.24.6 + '@babel/helper-function-name': 7.24.6 + '@babel/helper-hoist-variables': 7.24.6 + '@babel/helper-split-export-declaration': 7.24.6 + '@babel/parser': 7.24.6 + '@babel/types': 7.24.6 debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/types@7.24.5': + '@babel/types@7.24.6': dependencies: - '@babel/helper-string-parser': 7.24.1 - '@babel/helper-validator-identifier': 7.24.5 + '@babel/helper-string-parser': 7.24.6 + '@babel/helper-validator-identifier': 7.24.6 to-fast-properties: 2.0.0 + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + optional: true + '@emotion/is-prop-valid@1.2.2': dependencies: '@emotion/memoize': 0.8.1 @@ -1644,6 +1758,12 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + optional: true + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -1659,64 +1779,64 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@rollup/rollup-android-arm-eabi@4.17.2': + '@rollup/rollup-android-arm-eabi@4.18.0': optional: true - '@rollup/rollup-android-arm64@4.17.2': + '@rollup/rollup-android-arm64@4.18.0': optional: true - '@rollup/rollup-darwin-arm64@4.17.2': + '@rollup/rollup-darwin-arm64@4.18.0': optional: true - '@rollup/rollup-darwin-x64@4.17.2': + '@rollup/rollup-darwin-x64@4.18.0': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.17.2': + '@rollup/rollup-linux-arm-gnueabihf@4.18.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.17.2': + '@rollup/rollup-linux-arm-musleabihf@4.18.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.17.2': + '@rollup/rollup-linux-arm64-gnu@4.18.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.17.2': + '@rollup/rollup-linux-arm64-musl@4.18.0': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.17.2': + '@rollup/rollup-linux-powerpc64le-gnu@4.18.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.17.2': + '@rollup/rollup-linux-riscv64-gnu@4.18.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.17.2': + '@rollup/rollup-linux-s390x-gnu@4.18.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.17.2': + '@rollup/rollup-linux-x64-gnu@4.18.0': optional: true - '@rollup/rollup-linux-x64-musl@4.17.2': + '@rollup/rollup-linux-x64-musl@4.18.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.17.2': + '@rollup/rollup-win32-arm64-msvc@4.18.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.17.2': + '@rollup/rollup-win32-ia32-msvc@4.18.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.17.2': + '@rollup/rollup-win32-x64-msvc@4.18.0': optional: true '@tanstack/history@1.31.16': {} - '@tanstack/query-core@5.36.0': {} + '@tanstack/query-core@5.40.0': {} - '@tanstack/react-query@5.36.0(react@18.3.1)': + '@tanstack/react-query@5.40.0(react@18.3.1)': dependencies: - '@tanstack/query-core': 5.36.0 + '@tanstack/query-core': 5.40.0 react: 18.3.1 - '@tanstack/react-router@1.32.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@tanstack/react-router@1.34.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@tanstack/history': 1.31.16 '@tanstack/react-store': 0.2.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -1732,28 +1852,28 @@ snapshots: react-dom: 18.3.1(react@18.3.1) use-sync-external-store: 1.2.2(react@18.3.1) - '@tanstack/router-generator@1.32.2': + '@tanstack/router-generator@1.34.8': dependencies: prettier: 3.2.5 zod: 3.23.8 - '@tanstack/router-vite-plugin@1.32.2(vite@5.2.11(@types/node@20.12.12))': - dependencies: - '@babel/core': 7.24.5 - '@babel/generator': 7.24.5 - '@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-syntax-typescript': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-react-jsx': 7.23.4(@babel/core@7.24.5) - '@babel/plugin-transform-typescript': 7.24.5(@babel/core@7.24.5) - '@babel/template': 7.24.0 - '@babel/traverse': 7.24.5 - '@babel/types': 7.24.5 - '@tanstack/router-generator': 1.32.2 + '@tanstack/router-vite-plugin@1.34.8(vite@5.2.12(@types/node@20.12.13))': + dependencies: + '@babel/core': 7.24.6 + '@babel/generator': 7.24.6 + '@babel/plugin-syntax-jsx': 7.24.6(@babel/core@7.24.6) + '@babel/plugin-syntax-typescript': 7.24.6(@babel/core@7.24.6) + '@babel/plugin-transform-react-jsx': 7.24.6(@babel/core@7.24.6) + '@babel/plugin-transform-typescript': 7.24.6(@babel/core@7.24.6) + '@babel/template': 7.24.6 + '@babel/traverse': 7.24.6 + '@babel/types': 7.24.6 + '@tanstack/router-generator': 1.34.8 '@types/babel__core': 7.20.5 '@types/babel__generator': 7.6.8 '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.20.5 - '@vitejs/plugin-react': 4.2.1(vite@5.2.11(@types/node@20.12.12)) + '@types/babel__traverse': 7.20.6 + '@vitejs/plugin-react': 4.3.0(vite@5.2.12(@types/node@20.12.13)) zod: 3.23.8 transitivePeerDependencies: - supports-color @@ -1761,7 +1881,7 @@ snapshots: '@tanstack/store@0.1.3': {} - '@tauri-apps/api@1.5.5': {} + '@tauri-apps/api@1.5.6': {} '@tauri-apps/cli-darwin-arm64@1.5.14': optional: true @@ -1806,30 +1926,44 @@ snapshots: '@tauri-apps/cli-win32-ia32-msvc': 1.5.14 '@tauri-apps/cli-win32-x64-msvc': 1.5.14 + '@total-typescript/ts-reset@0.5.1': {} + + '@tsconfig/node10@1.0.11': + optional: true + + '@tsconfig/node12@1.0.11': + optional: true + + '@tsconfig/node14@1.0.3': + optional: true + + '@tsconfig/node16@1.0.4': + optional: true + '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.24.5 - '@babel/types': 7.24.5 + '@babel/parser': 7.24.6 + '@babel/types': 7.24.6 '@types/babel__generator': 7.6.8 '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.20.5 + '@types/babel__traverse': 7.20.6 '@types/babel__generator@7.6.8': dependencies: - '@babel/types': 7.24.5 + '@babel/types': 7.24.6 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.24.5 - '@babel/types': 7.24.5 + '@babel/parser': 7.24.6 + '@babel/types': 7.24.6 - '@types/babel__traverse@7.20.5': + '@types/babel__traverse@7.20.6': dependencies: - '@babel/types': 7.24.5 + '@babel/types': 7.24.6 '@types/estree@1.0.5': {} - '@types/node@20.12.12': + '@types/node@20.12.13': dependencies: undici-types: 5.26.5 @@ -1837,24 +1971,30 @@ snapshots: '@types/react-dom@18.3.0': dependencies: - '@types/react': 18.3.2 + '@types/react': 18.3.3 - '@types/react@18.3.2': + '@types/react@18.3.3': dependencies: '@types/prop-types': 15.7.12 csstype: 3.1.3 - '@vitejs/plugin-react@4.2.1(vite@5.2.11(@types/node@20.12.12))': + '@vitejs/plugin-react@4.3.0(vite@5.2.12(@types/node@20.12.13))': dependencies: - '@babel/core': 7.24.5 - '@babel/plugin-transform-react-jsx-self': 7.24.5(@babel/core@7.24.5) - '@babel/plugin-transform-react-jsx-source': 7.24.1(@babel/core@7.24.5) + '@babel/core': 7.24.6 + '@babel/plugin-transform-react-jsx-self': 7.24.6(@babel/core@7.24.6) + '@babel/plugin-transform-react-jsx-source': 7.24.6(@babel/core@7.24.6) '@types/babel__core': 7.20.5 react-refresh: 0.14.2 - vite: 5.2.11(@types/node@20.12.12) + vite: 5.2.12(@types/node@20.12.13) transitivePeerDependencies: - supports-color + acorn-walk@8.3.2: + optional: true + + acorn@8.11.3: + optional: true + ansi-regex@5.0.1: {} ansi-regex@6.0.1: {} @@ -1876,12 +2016,15 @@ snapshots: normalize-path: 3.0.0 picomatch: 2.3.1 + arg@4.1.3: + optional: true + arg@5.0.2: {} autoprefixer@10.4.19(postcss@8.4.38): dependencies: browserslist: 4.23.0 - caniuse-lite: 1.0.30001618 + caniuse-lite: 1.0.30001625 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.0.1 @@ -1896,20 +2039,20 @@ snapshots: dependencies: balanced-match: 1.0.2 - braces@3.0.2: + braces@3.0.3: dependencies: - fill-range: 7.0.1 + fill-range: 7.1.1 browserslist@4.23.0: dependencies: - caniuse-lite: 1.0.30001618 - electron-to-chromium: 1.4.769 + caniuse-lite: 1.0.30001625 + electron-to-chromium: 1.4.787 node-releases: 2.0.14 update-browserslist-db: 1.0.16(browserslist@4.23.0) camelcase-css@2.0.1: {} - caniuse-lite@1.0.30001618: {} + caniuse-lite@1.0.30001625: {} chalk@2.4.2: dependencies: @@ -1920,7 +2063,7 @@ snapshots: chokidar@3.6.0: dependencies: anymatch: 3.1.3 - braces: 3.0.2 + braces: 3.0.3 glob-parent: 5.1.2 is-binary-path: 2.1.0 is-glob: 4.0.3 @@ -1929,6 +2072,8 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + chroma-js@2.4.2: {} + clsx@2.1.1: {} color-convert@1.9.3: @@ -1947,6 +2092,9 @@ snapshots: convert-source-map@2.0.0: {} + create-require@1.1.1: + optional: true + cross-spawn@7.0.3: dependencies: path-key: 3.1.1 @@ -1963,11 +2111,16 @@ snapshots: didyoumean@1.2.2: {} + diff@4.0.2: + optional: true + dlv@1.1.3: {} + easing-coordinates@2.0.2: {} + eastasianwidth@0.2.0: {} - electron-to-chromium@1.4.769: {} + electron-to-chromium@1.4.787: {} emoji-regex@8.0.0: {} @@ -2009,13 +2162,13 @@ snapshots: '@nodelib/fs.walk': 1.2.8 glob-parent: 5.1.2 merge2: 1.4.1 - micromatch: 4.0.5 + micromatch: 4.0.7 fastq@1.17.1: dependencies: reusify: 1.0.4 - fill-range@7.0.1: + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -2026,7 +2179,7 @@ snapshots: fraction.js@4.3.7: {} - framer-motion@11.2.0(@emotion/is-prop-valid@1.2.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + framer-motion@11.2.9(@emotion/is-prop-valid@1.2.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: tslib: 2.6.2 optionalDependencies: @@ -2041,6 +2194,10 @@ snapshots: gensync@1.0.0-beta.2: {} + get-tsconfig@4.7.5: + dependencies: + resolve-pkg-maps: 1.0.0 + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -2049,12 +2206,12 @@ snapshots: dependencies: is-glob: 4.0.3 - glob@10.3.15: + glob@10.4.1: dependencies: foreground-child: 3.1.1 - jackspeak: 2.3.6 + jackspeak: 3.1.2 minimatch: 9.0.4 - minipass: 7.1.1 + minipass: 7.1.2 path-scurry: 1.11.1 globals@11.12.0: {} @@ -2085,7 +2242,7 @@ snapshots: isexe@2.0.0: {} - jackspeak@2.3.6: + jackspeak@3.1.2: dependencies: '@isaacs/cliui': 8.0.2 optionalDependencies: @@ -2115,22 +2272,25 @@ snapshots: dependencies: yallist: 3.1.1 - lucide-react@0.378.0(react@18.3.1): + lucide-react@0.381.0(react@18.3.1): dependencies: react: 18.3.1 + make-error@1.3.6: + optional: true + merge2@1.4.1: {} - micromatch@4.0.5: + micromatch@4.0.7: dependencies: - braces: 3.0.2 + braces: 3.0.3 picomatch: 2.3.1 minimatch@9.0.4: dependencies: brace-expansion: 2.0.1 - minipass@7.1.1: {} + minipass@7.1.2: {} ms@2.1.2: {} @@ -2159,7 +2319,7 @@ snapshots: path-scurry@1.11.1: dependencies: lru-cache: 10.2.2 - minipass: 7.1.1 + minipass: 7.1.2 picocolors@1.0.1: {} @@ -2181,19 +2341,20 @@ snapshots: camelcase-css: 2.0.1 postcss: 8.4.38 - postcss-load-config@4.0.2(postcss@8.4.38): + postcss-load-config@4.0.2(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.12.13)(typescript@5.4.5)): dependencies: lilconfig: 3.1.1 yaml: 2.4.2 optionalDependencies: postcss: 8.4.38 + ts-node: 10.9.2(@types/node@20.12.13)(typescript@5.4.5) postcss-nested@6.0.1(postcss@8.4.38): dependencies: postcss: 8.4.38 - postcss-selector-parser: 6.0.16 + postcss-selector-parser: 6.1.0 - postcss-selector-parser@6.0.16: + postcss-selector-parser@6.1.0: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 @@ -2211,7 +2372,7 @@ snapshots: prettier: 3.2.5 typescript: 5.4.5 - prettier-plugin-tailwindcss@0.5.14(prettier-plugin-organize-imports@3.2.4(prettier@3.2.5)(typescript@5.4.5))(prettier@3.2.5): + prettier-plugin-tailwindcss@0.6.0(prettier-plugin-organize-imports@3.2.4(prettier@3.2.5)(typescript@5.4.5))(prettier@3.2.5): dependencies: prettier: 3.2.5 optionalDependencies: @@ -2221,6 +2382,8 @@ snapshots: queue-microtask@1.2.3: {} + ramda@0.26.1: {} + react-dom@18.3.1(react@18.3.1): dependencies: loose-envify: 1.4.0 @@ -2241,6 +2404,10 @@ snapshots: dependencies: picomatch: 2.3.1 + readline-sync@1.4.10: {} + + resolve-pkg-maps@1.0.0: {} + resolve@1.22.8: dependencies: is-core-module: 2.13.1 @@ -2249,26 +2416,26 @@ snapshots: reusify@1.0.4: {} - rollup@4.17.2: + rollup@4.18.0: dependencies: '@types/estree': 1.0.5 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.17.2 - '@rollup/rollup-android-arm64': 4.17.2 - '@rollup/rollup-darwin-arm64': 4.17.2 - '@rollup/rollup-darwin-x64': 4.17.2 - '@rollup/rollup-linux-arm-gnueabihf': 4.17.2 - '@rollup/rollup-linux-arm-musleabihf': 4.17.2 - '@rollup/rollup-linux-arm64-gnu': 4.17.2 - '@rollup/rollup-linux-arm64-musl': 4.17.2 - '@rollup/rollup-linux-powerpc64le-gnu': 4.17.2 - '@rollup/rollup-linux-riscv64-gnu': 4.17.2 - '@rollup/rollup-linux-s390x-gnu': 4.17.2 - '@rollup/rollup-linux-x64-gnu': 4.17.2 - '@rollup/rollup-linux-x64-musl': 4.17.2 - '@rollup/rollup-win32-arm64-msvc': 4.17.2 - '@rollup/rollup-win32-ia32-msvc': 4.17.2 - '@rollup/rollup-win32-x64-msvc': 4.17.2 + '@rollup/rollup-android-arm-eabi': 4.18.0 + '@rollup/rollup-android-arm64': 4.18.0 + '@rollup/rollup-darwin-arm64': 4.18.0 + '@rollup/rollup-darwin-x64': 4.18.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.18.0 + '@rollup/rollup-linux-arm-musleabihf': 4.18.0 + '@rollup/rollup-linux-arm64-gnu': 4.18.0 + '@rollup/rollup-linux-arm64-musl': 4.18.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.18.0 + '@rollup/rollup-linux-riscv64-gnu': 4.18.0 + '@rollup/rollup-linux-s390x-gnu': 4.18.0 + '@rollup/rollup-linux-x64-gnu': 4.18.0 + '@rollup/rollup-linux-x64-musl': 4.18.0 + '@rollup/rollup-win32-arm64-msvc': 4.18.0 + '@rollup/rollup-win32-ia32-msvc': 4.18.0 + '@rollup/rollup-win32-x64-msvc': 4.18.0 fsevents: 2.3.3 run-parallel@1.2.0: @@ -2281,6 +2448,8 @@ snapshots: semver@6.3.1: {} + semver@7.6.2: {} + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -2320,7 +2489,7 @@ snapshots: dependencies: '@jridgewell/gen-mapping': 0.3.5 commander: 4.1.1 - glob: 10.3.15 + glob: 10.4.1 lines-and-columns: 1.2.4 mz: 2.7.0 pirates: 4.0.6 @@ -2332,7 +2501,13 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - tailwindcss@3.4.3: + tailwind-easing-gradients@1.0.2: + dependencies: + chroma-js: 2.4.2 + easing-coordinates: 2.0.2 + ramda: 0.26.1 + + tailwindcss@3.4.3(ts-node@10.9.2(@types/node@20.12.13)(typescript@5.4.5)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -2344,16 +2519,16 @@ snapshots: is-glob: 4.0.3 jiti: 1.21.0 lilconfig: 2.1.0 - micromatch: 4.0.5 + micromatch: 4.0.7 normalize-path: 3.0.0 object-hash: 3.0.0 picocolors: 1.0.1 postcss: 8.4.38 postcss-import: 15.1.0(postcss@8.4.38) postcss-js: 4.0.1(postcss@8.4.38) - postcss-load-config: 4.0.2(postcss@8.4.38) + postcss-load-config: 4.0.2(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.12.13)(typescript@5.4.5)) postcss-nested: 6.0.1(postcss@8.4.38) - postcss-selector-parser: 6.0.16 + postcss-selector-parser: 6.1.0 resolve: 1.22.8 sucrase: 3.35.0 transitivePeerDependencies: @@ -2379,8 +2554,34 @@ snapshots: ts-interface-checker@0.1.13: {} + ts-node@10.9.2(@types/node@20.12.13)(typescript@5.4.5): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.12.13 + acorn: 8.11.3 + acorn-walk: 8.3.2 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.4.5 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + optional: true + tslib@2.6.2: {} + tsx@4.11.0: + dependencies: + esbuild: 0.20.2 + get-tsconfig: 4.7.5 + optionalDependencies: + fsevents: 2.3.3 + typescript@5.4.5: {} undici-types@5.26.5: {} @@ -2397,17 +2598,20 @@ snapshots: util-deprecate@1.0.2: {} - vite-plugin-package-version@1.1.0(vite@5.2.11(@types/node@20.12.12)): + v8-compile-cache-lib@3.0.1: + optional: true + + vite-plugin-package-version@1.1.0(vite@5.2.12(@types/node@20.12.13)): dependencies: - vite: 5.2.11(@types/node@20.12.12) + vite: 5.2.12(@types/node@20.12.13) - vite@5.2.11(@types/node@20.12.12): + vite@5.2.12(@types/node@20.12.13): dependencies: esbuild: 0.20.2 postcss: 8.4.38 - rollup: 4.17.2 + rollup: 4.18.0 optionalDependencies: - '@types/node': 20.12.12 + '@types/node': 20.12.13 fsevents: 2.3.3 which@2.0.2: @@ -2430,4 +2634,7 @@ snapshots: yaml@2.4.2: {} + yn@3.1.1: + optional: true + zod@3.23.8: {} diff --git a/public/tracer.png b/public/tracer.png new file mode 100644 index 0000000..c79276f Binary files /dev/null and b/public/tracer.png differ diff --git a/screenshots/screenshot-1.png b/screenshots/screenshot-1.png index 3027ff9..1d658c8 100644 Binary files a/screenshots/screenshot-1.png and b/screenshots/screenshot-1.png differ diff --git a/screenshots/screenshot-2.png b/screenshots/screenshot-2.png index 168e19b..4566a60 100644 Binary files a/screenshots/screenshot-2.png and b/screenshots/screenshot-2.png differ diff --git a/scripts/update.ts b/scripts/update.ts new file mode 100644 index 0000000..2a7b1a1 --- /dev/null +++ b/scripts/update.ts @@ -0,0 +1,66 @@ +import * as fs from 'fs' +import readlineSync from 'readline-sync' +import * as semver from 'semver' + +const packageJsonPath = './package.json' +const cargoTomlPath = './src-tauri/Cargo.toml' +const readmePath = './README.md' + +async function updateVersion(type: string) { + // Read package.json and Cargo.toml + const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')) + const cargoToml = fs.readFileSync(cargoTomlPath, 'utf8') + + // Get current version from package.json + let currentVersion = (packageJson as any).version + console.log(`Current version: ${currentVersion}`) + + // Determine new version + let newVersion = '' + if (['patch', 'minor', 'major'].includes(type)) { + newVersion = semver.inc(currentVersion, type)! + } else { + newVersion = type // Custom version + } + + // Ask for confirmation + if (!semver.valid(newVersion)) { + console.log( + 'Invalid version number. Please provide a valid semver version or "patch", "minor", or "major".' + ) + return + } + console.log(`New version: ${newVersion}`) + + if ( + !readlineSync.keyInYN(`Are you sure you want to update to ${newVersion}?`) + ) { + console.log('Version update cancelled.') + return + } + + // Update package.json + ;(packageJson as any).version = newVersion + fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n') + + // Update Cargo.toml + const updatedCargoToml = cargoToml.replace( + /version = ".*"/, + `version = "${newVersion}"` + ) + fs.writeFileSync(cargoTomlPath, updatedCargoToml) + + // Update README.md + const readmeContent = fs.readFileSync(readmePath, 'utf8') + const updatedReadme = readmeContent.replace( + /Version: .*?(\s|<.*|$)/, + `Version: ${newVersion}$1` + ) + fs.writeFileSync(readmePath, updatedReadme, 'utf8') + + console.log(`Version updated to ${newVersion} successfully!`) +} + +// Get version type from command line argument +const versionType = process.argv[2] +updateVersion(versionType).catch(console.error) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 13d966f..3df64d7 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ "gimli", ] @@ -58,9 +58,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.83" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "atk" @@ -94,9 +94,9 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" -version = "0.3.71" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +checksum = "17c6a35df3749d2e8bb1b7b21a976d82b15548788d2735b9d82f329268f71a11" dependencies = [ "addr2line", "cc", @@ -191,9 +191,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15" +checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5" [[package]] name = "byteorder" @@ -246,9 +246,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.97" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" +checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" [[package]] name = "cesu8" @@ -408,18 +408,18 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-channel" -version = "0.5.12" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" dependencies = [ "crossbeam-utils", ] @@ -445,9 +445,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crypto-common" @@ -483,7 +483,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.63", + "syn 2.0.66", ] [[package]] @@ -493,14 +493,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f" dependencies = [ "quote", - "syn 2.0.63", + "syn 2.0.66", ] [[package]] name = "darling" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" +checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" dependencies = [ "darling_core", "darling_macro", @@ -508,27 +508,27 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" +checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn 2.0.63", + "syn 2.0.66", ] [[package]] name = "darling_macro" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" +checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ "darling_core", "quote", - "syn 2.0.63", + "syn 2.0.66", ] [[package]] @@ -614,9 +614,9 @@ checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" [[package]] name = "either" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" [[package]] name = "embed-resource" @@ -627,7 +627,7 @@ dependencies = [ "cc", "memchr", "rustc_version", - "toml 0.8.12", + "toml 0.8.13", "vswhom", "winreg 0.52.0", ] @@ -790,7 +790,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.66", ] [[package]] @@ -964,9 +964,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "gio" @@ -1393,9 +1393,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", ] @@ -1502,9 +1502,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.154" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libredox" @@ -1524,9 +1524,9 @@ checksum = "dd1bc4d24ad230d21fb898d1116b1801d7adfc449d42026475862ab48b11e70e" [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lock_api" @@ -1632,9 +1632,9 @@ checksum = "933dca44d65cdd53b355d0b73d380a2ff5da71f87f036053188bf1eab6a19881" [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" dependencies = [ "adler", "simd-adler32", @@ -1653,11 +1653,10 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" dependencies = [ - "lazy_static", "libc", "log", "openssl", @@ -1815,9 +1814,9 @@ dependencies = [ [[package]] name = "object" -version = "0.32.2" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e" dependencies = [ "memchr", ] @@ -1861,7 +1860,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.66", ] [[package]] @@ -1884,7 +1883,7 @@ dependencies = [ [[package]] name = "overbuddy" -version = "1.1.2" +version = "1.2.0" dependencies = [ "dunce", "serde", @@ -1928,9 +1927,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -2065,7 +2064,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.66", ] [[package]] @@ -2200,9 +2199,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.82" +version = "1.0.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6" dependencies = [ "unicode-ident", ] @@ -2510,9 +2509,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092474d1a01ea8278f69e6a358998405fae5b8b963ddaeb2b0b04a128bf1dfb0" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "ryu" @@ -2604,22 +2603,22 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.201" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.201" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.66", ] [[package]] @@ -2642,14 +2641,14 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.66", ] [[package]] name = "serde_spanned" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" dependencies = [ "serde", ] @@ -2693,7 +2692,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.66", ] [[package]] @@ -2856,9 +2855,9 @@ dependencies = [ [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" @@ -2873,9 +2872,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.63" +version = "2.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf5be731623ca1a1fb7d8be6f261a3be6d3e2337b8a1f97be944d020c8fcb704" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" dependencies = [ "proc-macro2", "quote", @@ -2946,7 +2945,7 @@ dependencies = [ "cfg-expr 0.15.8", "heck 0.5.0", "pkg-config", - "toml 0.8.12", + "toml 0.8.13", "version-compare 0.2.0", ] @@ -3027,9 +3026,9 @@ checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" [[package]] name = "tauri" -version = "1.6.5" +version = "1.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13ce04f77bcd40bb57ec7061725c9c415d30b2bf80257637b857ee067f2fa198" +checksum = "67c7177b6be45bbb875aa239578f5adc982a1b3d5ea5b315ccd100aeb0043374" dependencies = [ "anyhow", "base64 0.21.7", @@ -3041,6 +3040,7 @@ dependencies = [ "encoding_rs", "flate2", "futures-util", + "getrandom 0.2.15", "glib", "glob", "gtk", @@ -3163,9 +3163,9 @@ dependencies = [ [[package]] name = "tauri-runtime-wry" -version = "0.14.7" +version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2af45aeb15b1cadb4ca91248423f4438a0864b836298cecb436892afbfdff4" +checksum = "1989b3b4d611f5428b3414a4abae6fa6df30c7eb8ed33250ca90a5f7e5bb3655" dependencies = [ "cocoa", "gtk", @@ -3252,22 +3252,22 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" [[package]] name = "thiserror" -version = "1.0.60" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.60" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.66", ] [[package]] @@ -3388,21 +3388,21 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.12" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" +checksum = "a4e43f8cc456c9704c851ae29c67e17ef65d2c30017c17a9765b89c382dc8bba" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.12", + "toml_edit 0.22.13", ] [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" dependencies = [ "serde", ] @@ -3422,15 +3422,15 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.12" +version = "0.22.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef" +checksum = "c127785850e8c20836d49732ae6abfa47616e60bf9d9f57c43c250361a9db96c" dependencies = [ "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.8", + "winnow 0.6.9", ] [[package]] @@ -3458,7 +3458,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.66", ] [[package]] @@ -3668,7 +3668,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.66", "wasm-bindgen-shared", ] @@ -3702,7 +3702,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.66", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4215,9 +4215,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.8" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c52e9c97a68071b23e836c9380edae937f17b9c4667bd021973efc689f618d" +checksum = "86c949fede1d13936a99f14fafd3e76fd642b556dd2ce96287fbe2e0151bfac6" dependencies = [ "memchr", ] @@ -4244,9 +4244,9 @@ dependencies = [ [[package]] name = "wry" -version = "0.24.9" +version = "0.24.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c689900e022bb67b0d9728fb817bbef2b9da7ebd6c79aade5f0c32fe4c18c73" +checksum = "00711278ed357350d44c749c286786ecac644e044e4da410d466212152383b45" dependencies = [ "base64 0.13.1", "block", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index e79d4eb..f4b6a6a 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "overbuddy" -version = "1.1.2" +version = "1.2.0" description = "Elevate your Overwatch™ 2 experience by customizing your in-game menu background with ease." authors = ["Kirill Tregubov"] -license = "" -repository = "" +license = "../LICENSE" +repository = "https://github.com/KirillTregubov/OverBuddy" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -18,7 +18,7 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0" dunce = "1.0.4" -sysinfo = "0.30.5" +sysinfo = "0.30.12" [features] # this feature is used for production builds or when `devPath` points to the filesystem diff --git a/src-tauri/icons/icon.icns b/src-tauri/icons/icon.icns index 78b45ce..0c11975 100644 Binary files a/src-tauri/icons/icon.icns and b/src-tauri/icons/icon.icns differ diff --git a/src-tauri/src/helpers.rs b/src-tauri/src/helpers.rs index b50ec7d..68218b6 100644 --- a/src-tauri/src/helpers.rs +++ b/src-tauri/src/helpers.rs @@ -1,6 +1,10 @@ use crate::config::{get_default_config, Config, CONFIG_FILE}; -use std::fs; +use serde::Serialize; +use serde_json::{from_reader, Serializer, Value}; +use std::fs::{self, File}; +use std::io; +use std::path::{Path, PathBuf}; use sysinfo::System; use tauri::AppHandle; @@ -26,7 +30,7 @@ impl serde::Serialize for Error { } } -pub fn display_path_string(path: &std::path::PathBuf) -> Result { +pub fn display_path_string(path: &PathBuf) -> Result { dunce::canonicalize(&path) .map(|canonicalized| canonicalized.display().to_string()) .map_err(|err| Error::Custom(format!("Error processing path: {:?}", err))) @@ -49,7 +53,6 @@ pub fn close_battle_net() -> bool { // for _ in system.processes_by_name("Battle.net.exe") { // return Ok(true); // } - // Ok(false) // } @@ -62,8 +65,8 @@ pub fn read_config(handle: &AppHandle) -> Result { Ok(_) => {} Err(_) => { return Err(Error::Custom(format!( - "Failed to create directory: {:?}", - app_local_data_dir + "Failed to read local data in [[{}]]", + app_local_data_dir.to_str().unwrap() ))); } } @@ -76,8 +79,8 @@ pub fn read_config(handle: &AppHandle) -> Result { Ok(_) => {} Err(_) => { return Err(Error::Custom(format!( - "Failed to create file: {:?}", - config_file_path + "Failed to create configuration file [[{}]]", + config_file_path.to_str().unwrap() ))); } } @@ -111,8 +114,8 @@ pub fn write_config(handle: &AppHandle, config: &Config) -> Result<(), Error> { Ok(_) => {} Err(_) => { return Err(Error::Custom(format!( - "Failed to create directory: {:?}", - app_local_data_dir + "Failed to write local data in [[{}]]", + app_local_data_dir.to_str().unwrap() ))); } } @@ -125,8 +128,8 @@ pub fn write_config(handle: &AppHandle, config: &Config) -> Result<(), Error> { Ok(_) => {} Err(_) => { return Err(Error::Custom(format!( - "Failed to create file: {:?}", - config_file_path + "Failed to create configuration file in [[{}]]", + config_file_path.to_str().unwrap() ))); } } @@ -143,11 +146,100 @@ pub fn write_config(handle: &AppHandle, config: &Config) -> Result<(), Error> { Ok(_) => {} Err(_) => { return Err(Error::Custom(format!( - "Failed to write to file: {:?}", - config_file_path + "Failed to write configuration file in [[{}]]", + config_file_path.to_str().unwrap() ))); } } return Ok(()); } + +pub fn get_file_name_from_path(path: &str) -> Option<&str> { + Path::new(path).file_name().and_then(|name| name.to_str()) +} + +pub fn safe_json_write(path: String, json: &serde_json::Value) -> Result<(), Error> { + // Create backup + let backup_path = format!("{}.backup", path); + if Path::new(&path).exists() { + fs::copy(&path, &backup_path).map_err(|_| { + Error::Custom(format!( + "Failed to create backup of [[{}]]", + get_file_name_from_path(&path).unwrap_or("unknown") + )) + })?; + } + + let cleanup = |replace: bool| -> Result<(), Error> { + if Path::new(&backup_path).exists() { + if replace { + fs::copy(&backup_path, &path).map_err(|_| { + Error::Custom(format!( + "Failed to restore backup of [[{}]]", + get_file_name_from_path(&path).unwrap_or("unknown") + )) + })?; + } + let _ = fs::remove_file(&backup_path); + } + Ok(()) + }; + + // Write to file + let mut file = match fs::OpenOptions::new() + .write(true) + .truncate(true) + .open(&path) + { + Ok(file) => file, + Err(_) => { + cleanup(false)?; + return Err(Error::Custom(format!( + "Failed to open [[{}]] file at [[{}]]", + get_file_name_from_path(&path).unwrap_or("unknown"), + path + ))); + } + }; + let pretty_formatter = serde_json::ser::PrettyFormatter::with_indent(b" "); + let mut serializer = Serializer::with_formatter(&mut file, pretty_formatter); + match json.serialize(&mut serializer) { + Ok(_) => (), + Err(_) => { + cleanup(false)?; + return Err(Error::Custom(format!("Failed to write to [[{}]]", path))); + } + } + + // Validate new config + let file = match File::open(&path) { + Ok(file) => file, + Err(_) => { + // Restore backup + cleanup(true)?; + return Err(Error::Custom(format!( + "Failed to open [[{}]] file at [[{}]]", + get_file_name_from_path(&path).unwrap_or("unknown"), + path + ))); + } + }; + + let parsed_json: Result = from_reader(file); + match parsed_json { + Ok(_) => { + // JSON is good, remove the backup + cleanup(false)?; + Ok(()) + } + Err(_) => { + // JSON is corrupted, restore the backup + cleanup(true)?; + Err(Error::Io(std::io::Error::new( + io::ErrorKind::InvalidData, + format!("Failed to write to [[{}]]", path), + ))) + } + } +} diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index ed495c4..b6002e4 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -7,10 +7,9 @@ mod helpers; use helpers::Error; use serde::Serialize; -use serde_json::json; -use serde_json::Serializer; +use serde_json::{from_reader, json}; use std::env; -use std::fs; +use std::fs::{self, File}; use std::io::Read; use std::path::Path; use std::process::Command; @@ -36,33 +35,34 @@ fn get_launch_config(handle: AppHandle) -> Result { if config.is_setup { if config.battle_net.enabled { let battle_net_config = config.battle_net.config.clone().unwrap(); - let mut file = match fs::OpenOptions::new() - .read(true) - .open(battle_net_config.clone()) - { + + let backup_path = format!("{}.backup", battle_net_config); + if Path::new(&backup_path).exists() { + fs::copy(&backup_path, &battle_net_config).map_err(|_| { + Error::Custom(format!( + "Failed to restore backup of [[{}]]", + helpers::get_file_name_from_path(&battle_net_config).unwrap_or("unknown") + )) + })?; + let _ = fs::remove_file(&backup_path); + } + + let file = match File::open(&battle_net_config) { Ok(file) => file, Err(_) => { return Err(Error::Custom(format!( - "Failed to open Battle.net.config file at {}", + "Failed to open [[{}]] file at [[{}]]", + helpers::get_file_name_from_path(&battle_net_config).unwrap_or("unknown"), battle_net_config ))); } }; - let mut contents = String::new(); - match file.read_to_string(&mut contents) { - Ok(_) => {} - Err(_) => { - return Err(Error::Custom(format!( - "Failed to read Battle.net.config file at {}", - battle_net_config - ))); - } - } - let mut json: serde_json::Value = match serde_json::from_str(&contents) { + let mut json: serde_json::Value = match from_reader(file) { Ok(json) => json, Err(_) => { return Err(Error::Custom(format!( - "Failed to parse Battle.net.config file at {}", + "Failed to read [[{}]] file at [[{}]]", + helpers::get_file_name_from_path(&battle_net_config).unwrap_or("unknown"), battle_net_config ))); } @@ -85,6 +85,7 @@ fn get_launch_config(handle: AppHandle) -> Result { .find(|s| s.starts_with("--lobbyMap=")) .and_then(|s| s.split('=').nth(1)) .map(String::from); + let mut new_background = current_background.clone(); if let Some(ref current_background) = current_background { if current_background.is_empty() { @@ -94,28 +95,26 @@ fn get_launch_config(handle: AppHandle) -> Result { .collect::>() .join(" "); - if let Some(game_config) = json - .get_mut("Games") - .and_then(|games| games.get_mut("prometheus")) - { - game_config.as_object_mut().unwrap().insert( - "AdditionalLaunchArguments".to_string(), - json!(new_launch_args), - ); - - let mut file = fs::OpenOptions::new() - .write(true) - .truncate(true) - .open(battle_net_config)?; - let pretty_formatter = - serde_json::ser::PrettyFormatter::with_indent(b" "); - let mut serializer = - Serializer::with_formatter(&mut file, pretty_formatter); - json.serialize(&mut serializer)?; + // TODO: Provide the option to restore saved background + + if launch_args != new_launch_args { + if let Some(game_config) = json + .get_mut("Games") + .and_then(|games| games.get_mut("prometheus")) + { + game_config.as_object_mut().unwrap().insert( + "AdditionalLaunchArguments".to_string(), + json!(new_launch_args), + ); + + helpers::safe_json_write(battle_net_config, &json)?; + } } + new_background = None; } } - config.background.current = current_background; + + config.background.current = new_background; } } } @@ -193,7 +192,7 @@ fn setup(handle: AppHandle, platforms: Vec<&str>) -> Result { return Err(Error::Custom(serde_json::to_string(&SetupError { error_key: ErrorKey::BattleNetConfig, message: format!( - "Failed to find \"{}\" in {}.", + "Failed to find [[{}]] in [[{}]].", CONFIG_FILE, display_path ), error_action: Some("finding".to_string()), @@ -203,7 +202,7 @@ fn setup(handle: AppHandle, platforms: Vec<&str>) -> Result { } else { return Err(Error::Custom(serde_json::to_string(&SetupError { error_key: ErrorKey::BattleNetConfig, - message: "Failed to find Battle.net AppData directory.".to_string(), + message: "Failed to find the Battle.net AppData directory.".to_string(), error_action: Some("finding".to_string()), platforms: Some(platforms.iter().map(|s| s.to_string()).collect()), })?)); @@ -220,7 +219,7 @@ fn setup(handle: AppHandle, platforms: Vec<&str>) -> Result { return Err(Error::Custom(serde_json::to_string(&SetupError { error_key: ErrorKey::BattleNetConfig, message: format!( - "Failed to open \"{}\" file at {}", + "Failed to open [[{}]] file in [[{}]]", CONFIG_FILE, battle_net_config ), error_action: Some("opening".to_string()), @@ -235,7 +234,7 @@ fn setup(handle: AppHandle, platforms: Vec<&str>) -> Result { return Err(Error::Custom(serde_json::to_string(&SetupError { error_key: ErrorKey::BattleNetConfig, message: format!( - "Failed to read \"{}\" file at {}", + "Failed to read [[{}]] file in [[{}]]", CONFIG_FILE, battle_net_config ), error_action: Some("reading".to_string()), @@ -270,13 +269,25 @@ fn setup(handle: AppHandle, platforms: Vec<&str>) -> Result { .unwrap() .insert("AdditionalLaunchArguments".to_string(), json!("")); - let mut file = fs::OpenOptions::new() - .write(true) - .truncate(true) - .open(battle_net_config)?; - let pretty_formatter = serde_json::ser::PrettyFormatter::with_indent(b" "); - let mut serializer = Serializer::with_formatter(&mut file, pretty_formatter); - json.serialize(&mut serializer)?; + helpers::safe_json_write(battle_net_config, &json)?; + } else { + let launch_args = json["Games"]["prometheus"]["AdditionalLaunchArguments"] + .as_str() + .map(|s| s.to_string()); + match launch_args { + Some(arguments) => { + let current_background = arguments + .split_whitespace() + .find(|s| s.starts_with("--lobbyMap=")) + .and_then(|s| s.split('=').nth(1)) + .map(String::from); + + if let Some(ref current_background) = current_background { + config.background.current = Some(current_background.clone()); + } + } + None => (), + }; } } @@ -360,7 +371,7 @@ fn get_setup_path(key: &str, handle: AppHandle) -> Result { return Ok(path.to_string_lossy().to_string()); } return Err(Error::Custom(format!( - "Failed to find the \"Program Files (x86)\" directory." + "Failed to find the [[Program Files (x86)]] directory." ))); } "BattleNetConfig" => { @@ -374,7 +385,7 @@ fn get_setup_path(key: &str, handle: AppHandle) -> Result { return Ok(path.to_string_lossy().to_string()); } return Err(Error::Custom(format!( - "Failed to find the \"Program Files (x86)\" directory." + "Failed to find the [[Program Files (x86)]] directory." ))); } _ => { @@ -409,6 +420,7 @@ fn set_background(handle: AppHandle, id: &str) -> Result { let cleanup = || { if battle_net_was_closed { + // TODO: test error Command::new(battle_net_install).spawn().ok(); } }; @@ -470,34 +482,7 @@ fn set_background(handle: AppHandle, id: &str) -> Result { }; json["Games"]["prometheus"]["AdditionalLaunchArguments"] = json!(launch_args); - - let mut file = match fs::OpenOptions::new() - .write(true) - .truncate(true) - .open(battle_net_config.clone()) - { - Ok(file) => file, - Err(_) => { - cleanup(); - return Err(Error::Custom(format!( - "Failed to open Battle.net.config file at {}", - battle_net_config - ))); - } - }; - - let pretty_formatter = serde_json::ser::PrettyFormatter::with_indent(b" "); - let mut serializer = Serializer::with_formatter(&mut file, pretty_formatter); - match json.serialize(&mut serializer) { - Ok(_) => {} - Err(_) => { - cleanup(); - return Err(Error::Custom(format!( - "Failed to write to Battle.net.config file at {}", - battle_net_config - ))); - } - }; + helpers::safe_json_write(battle_net_config, &json)?; config.background.current = Some(id.to_string()); helpers::write_config(&handle, &config)?; @@ -588,34 +573,7 @@ fn reset_background(handle: AppHandle) -> Result { }; json["Games"]["prometheus"]["AdditionalLaunchArguments"] = json!(launch_args); - - let mut file = match fs::OpenOptions::new() - .write(true) - .truncate(true) - .open(battle_net_config.clone()) - { - Ok(file) => file, - Err(_) => { - cleanup(); - return Err(Error::Custom(format!( - "Failed to open Battle.net.config file at {}", - battle_net_config - ))); - } - }; - - let pretty_formatter = serde_json::ser::PrettyFormatter::with_indent(b" "); - let mut serializer = Serializer::with_formatter(&mut file, pretty_formatter); - match json.serialize(&mut serializer) { - Ok(_) => {} - Err(_) => { - cleanup(); - return Err(Error::Custom(format!( - "Failed to write to Battle.net.config file at {}", - battle_net_config - ))); - } - }; + helpers::safe_json_write(battle_net_config, &json)?; config.background.current = None; helpers::write_config(&handle, &config)?; @@ -624,6 +582,13 @@ fn reset_background(handle: AppHandle) -> Result { return Ok(serde_json::to_string(&config)?); } +#[tauri::command] +fn reset(handle: AppHandle) -> Result { + let config = config::get_default_config(); + helpers::write_config(&handle, &config)?; + return Ok(serde_json::to_string(&config)?); +} + fn main() { tauri::Builder::default() // .setup(|app| { @@ -649,7 +614,8 @@ fn main() { resolve_setup_error, get_backgrounds, set_background, - reset_background + reset_background, + reset ]) .run(tauri::generate_context!()) .expect("Encountered an error while starting OverBuddy"); diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index bdcdf3d..480e00b 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -27,10 +27,9 @@ "icons/32x32.png", "icons/128x128.png", "icons/128x128@2x.png", - "icons/icon.icns", "icons/icon.ico" ], - "shortDescription": "Elevate your Overwatch™ 2 experience by customizing your in-game menu background.", + "shortDescription": "OverBuddy", "longDescription": "Elevate your Overwatch™ 2 experience by customizing your in-game menu background with ease. Browse through all available backgrounds and select your favourite. No need to guess the lobby code or mess around with configuration anymore!", "windows": { "certificateThumbprint": null, diff --git a/src/components/ErrorComponent.tsx b/src/components/ErrorComponent.tsx new file mode 100644 index 0000000..a42205b --- /dev/null +++ b/src/components/ErrorComponent.tsx @@ -0,0 +1,122 @@ +import { useRouter, type ErrorComponentProps } from '@tanstack/react-router' +import { invoke } from '@tauri-apps/api' +import clsx from 'clsx' +import { motion } from 'framer-motion' +import { useEffect, useState } from 'react' + +import { + fadeInVariants, + moveInVariants, + staggerChildrenVariants +} from '@/lib/animations' +import { useResetMutation } from '@/lib/data' +import Highlight from './Highlight' + +const FormattedError = ({ text }: { text: string }) => { + const regex = /\[\[(.*?)\]\]/g + const parts = [] + let lastIdx = 0 + + text.replace(regex, (match, captured, offset) => { + parts.push(text.slice(lastIdx, offset)) + parts.push({captured}) + lastIdx = offset + match.length + return '' + }) + + if (lastIdx < text.length) { + parts.push(text.slice(lastIdx)) + } + + return ( + + {parts} + + ) +} + +export default function ErrorComponent({ error, reset }: ErrorComponentProps) { + const router = useRouter() + const { + status, + mutate, + reset: resetMutation + } = useResetMutation({ + onSuccess: () => { + reset() + router.navigate({ + to: '/', + replace: true + }) + }, + onSettled: () => { + resetMutation() + } + }) + const [imageLoaded, setImageLoaded] = useState(false) + + useEffect(() => { + invoke('mounted') + }, []) + + if (typeof error === 'string') { + error = Error(error) + } + + return ( + + + {/* */} + + Oops! Something went wrong. + + + + + + {/* TODO: report error */} + + + logo setImageLoaded(true)} + draggable={false} + /> + + ) +} diff --git a/src/components/Highlight.tsx b/src/components/Highlight.tsx new file mode 100644 index 0000000..af3bbe3 --- /dev/null +++ b/src/components/Highlight.tsx @@ -0,0 +1,7 @@ +export default function Highlight({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ) +} diff --git a/src/components/Loading.tsx b/src/components/Loading.tsx index e46f331..e7a8b72 100644 --- a/src/components/Loading.tsx +++ b/src/components/Loading.tsx @@ -1,9 +1,16 @@ +import { fadeInVariants } from '@/lib/animations' +import { motion } from 'framer-motion' import { LoaderPinwheel } from 'lucide-react' export default function Loading() { return ( -
- -
+ + + ) } diff --git a/src/components/Toaster.tsx b/src/components/Toaster.tsx new file mode 100644 index 0000000..52ce523 --- /dev/null +++ b/src/components/Toaster.tsx @@ -0,0 +1,15 @@ +import { Toaster as SonnerToaster } from 'sonner' + +export default function Toaster() { + return ( + + ) +} diff --git a/src/routes/setup/-constants.ts b/src/lib/animations.ts similarity index 50% rename from src/routes/setup/-constants.ts rename to src/lib/animations.ts index 6c25593..b8baa77 100644 --- a/src/routes/setup/-constants.ts +++ b/src/lib/animations.ts @@ -1,4 +1,14 @@ -export const containerVariants = { +export const fadeInVariants = { + hidden: { opacity: 0 }, + show: { + opacity: 1, + transition: { + duration: 1 + } + } +} + +export const staggerChildrenVariants = { show: { transition: { staggerChildren: 0.02 @@ -6,7 +16,7 @@ export const containerVariants = { } } -export const childVariants = { +export const moveInVariants = { hidden: { transform: 'translateY(20px)' }, show: { transform: 'translateY(0)', diff --git a/src/lib/data.ts b/src/lib/data.ts index 44799ca..f268e0f 100644 --- a/src/lib/data.ts +++ b/src/lib/data.ts @@ -3,75 +3,32 @@ import { invoke } from '@tauri-apps/api' import { toast } from 'sonner' import { z } from 'zod' -import { queryClient } from '../main' - -const handleError = (error: unknown) => { - if (error instanceof Error) error = error.message - if (typeof error !== 'string') error = 'An unknown error occurred.' - toast.error(error as string) -} - -const LaunchConfig = z.object({ - is_setup: z.boolean(), - battle_net: z.object({ - enabled: z.boolean(), - config: z.string().nullable(), - install: z.string().nullable() - }), - steam: z.object({ - enabled: z.boolean(), - config: z.string().nullable(), - install: z.string().nullable() - }), - background: z.object({ - current: z.string().nullable() - }) -}) -type LaunchConfig = z.infer +import { + ConfigError, + ConfigErrorSchema, + ConfigErrors, + SetupError, + handleError +} from '@/lib/errors' +import { LaunchConfig, type Platform } from '@/lib/schemas' +import { queryClient } from '@/main' export const launchQueryOptions = queryOptions({ queryKey: ['launch'], queryFn: async () => { - const data = await invoke('get_launch_config') + const data = await invoke('get_launch_config').catch((error) => { + if (typeof error !== 'string') throw error + throw new Error(error) + }) const config = LaunchConfig.safeParse(JSON.parse(data as string)) if (!config.success) { throw new Error(config.error.message) } return config.data - } + }, + staleTime: Infinity }) -const Platform = z.enum(['BattleNet', 'Steam']) -export type Platform = z.infer - -export const ConfigErrors = z.enum([ - 'BattleNetConfig', - 'BattleNetInstall', - 'SteamInstall' -]) -export type ConfigErrors = z.infer - -const ConfigErrorSchema = z.object({ - error_key: ConfigErrors.or(z.enum(['NoOverwatch'])), - message: z.string(), - error_action: z.string().nullable(), - platforms: z.array(Platform) -}) -export type ConfigErrorSchema = z.infer - -export class ConfigError extends Error { - error_key: ConfigErrorSchema['error_key'] - error_action: ConfigErrorSchema['error_action'] - platforms: ConfigErrorSchema['platforms'] - - constructor(public error: ConfigErrorSchema) { - super(error.message) - this.error_key = error.error_key - this.error_action = error.error_action - this.platforms = error.platforms - } -} - export const useSetupMutation = ({ onError, onSuccess @@ -102,8 +59,10 @@ export const useSetupMutation = ({ throw new Error(config.error.message) } if (!config.data.is_setup) { - throw new Error('Setup failed') + throw new SetupError() } + + queryClient.setQueryData(['launch'], config.data) return config.data }, onError, @@ -164,6 +123,8 @@ export const useSetupErrorMutation = ({ if (!config.success) { throw new Error(`Failed to setup. ${config.error.message}`) } + + queryClient.setQueryData(['launch'], config.data) return config.data }, onError, @@ -244,3 +205,27 @@ export const useResetBackgroundMutation = ({ }, onSettled }) + +export const useResetMutation = ({ + onSuccess, + onSettled +}: { + onSuccess?: () => void + onSettled?: () => void +} = {}) => + useMutation({ + mutationFn: async () => { + const data = (await invoke('reset')) as string + const config = LaunchConfig.safeParse(JSON.parse(data)) + if (!config.success) { + throw new Error(`Failed to reset.`) + } + queryClient.setQueryData(['launch'], config.data) + }, + onError: (error) => handleError(error), + onSuccess: () => { + toast.success('Reset to default settings.') + onSuccess?.() + }, + onSettled + }) diff --git a/src/lib/errors.ts b/src/lib/errors.ts new file mode 100644 index 0000000..c12e5fb --- /dev/null +++ b/src/lib/errors.ts @@ -0,0 +1,49 @@ +import { toast } from 'sonner' +import { z } from 'zod' + +import { Platform } from '@/lib/schemas' + +/* ConfigErrors */ +export const ConfigErrors = z.enum([ + 'BattleNetConfig', + 'BattleNetInstall', + 'SteamInstall' +]) +export type ConfigErrors = z.infer + +/* ConfigError Response Schema */ +export const ConfigErrorSchema = z.object({ + error_key: ConfigErrors.or(z.enum(['NoOverwatch'])), + message: z.string(), + error_action: z.string().nullable(), + platforms: z.array(Platform) +}) +export type ConfigErrorSchema = z.infer + +/* ConfigError Class */ +export class ConfigError extends Error { + error_key: ConfigErrorSchema['error_key'] + error_action: ConfigErrorSchema['error_action'] + platforms: ConfigErrorSchema['platforms'] + + constructor(public error: ConfigErrorSchema) { + super(error.message) + this.error_key = error.error_key + this.error_action = error.error_action + this.platforms = error.platforms + } +} + +/* SetupError Class */ +export class SetupError extends Error { + constructor() { + super('Failed to setup!') + } +} + +/* Handle non-critical errors */ +export function handleError(error: unknown) { + if (error instanceof Error) error = error.message + else if (typeof error !== 'string') error = 'An unknown error occurred.' + toast.error((error as string).replaceAll(/\[\[|\]\]/g, '"')) +} diff --git a/src/lib/schemas.ts b/src/lib/schemas.ts new file mode 100644 index 0000000..d88c26a --- /dev/null +++ b/src/lib/schemas.ts @@ -0,0 +1,22 @@ +import { z } from 'zod' + +export const Platform = z.enum(['BattleNet', 'Steam']) +export type Platform = z.infer + +export const LaunchConfig = z.object({ + is_setup: z.boolean(), + battle_net: z.object({ + enabled: z.boolean(), + config: z.string().nullable(), + install: z.string().nullable() + }), + steam: z.object({ + enabled: z.boolean(), + config: z.string().nullable(), + install: z.string().nullable() + }), + background: z.object({ + current: z.string().nullable() + }) +}) +export type LaunchConfig = z.infer diff --git a/src/main.tsx b/src/main.tsx index 0a65b7d..5f8d569 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -3,8 +3,10 @@ import { RouterProvider, createRouter } from '@tanstack/react-router' import React from 'react' import ReactDOM from 'react-dom/client' -import { routeTree } from './routeTree.gen' -import './styles.css' +import ErrorComponent from '@/components/ErrorComponent' +import Toaster from '@/components/Toaster' +import { routeTree } from '@/routeTree.gen' +import '@/styles.css' export const queryClient = new QueryClient({ defaultOptions: { @@ -23,7 +25,9 @@ const router = createRouter({ defaultPreload: 'intent', // Since we're using React Query, we don't want loader calls to ever be stale // This will ensure that the loader is always called when the route is preloaded or visited - defaultPreloadStaleTime: 0 + defaultPreloadStaleTime: 0, + notFoundMode: 'root', + defaultErrorComponent: ErrorComponent }) declare module '@tanstack/react-router' { @@ -37,5 +41,6 @@ ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( + ) diff --git a/src/reset.d.ts b/src/reset.d.ts new file mode 100644 index 0000000..f015b25 --- /dev/null +++ b/src/reset.d.ts @@ -0,0 +1,2 @@ +import '@total-typescript/ts-reset' +import '@total-typescript/ts-reset/dom' diff --git a/src/routeTree.gen.ts b/src/routeTree.gen.ts index f2fa279..276474f 100644 --- a/src/routeTree.gen.ts +++ b/src/routeTree.gen.ts @@ -13,6 +13,7 @@ import { Route as rootRoute } from './routes/__root' import { Route as SetupImport } from './routes/setup' import { Route as MenuImport } from './routes/menu' +import { Route as IndexImport } from './routes/index' import { Route as SetupIndexImport } from './routes/setup/index' import { Route as SetupSelectImport } from './routes/setup/select' import { Route as SetupKeyImport } from './routes/setup/$key' @@ -29,6 +30,11 @@ const MenuRoute = MenuImport.update({ getParentRoute: () => rootRoute, } as any) +const IndexRoute = IndexImport.update({ + path: '/', + getParentRoute: () => rootRoute, +} as any) + const SetupIndexRoute = SetupIndexImport.update({ path: '/', getParentRoute: () => SetupRoute, @@ -48,6 +54,13 @@ const SetupKeyRoute = SetupKeyImport.update({ declare module '@tanstack/react-router' { interface FileRoutesByPath { + '/': { + id: '/' + path: '/' + fullPath: '/' + preLoaderRoute: typeof IndexImport + parentRoute: typeof rootRoute + } '/menu': { id: '/menu' path: '/menu' @@ -89,6 +102,7 @@ declare module '@tanstack/react-router' { // Create and export the route tree export const routeTree = rootRoute.addChildren({ + IndexRoute, MenuRoute, SetupRoute: SetupRoute.addChildren({ SetupKeyRoute, @@ -98,3 +112,44 @@ export const routeTree = rootRoute.addChildren({ }) /* prettier-ignore-end */ + +/* ROUTE_MANIFEST_START +{ + "routes": { + "__root__": { + "filePath": "__root.tsx", + "children": [ + "/", + "/menu", + "/setup" + ] + }, + "/": { + "filePath": "index.tsx" + }, + "/menu": { + "filePath": "menu.tsx" + }, + "/setup": { + "filePath": "setup.tsx", + "children": [ + "/setup/$key", + "/setup/select", + "/setup/" + ] + }, + "/setup/$key": { + "filePath": "setup/$key.tsx", + "parent": "/setup" + }, + "/setup/select": { + "filePath": "setup/select.tsx", + "parent": "/setup" + }, + "/setup/": { + "filePath": "setup/index.tsx", + "parent": "/setup" + } + } +} +ROUTE_MANIFEST_END */ diff --git a/src/routes/__root.tsx b/src/routes/__root.tsx index e8f0ff0..2fd20da 100644 --- a/src/routes/__root.tsx +++ b/src/routes/__root.tsx @@ -1,54 +1,15 @@ import { QueryClient } from '@tanstack/react-query' -import { - ErrorComponent, - ErrorComponentProps, - Outlet, - createRootRouteWithContext, - redirect -} from '@tanstack/react-router' +import { Outlet, createRootRouteWithContext } from '@tanstack/react-router' import { invoke } from '@tauri-apps/api' import { useEffect } from 'react' -import { Toaster } from 'sonner' - -import { launchQueryOptions } from '@/lib/data' export const Route = createRootRouteWithContext<{ queryClient: QueryClient }>()({ - beforeLoad: async ({ context: { queryClient }, location }) => { - if (location.pathname !== '/') { - return - } - const { is_setup } = await queryClient - .fetchQuery(launchQueryOptions) - .catch((error) => { - if (typeof error === 'string') { - error = Error(error) - } - throw error - }) - if (!is_setup) { - throw redirect({ to: '/setup' }) - } else { - throw redirect({ to: '/menu' }) - } - }, - errorComponent: RootErrorComponent, + // notFoundComponent: () => , component: RootComponent }) -function RootErrorComponent({ error }: ErrorComponentProps) { - useEffect(() => { - invoke('mounted') - }, []) - - if (typeof error === 'string') { - error = Error(error) - } - - return -} - function RootComponent() { useEffect(() => { invoke('mounted') @@ -57,15 +18,6 @@ function RootComponent() { return (
-
) } diff --git a/src/routes/index.tsx b/src/routes/index.tsx new file mode 100644 index 0000000..14038f2 --- /dev/null +++ b/src/routes/index.tsx @@ -0,0 +1,12 @@ +import { launchQueryOptions } from '@/lib/data' +import { createFileRoute, redirect } from '@tanstack/react-router' + +export const Route = createFileRoute('/')({ + loader: async ({ context: { queryClient } }) => { + const { is_setup } = await queryClient.fetchQuery(launchQueryOptions) + if (is_setup) { + throw redirect({ to: '/menu' }) + } + throw redirect({ to: '/setup' }) + } +}) diff --git a/src/routes/menu.tsx b/src/routes/menu.tsx index f7c8364..c7e668d 100644 --- a/src/routes/menu.tsx +++ b/src/routes/menu.tsx @@ -11,7 +11,6 @@ import { // SettingsIcon } from 'lucide-react' import { useEffect, useRef, useState } from 'react' -import { toast } from 'sonner' import placeholder from '@/assets/placeholder.svg' import Loading from '@/components/Loading' @@ -21,24 +20,18 @@ import { useBackgroundMutation, useResetBackgroundMutation } from '@/lib/data' +import { handleError } from '@/lib/errors' export const Route = createFileRoute('/menu')({ - loader: async ({ context }) => { - if (context === undefined) { - return - } - const { queryClient } = context - await queryClient.ensureQueryData(backgroundsQueryOptions) - }, + loader: async ({ context: { queryClient } }) => + await queryClient.ensureQueryData(backgroundsQueryOptions), beforeLoad: async ({ context: { queryClient } }) => { const { is_setup } = await queryClient .fetchQuery(launchQueryOptions) - .catch((error) => { - if (typeof error === 'string') { - error = Error(error) - } - throw error + .catch(() => { + throw redirect({ to: '/' }) }) + if (!is_setup) { throw redirect({ to: '/setup' }) } @@ -87,7 +80,7 @@ function Menu() { const index = data.findIndex((bg) => bg.id === config.background.current) if (index === -1) { // FIXME: Handle removed background - toast.error('Background has been removed.') + handleError('Background has been removed.') } handleSelect(index) @@ -140,13 +133,13 @@ function Menu() {
*/}
-
+
{data.map((background, index) => (
-
- {activeBackground.tags.map((tag) => ( - - {tag} - - ))} -
+ {activeBackground !== undefined && ( +
+ {activeBackground.tags.map((tag) => ( + + {tag} + + ))} +
+ )} Selected Wallpaper -
- -

{activeBackground.name}

-

{activeBackground.description}

-
+
+ {activeBackground !== undefined && ( + +

{activeBackground.name}

+

{activeBackground.description}

+
+ )} {config.background.current !== null && ( */} - + {activeBackground !== undefined && ( + + )}
diff --git a/src/routes/setup.tsx b/src/routes/setup.tsx index 3c36878..284bfd9 100644 --- a/src/routes/setup.tsx +++ b/src/routes/setup.tsx @@ -1,7 +1,20 @@ -import { Outlet, createFileRoute } from '@tanstack/react-router' +import { fadeInVariants } from '@/lib/animations' +import { launchQueryOptions } from '@/lib/data' +import { Outlet, createFileRoute, redirect } from '@tanstack/react-router' import { motion } from 'framer-motion' export const Route = createFileRoute('/setup')({ + beforeLoad: async ({ context: { queryClient } }) => { + const { is_setup } = await queryClient + .fetchQuery(launchQueryOptions) + .catch(() => { + throw redirect({ to: '/' }) + }) + + if (is_setup) { + throw redirect({ to: '/menu' }) + } + }, component: Setup }) @@ -9,9 +22,9 @@ export function Setup() { return ( { @@ -28,8 +31,6 @@ export const Route = createFileRoute('/setup/$key')({ } }, staleTime: Infinity, - // TODO: Design loading component - pendingComponent: () =>
Loading...
, component: ConfigureComponent }) @@ -38,8 +39,9 @@ function ConfigureComponent() { const { key } = Route.useParams() as { key: ConfigErrors } const { action, platforms } = Route.useSearch() const { data: defaultPath } = useSuspenseQuery(getSetupPath(key)) + const [imageLoaded, setImageLoaded] = useState(false) - const mutation = useSetupErrorMutation({ + const { mutate } = useSetupErrorMutation({ onSuccess: async () => { navigate({ to: '/menu', @@ -48,7 +50,6 @@ function ConfigureComponent() { }, onError: (error) => { if (error instanceof ConfigError) { - toast.error(error.message) if ( error.error_key === 'BattleNetConfig' || error.error_key === 'BattleNetInstall' @@ -64,118 +65,118 @@ function ConfigureComponent() { }, replace: true }) + return } - return } - toast.error(error.message) + handleError(error) } }) return ( - - Something went wrong - - - There was an error {action} your{' '} - {key === 'BattleNetInstall' ? ( - <> - Battle.net Launcher. If you have Overwatch installed through Steam, - please wait for a future update. - - If you do have Battle.net installed, please select the{' '} - - Battle.net Launcher.exe - {' '} - file, which is likely located in{' '} - - {defaultPath} - - . - - - ) : key === 'BattleNetConfig' ? ( - <> - Battle.net configuration file. Please select the{' '} - - Battle.net.config - {' '} - file, which is likely located in{' '} - - {defaultPath} - - . - - ) : ( - key === 'SteamInstall' && ( + + Setup Error + + + There was an error {action} your{' '} + {key === 'BattleNetInstall' ? ( <> - Steam installation. Please select the{' '} - - steam.exe - {' '} - file, which is likely located in{' '} - - {defaultPath} + Battle.net Launcher. If you have Overwatch installed through + Steam, please wait for a future update. + + If you do have Battle.net installed, please select the{' '} + Battle.net Launcher.exe file, which is + likely located in {defaultPath}. - . - ) + ) : key === 'BattleNetConfig' ? ( + <> + Battle.net configuration file. Please select the{' '} + Battle.net.config file, which is likely + located in {defaultPath}. + + ) : ( + key === 'SteamInstall' && ( + <> + Steam installation. Please select the{' '} + steam.exe file, which is likely located + in {defaultPath}. + + ) + )} + + { + const selected = await open({ + filters: [ + { + name: + key === 'BattleNetInstall' + ? 'Battle.net Launcher' + : key === 'BattleNetConfig' + ? 'Configuration File' + : 'steam', + extensions: [key.endsWith('Config') ? 'config' : 'exe'] + } + ], + defaultPath + }) + if (!selected) return + const file = + key === 'BattleNetInstall' + ? 'Battle.net Launcher.exe' + : key === 'BattleNetConfig' + ? 'Battle.net.config' + : 'steam.exe' + if (selected.indexOf(file) === -1) { + toast.error(`Please select the "${file}" file.`) + return + } + mutate({ + key, + path: selected as string, + platforms + }) + }} + variants={moveInVariants} + > + Select{' '} + {key === 'BattleNetInstall' + ? 'Battle.net Launcher.exe' + : key === 'BattleNetConfig' + ? 'Battle.net.config' + : 'steam.exe'} + + + logo - { - const selected = await open({ - filters: [ - { - name: - key === 'BattleNetInstall' - ? 'Battle.net Launcher' - : key === 'BattleNetConfig' - ? 'Configuration File' - : 'steam', - extensions: [key.endsWith('Config') ? 'config' : 'exe'] - } - ], - defaultPath - }) - if (!selected) return - const file = - key === 'BattleNetInstall' - ? 'Battle.net Launcher.exe' - : key === 'BattleNetConfig' - ? 'Battle.net.config' - : 'steam.exe' - if (selected.indexOf(file) === -1) { - toast.error(`Please select the "${file}" file.`) - return - } - mutation.mutate({ - key, - path: selected as string, - platforms - }) - }} - variants={childVariants} - > - Select{' '} - {key === 'BattleNetInstall' - ? 'Battle.net Launcher.exe' - : key === 'BattleNetConfig' - ? 'Battle.net.config' - : 'steam.exe'} - + loading="eager" + onLoad={() => setImageLoaded(true)} + draggable={false} + />
) } diff --git a/src/routes/setup/index.tsx b/src/routes/setup/index.tsx index 1e509b1..4857659 100644 --- a/src/routes/setup/index.tsx +++ b/src/routes/setup/index.tsx @@ -5,11 +5,11 @@ import { } from '@tanstack/react-router' import { motion } from 'framer-motion' import { BookLockIcon, GlobeIcon, SparklesIcon } from 'lucide-react' -import { toast } from 'sonner' import logo from '@/assets/logo.svg' -import { ConfigError, ConfigErrors, useSetupMutation } from '@/lib/data' -import { childVariants, containerVariants } from './-constants' +import { moveInVariants, staggerChildrenVariants } from '@/lib/animations' +import { useSetupMutation } from '@/lib/data' +import { ConfigError, ConfigErrors, handleError } from '@/lib/errors' export const Route = createFileRoute('/setup/')({ component: SetupSplash @@ -19,24 +19,24 @@ export function SetupSplash() { const navigate = useNavigate() const { status, mutate, reset } = useSetupMutation({ onError: (error) => { - if (error instanceof ConfigError) { - toast.error(error.message) - if (ConfigErrors.safeParse(error.error_key).success) { - navigate({ - to: '/setup/$key', - params: { - key: error.error_key - }, - search: { - action: error.error_action || 'finding', - platforms: error.platforms - }, - replace: true - }) - } + if ( + error instanceof ConfigError && + ConfigErrors.safeParse(error.error_key).success + ) { + navigate({ + to: '/setup/$key', + params: { + key: error.error_key + }, + search: { + action: error.error_action || 'finding', + platforms: error.platforms + }, + replace: true + }) return } - toast.error(error.message) + handleError(error) reset() }, onSuccess: () => { @@ -50,38 +50,39 @@ export function SetupSplash() { return ( - + Welcome to OverBuddy!
Personalized Overwatch™ Experience - + Explore all available backgrounds and select your favourite to customize your in-game menu. @@ -90,18 +91,18 @@ export function SetupSplash() {
Free and Open Source - + OverBuddy is free to use and open source. It operates independently and is not affiliated with Blizzard Entertainment®. You can undo the changes made by this app at any time by reverting @@ -112,18 +113,18 @@ export function SetupSplash() {
Privacy Notice - + To change your background, this app needs to read and write your Battle.net®{/* or Steam®*/} configuration files. It does{' '} NOT modify any game files. To @@ -133,9 +134,9 @@ export function SetupSplash() {
- + {/* */} { if (platforms.length === 0) { @@ -199,7 +196,7 @@ export function SetupSelect() { } mutate(platforms) }} - variants={childVariants} + variants={moveInVariants} > Continue diff --git a/src/styles.css b/src/styles.css index 2c8e406..b55ef88 100644 --- a/src/styles.css +++ b/src/styles.css @@ -4,9 +4,7 @@ @layer utilities { .scrollbar-hide { - /* IE and Edge */ -ms-overflow-style: none; - /* Firefox */ scrollbar-width: none; } @@ -19,7 +17,6 @@ box-sizing: border-box; } -/* Fade in */ .underline-fade-in::after { content: ''; position: absolute; diff --git a/tailwind.config.js b/tailwind.config.js index 3aad57d..248fbad 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -14,5 +14,17 @@ export default { } } }, - plugins: [] + plugins: [ + require('tailwind-easing-gradients')({ + gradients: { + 'menu-bottom': { + color: ['rgba(9, 9, 11, 0)', 'rgba(9, 9, 11, 0.5)'] + }, + 'menu-top': { + color: ['transparent', 'rgb(24, 24, 27)'] + } + }, + easing: 'ease-in-out' + }) + ] } diff --git a/tsconfig.json b/tsconfig.json index 22de3b3..4c2de66 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,26 +1,27 @@ { + "$schema": "https://json.schemastore.org/tsconfig", "compilerOptions": { "baseUrl": ".", "paths": { "@/*": ["src/*"] }, - "target": "ES2020", + "target": "ES2022", "useDefineForClassFields": true, - "lib": ["ES2020", "DOM", "DOM.Iterable"], - "module": "ESNext", + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "module": "preserve", "skipLibCheck": true, /* Bundler mode */ - "moduleResolution": "bundler", "allowImportingTsExtensions": true, - "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", + "verbatimModuleSyntax": true, /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true + "noFallthroughCasesInSwitch": true, + "noUncheckedIndexedAccess": true }, "include": ["src"], "references": [