diff --git a/gui/.editorconfig b/gui/.editorconfig index ebe51d3..e47a131 100644 --- a/gui/.editorconfig +++ b/gui/.editorconfig @@ -8,5 +8,8 @@ indent_style = space indent_size = 2 end_of_line = lf charset = utf-8 -trim_trailing_whitespace = false -insert_final_newline = false \ No newline at end of file +trim_trailing_whitespace = true +insert_final_newline = true + +[*.rs] +indent_size = 4 diff --git a/gui/package.json b/gui/package.json index e83d437..4086458 100644 --- a/gui/package.json +++ b/gui/package.json @@ -12,6 +12,7 @@ }, "dependencies": { "@tauri-apps/api": "^1.2.0", + "classnames": "^2.3.2", "daisyui": "^2.51.3", "i18next": "^22.4.10", "i18next-browser-languagedetector": "^7.0.1", diff --git a/gui/pnpm-lock.yaml b/gui/pnpm-lock.yaml index 8f799a2..ced6f7e 100644 --- a/gui/pnpm-lock.yaml +++ b/gui/pnpm-lock.yaml @@ -10,6 +10,7 @@ specifiers: '@types/react-dom': ^18.0.6 '@vitejs/plugin-react': ^3.1.0 autoprefixer: ^10.4.13 + classnames: ^2.3.2 daisyui: ^2.51.3 eslint: ^8.35.0 eslint-config-react-app: ^7.0.1 @@ -29,6 +30,7 @@ specifiers: dependencies: '@tauri-apps/api': 1.2.0 + classnames: registry.npmmirror.com/classnames/2.3.2 daisyui: 2.51.3_gbtt6ss3tbiz4yjtvdr6fbrj44 i18next: 22.4.10 i18next-browser-languagedetector: 7.0.1 @@ -48,7 +50,7 @@ devDependencies: eslint: 8.35.0 eslint-config-react-app: 7.0.1_ycpbpc6yetojsgtrx3mwntkhsu postcss: 8.4.21 - tailwindcss: 3.2.7_postcss@8.4.21 + tailwindcss: 3.2.7 typescript: 4.9.5 vite: 4.1.4_@types+node@18.14.5 vite-plugin-eslint: 1.8.1_eslint@8.35.0+vite@4.1.4 @@ -1415,204 +1417,6 @@ packages: to-fast-properties: 2.0.0 dev: true - /@esbuild/android-arm/0.16.17: - resolution: {integrity: sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/android-arm64/0.16.17: - resolution: {integrity: sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/android-x64/0.16.17: - resolution: {integrity: sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/darwin-arm64/0.16.17: - resolution: {integrity: sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@esbuild/darwin-x64/0.16.17: - resolution: {integrity: sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@esbuild/freebsd-arm64/0.16.17: - resolution: {integrity: sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/freebsd-x64/0.16.17: - resolution: {integrity: sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-arm/0.16.17: - resolution: {integrity: sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-arm64/0.16.17: - resolution: {integrity: sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-ia32/0.16.17: - resolution: {integrity: sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-loong64/0.16.17: - resolution: {integrity: sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-mips64el/0.16.17: - resolution: {integrity: sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-ppc64/0.16.17: - resolution: {integrity: sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-riscv64/0.16.17: - resolution: {integrity: sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-s390x/0.16.17: - resolution: {integrity: sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-x64/0.16.17: - resolution: {integrity: sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/netbsd-x64/0.16.17: - resolution: {integrity: sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/openbsd-x64/0.16.17: - resolution: {integrity: sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/sunos-x64/0.16.17: - resolution: {integrity: sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - requiresBuild: true - dev: true - optional: true - - /@esbuild/win32-arm64/0.16.17: - resolution: {integrity: sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@esbuild/win32-ia32/0.16.17: - resolution: {integrity: sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@esbuild/win32-x64/0.16.17: - resolution: {integrity: sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true - optional: true - /@eslint/eslintrc/2.0.0: resolution: {integrity: sha512-fluIaaV+GyV24CCu/ggiHdV+j4RNh85yQnAYS/G2mZODZgGmmlrgCydjUcV3YvxCm9x8nMAfThsqTni4KiXT4A==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1739,101 +1543,20 @@ packages: engines: {node: '>= 14.6.0', npm: '>= 6.6.0', yarn: '>= 1.19.1'} dev: false - /@tauri-apps/cli-darwin-arm64/1.2.3: - resolution: {integrity: sha512-phJN3fN8FtZZwqXg08bcxfq1+X1JSDglLvRxOxB7VWPq+O5SuB8uLyssjJsu+PIhyZZnIhTGdjhzLSFhSXfLsw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@tauri-apps/cli-darwin-x64/1.2.3: - resolution: {integrity: sha512-jFZ/y6z8z6v4yliIbXKBXA7BJgtZVMsITmEXSuD6s5+eCOpDhQxbRkr6CA+FFfr+/r96rWSDSgDenDQuSvPAKw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@tauri-apps/cli-linux-arm-gnueabihf/1.2.3: - resolution: {integrity: sha512-C7h5vqAwXzY0kRGSU00Fj8PudiDWFCiQqqUNI1N+fhCILrzWZB9TPBwdx33ZfXKt/U4+emdIoo/N34v3TiAOmQ==} - engines: {node: '>= 10'} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@tauri-apps/cli-linux-arm64-gnu/1.2.3: - resolution: {integrity: sha512-buf1c8sdkuUzVDkGPQpyUdAIIdn5r0UgXU6+H5fGPq/Xzt5K69JzXaeo6fHsZEZghbV0hOK+taKV4J0m30UUMQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@tauri-apps/cli-linux-arm64-musl/1.2.3: - resolution: {integrity: sha512-x88wPS9W5xAyk392vc4uNHcKBBvCp0wf4H9JFMF9OBwB7vfd59LbQCFcPSu8f0BI7bPrOsyHqspWHuFL8ojQEA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@tauri-apps/cli-linux-x64-gnu/1.2.3: - resolution: {integrity: sha512-ZMz1jxEVe0B4/7NJnlPHmwmSIuwiD6ViXKs8F+OWWz2Y4jn5TGxWKFg7DLx5OwQTRvEIZxxT7lXHi5CuTNAxKg==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@tauri-apps/cli-linux-x64-musl/1.2.3: - resolution: {integrity: sha512-B/az59EjJhdbZDzawEVox0LQu2ZHCZlk8rJf85AMIktIUoAZPFbwyiUv7/zjzA/sY6Nb58OSJgaPL2/IBy7E0A==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@tauri-apps/cli-win32-ia32-msvc/1.2.3: - resolution: {integrity: sha512-ypdO1OdC5ugNJAKO2m3sb1nsd+0TSvMS9Tr5qN/ZSMvtSduaNwrcZ3D7G/iOIanrqu/Nl8t3LYlgPZGBKlw7Ng==} - engines: {node: '>= 10'} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@tauri-apps/cli-win32-x64-msvc/1.2.3: - resolution: {integrity: sha512-CsbHQ+XhnV/2csOBBDVfH16cdK00gNyNYUW68isedmqcn8j+s0e9cQ1xXIqi+Hue3awp8g3ImYN5KPepf3UExw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true - optional: true - /@tauri-apps/cli/1.2.3: resolution: {integrity: sha512-erxtXuPhMEGJPBtnhPILD4AjuT81GZsraqpFvXAmEJZ2p8P6t7MVBifCL8LznRknznM3jn90D3M8RNBP3wcXTw==} engines: {node: '>= 10'} hasBin: true optionalDependencies: - '@tauri-apps/cli-darwin-arm64': 1.2.3 - '@tauri-apps/cli-darwin-x64': 1.2.3 - '@tauri-apps/cli-linux-arm-gnueabihf': 1.2.3 - '@tauri-apps/cli-linux-arm64-gnu': 1.2.3 - '@tauri-apps/cli-linux-arm64-musl': 1.2.3 - '@tauri-apps/cli-linux-x64-gnu': 1.2.3 - '@tauri-apps/cli-linux-x64-musl': 1.2.3 - '@tauri-apps/cli-win32-ia32-msvc': 1.2.3 - '@tauri-apps/cli-win32-x64-msvc': 1.2.3 + '@tauri-apps/cli-darwin-arm64': registry.npmmirror.com/@tauri-apps/cli-darwin-arm64/1.2.3 + '@tauri-apps/cli-darwin-x64': registry.npmmirror.com/@tauri-apps/cli-darwin-x64/1.2.3 + '@tauri-apps/cli-linux-arm-gnueabihf': registry.npmmirror.com/@tauri-apps/cli-linux-arm-gnueabihf/1.2.3 + '@tauri-apps/cli-linux-arm64-gnu': registry.npmmirror.com/@tauri-apps/cli-linux-arm64-gnu/1.2.3 + '@tauri-apps/cli-linux-arm64-musl': registry.npmmirror.com/@tauri-apps/cli-linux-arm64-musl/1.2.3 + '@tauri-apps/cli-linux-x64-gnu': registry.npmmirror.com/@tauri-apps/cli-linux-x64-gnu/1.2.3 + '@tauri-apps/cli-linux-x64-musl': registry.npmmirror.com/@tauri-apps/cli-linux-x64-musl/1.2.3 + '@tauri-apps/cli-win32-ia32-msvc': registry.npmmirror.com/@tauri-apps/cli-win32-ia32-msvc/1.2.3 + '@tauri-apps/cli-win32-x64-msvc': registry.npmmirror.com/@tauri-apps/cli-win32-x64-msvc/1.2.3 dev: true /@types/eslint/8.21.1: @@ -2359,7 +2082,7 @@ packages: normalize-path: 3.0.0 readdirp: 3.6.0 optionalDependencies: - fsevents: 2.3.2 + fsevents: registry.npmmirror.com/fsevents/2.3.2 /color-convert/1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} @@ -2460,7 +2183,7 @@ packages: css-selector-tokenizer: 0.8.0 postcss: 8.4.21 postcss-js: 4.0.1_postcss@8.4.21 - tailwindcss: 3.2.7_postcss@8.4.21 + tailwindcss: 3.2.7 transitivePeerDependencies: - ts-node dev: false @@ -2661,28 +2384,28 @@ packages: hasBin: true requiresBuild: true optionalDependencies: - '@esbuild/android-arm': 0.16.17 - '@esbuild/android-arm64': 0.16.17 - '@esbuild/android-x64': 0.16.17 - '@esbuild/darwin-arm64': 0.16.17 - '@esbuild/darwin-x64': 0.16.17 - '@esbuild/freebsd-arm64': 0.16.17 - '@esbuild/freebsd-x64': 0.16.17 - '@esbuild/linux-arm': 0.16.17 - '@esbuild/linux-arm64': 0.16.17 - '@esbuild/linux-ia32': 0.16.17 - '@esbuild/linux-loong64': 0.16.17 - '@esbuild/linux-mips64el': 0.16.17 - '@esbuild/linux-ppc64': 0.16.17 - '@esbuild/linux-riscv64': 0.16.17 - '@esbuild/linux-s390x': 0.16.17 - '@esbuild/linux-x64': 0.16.17 - '@esbuild/netbsd-x64': 0.16.17 - '@esbuild/openbsd-x64': 0.16.17 - '@esbuild/sunos-x64': 0.16.17 - '@esbuild/win32-arm64': 0.16.17 - '@esbuild/win32-ia32': 0.16.17 - '@esbuild/win32-x64': 0.16.17 + '@esbuild/android-arm': registry.npmmirror.com/@esbuild/android-arm/0.16.17 + '@esbuild/android-arm64': registry.npmmirror.com/@esbuild/android-arm64/0.16.17 + '@esbuild/android-x64': registry.npmmirror.com/@esbuild/android-x64/0.16.17 + '@esbuild/darwin-arm64': registry.npmmirror.com/@esbuild/darwin-arm64/0.16.17 + '@esbuild/darwin-x64': registry.npmmirror.com/@esbuild/darwin-x64/0.16.17 + '@esbuild/freebsd-arm64': registry.npmmirror.com/@esbuild/freebsd-arm64/0.16.17 + '@esbuild/freebsd-x64': registry.npmmirror.com/@esbuild/freebsd-x64/0.16.17 + '@esbuild/linux-arm': registry.npmmirror.com/@esbuild/linux-arm/0.16.17 + '@esbuild/linux-arm64': registry.npmmirror.com/@esbuild/linux-arm64/0.16.17 + '@esbuild/linux-ia32': registry.npmmirror.com/@esbuild/linux-ia32/0.16.17 + '@esbuild/linux-loong64': registry.npmmirror.com/@esbuild/linux-loong64/0.16.17 + '@esbuild/linux-mips64el': registry.npmmirror.com/@esbuild/linux-mips64el/0.16.17 + '@esbuild/linux-ppc64': registry.npmmirror.com/@esbuild/linux-ppc64/0.16.17 + '@esbuild/linux-riscv64': registry.npmmirror.com/@esbuild/linux-riscv64/0.16.17 + '@esbuild/linux-s390x': registry.npmmirror.com/@esbuild/linux-s390x/0.16.17 + '@esbuild/linux-x64': registry.npmmirror.com/@esbuild/linux-x64/0.16.17 + '@esbuild/netbsd-x64': registry.npmmirror.com/@esbuild/netbsd-x64/0.16.17 + '@esbuild/openbsd-x64': registry.npmmirror.com/@esbuild/openbsd-x64/0.16.17 + '@esbuild/sunos-x64': registry.npmmirror.com/@esbuild/sunos-x64/0.16.17 + '@esbuild/win32-arm64': registry.npmmirror.com/@esbuild/win32-arm64/0.16.17 + '@esbuild/win32-ia32': registry.npmmirror.com/@esbuild/win32-ia32/0.16.17 + '@esbuild/win32-x64': registry.npmmirror.com/@esbuild/win32-x64/0.16.17 dev: true /escalade/3.1.1: @@ -3120,13 +2843,6 @@ packages: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} dev: true - /fsevents/2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - requiresBuild: true - optional: true - /function-bind/1.1.1: resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} @@ -3832,7 +3548,7 @@ packages: peerDependencies: postcss: ^8.0.0 dependencies: - postcss: 8.4.21 + postcss: registry.npmmirror.com/postcss/8.4.21 postcss-value-parser: 4.2.0 read-cache: 1.0.0 resolve: 1.22.1 @@ -3844,7 +3560,7 @@ packages: postcss: ^8.4.21 dependencies: camelcase-css: 2.0.1 - postcss: 8.4.21 + postcss: registry.npmmirror.com/postcss/8.4.21 /postcss-load-config/3.1.4_postcss@8.4.21: resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} @@ -3859,7 +3575,7 @@ packages: optional: true dependencies: lilconfig: 2.1.0 - postcss: 8.4.21 + postcss: registry.npmmirror.com/postcss/8.4.21 yaml: 1.10.2 /postcss-nested/6.0.0_postcss@8.4.21: @@ -3868,7 +3584,7 @@ packages: peerDependencies: postcss: ^8.2.14 dependencies: - postcss: 8.4.21 + postcss: registry.npmmirror.com/postcss/8.4.21 postcss-selector-parser: 6.0.11 /postcss-selector-parser/6.0.11: @@ -4093,7 +3809,7 @@ packages: engines: {node: '>=10.0.0'} hasBin: true optionalDependencies: - fsevents: 2.3.2 + fsevents: registry.npmmirror.com/fsevents/2.3.2 dev: true /rollup/3.18.0: @@ -4101,7 +3817,7 @@ packages: engines: {node: '>=14.18.0', npm: '>=8.0.0'} hasBin: true optionalDependencies: - fsevents: 2.3.2 + fsevents: registry.npmmirror.com/fsevents/2.3.2 dev: true /run-parallel/1.2.0: @@ -4246,12 +3962,10 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - /tailwindcss/3.2.7_postcss@8.4.21: + /tailwindcss/3.2.7: resolution: {integrity: sha512-B6DLqJzc21x7wntlH/GsZwEXTBttVSl1FtCzC8WP4oBc/NKef7kaax5jeihkkCEWc831/5NDJ9gRNDK6NEioQQ==} engines: {node: '>=12.13.0'} hasBin: true - peerDependencies: - postcss: ^8.0.9 dependencies: arg: 5.0.2 chokidar: 3.5.3 @@ -4267,7 +3981,7 @@ packages: normalize-path: 3.0.0 object-hash: 3.0.0 picocolors: 1.0.0 - postcss: 8.4.21 + postcss: registry.npmmirror.com/postcss/8.4.21 postcss-import: 14.1.0_postcss@8.4.21 postcss-js: 4.0.1_postcss@8.4.21 postcss-load-config: 3.1.4_postcss@8.4.21 @@ -4396,7 +4110,7 @@ packages: dependencies: browserslist: 4.21.5 escalade: 3.1.1 - picocolors: 1.0.0 + picocolors: registry.npmmirror.com/picocolors/1.0.0 /uri-js/4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} @@ -4462,7 +4176,7 @@ packages: resolve: 1.22.1 rollup: 3.18.0 optionalDependencies: - fsevents: 2.3.2 + fsevents: registry.npmmirror.com/fsevents/2.3.2 dev: true /void-elements/3.1.0: @@ -4538,3 +4252,391 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} dev: true + + registry.npmmirror.com/@esbuild/android-arm/0.16.17: + resolution: {integrity: sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.16.17.tgz} + name: '@esbuild/android-arm' + version: 0.16.17 + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@esbuild/android-arm64/0.16.17: + resolution: {integrity: sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.16.17.tgz} + name: '@esbuild/android-arm64' + version: 0.16.17 + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@esbuild/android-x64/0.16.17: + resolution: {integrity: sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.16.17.tgz} + name: '@esbuild/android-x64' + version: 0.16.17 + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@esbuild/darwin-arm64/0.16.17: + resolution: {integrity: sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.16.17.tgz} + name: '@esbuild/darwin-arm64' + version: 0.16.17 + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@esbuild/darwin-x64/0.16.17: + resolution: {integrity: sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.16.17.tgz} + name: '@esbuild/darwin-x64' + version: 0.16.17 + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@esbuild/freebsd-arm64/0.16.17: + resolution: {integrity: sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.17.tgz} + name: '@esbuild/freebsd-arm64' + version: 0.16.17 + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@esbuild/freebsd-x64/0.16.17: + resolution: {integrity: sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.16.17.tgz} + name: '@esbuild/freebsd-x64' + version: 0.16.17 + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@esbuild/linux-arm/0.16.17: + resolution: {integrity: sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.16.17.tgz} + name: '@esbuild/linux-arm' + version: 0.16.17 + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@esbuild/linux-arm64/0.16.17: + resolution: {integrity: sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.16.17.tgz} + name: '@esbuild/linux-arm64' + version: 0.16.17 + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@esbuild/linux-ia32/0.16.17: + resolution: {integrity: sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.16.17.tgz} + name: '@esbuild/linux-ia32' + version: 0.16.17 + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@esbuild/linux-loong64/0.16.17: + resolution: {integrity: sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.16.17.tgz} + name: '@esbuild/linux-loong64' + version: 0.16.17 + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@esbuild/linux-mips64el/0.16.17: + resolution: {integrity: sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.16.17.tgz} + name: '@esbuild/linux-mips64el' + version: 0.16.17 + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@esbuild/linux-ppc64/0.16.17: + resolution: {integrity: sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.16.17.tgz} + name: '@esbuild/linux-ppc64' + version: 0.16.17 + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@esbuild/linux-riscv64/0.16.17: + resolution: {integrity: sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.16.17.tgz} + name: '@esbuild/linux-riscv64' + version: 0.16.17 + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@esbuild/linux-s390x/0.16.17: + resolution: {integrity: sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.16.17.tgz} + name: '@esbuild/linux-s390x' + version: 0.16.17 + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@esbuild/linux-x64/0.16.17: + resolution: {integrity: sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.16.17.tgz} + name: '@esbuild/linux-x64' + version: 0.16.17 + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@esbuild/netbsd-x64/0.16.17: + resolution: {integrity: sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.16.17.tgz} + name: '@esbuild/netbsd-x64' + version: 0.16.17 + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@esbuild/openbsd-x64/0.16.17: + resolution: {integrity: sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.16.17.tgz} + name: '@esbuild/openbsd-x64' + version: 0.16.17 + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@esbuild/sunos-x64/0.16.17: + resolution: {integrity: sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.16.17.tgz} + name: '@esbuild/sunos-x64' + version: 0.16.17 + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@esbuild/win32-arm64/0.16.17: + resolution: {integrity: sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.16.17.tgz} + name: '@esbuild/win32-arm64' + version: 0.16.17 + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@esbuild/win32-ia32/0.16.17: + resolution: {integrity: sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.16.17.tgz} + name: '@esbuild/win32-ia32' + version: 0.16.17 + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@esbuild/win32-x64/0.16.17: + resolution: {integrity: sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.16.17.tgz} + name: '@esbuild/win32-x64' + version: 0.16.17 + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@tauri-apps/cli-darwin-arm64/1.2.3: + resolution: {integrity: sha512-phJN3fN8FtZZwqXg08bcxfq1+X1JSDglLvRxOxB7VWPq+O5SuB8uLyssjJsu+PIhyZZnIhTGdjhzLSFhSXfLsw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-1.2.3.tgz} + name: '@tauri-apps/cli-darwin-arm64' + version: 1.2.3 + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@tauri-apps/cli-darwin-x64/1.2.3: + resolution: {integrity: sha512-jFZ/y6z8z6v4yliIbXKBXA7BJgtZVMsITmEXSuD6s5+eCOpDhQxbRkr6CA+FFfr+/r96rWSDSgDenDQuSvPAKw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-1.2.3.tgz} + name: '@tauri-apps/cli-darwin-x64' + version: 1.2.3 + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@tauri-apps/cli-linux-arm-gnueabihf/1.2.3: + resolution: {integrity: sha512-C7h5vqAwXzY0kRGSU00Fj8PudiDWFCiQqqUNI1N+fhCILrzWZB9TPBwdx33ZfXKt/U4+emdIoo/N34v3TiAOmQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-1.2.3.tgz} + name: '@tauri-apps/cli-linux-arm-gnueabihf' + version: 1.2.3 + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@tauri-apps/cli-linux-arm64-gnu/1.2.3: + resolution: {integrity: sha512-buf1c8sdkuUzVDkGPQpyUdAIIdn5r0UgXU6+H5fGPq/Xzt5K69JzXaeo6fHsZEZghbV0hOK+taKV4J0m30UUMQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-1.2.3.tgz} + name: '@tauri-apps/cli-linux-arm64-gnu' + version: 1.2.3 + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [glibc] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@tauri-apps/cli-linux-arm64-musl/1.2.3: + resolution: {integrity: sha512-x88wPS9W5xAyk392vc4uNHcKBBvCp0wf4H9JFMF9OBwB7vfd59LbQCFcPSu8f0BI7bPrOsyHqspWHuFL8ojQEA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.2.3.tgz} + name: '@tauri-apps/cli-linux-arm64-musl' + version: 1.2.3 + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [musl] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@tauri-apps/cli-linux-x64-gnu/1.2.3: + resolution: {integrity: sha512-ZMz1jxEVe0B4/7NJnlPHmwmSIuwiD6ViXKs8F+OWWz2Y4jn5TGxWKFg7DLx5OwQTRvEIZxxT7lXHi5CuTNAxKg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-1.2.3.tgz} + name: '@tauri-apps/cli-linux-x64-gnu' + version: 1.2.3 + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [glibc] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@tauri-apps/cli-linux-x64-musl/1.2.3: + resolution: {integrity: sha512-B/az59EjJhdbZDzawEVox0LQu2ZHCZlk8rJf85AMIktIUoAZPFbwyiUv7/zjzA/sY6Nb58OSJgaPL2/IBy7E0A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-1.2.3.tgz} + name: '@tauri-apps/cli-linux-x64-musl' + version: 1.2.3 + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [musl] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@tauri-apps/cli-win32-ia32-msvc/1.2.3: + resolution: {integrity: sha512-ypdO1OdC5ugNJAKO2m3sb1nsd+0TSvMS9Tr5qN/ZSMvtSduaNwrcZ3D7G/iOIanrqu/Nl8t3LYlgPZGBKlw7Ng==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-1.2.3.tgz} + name: '@tauri-apps/cli-win32-ia32-msvc' + version: 1.2.3 + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/@tauri-apps/cli-win32-x64-msvc/1.2.3: + resolution: {integrity: sha512-CsbHQ+XhnV/2csOBBDVfH16cdK00gNyNYUW68isedmqcn8j+s0e9cQ1xXIqi+Hue3awp8g3ImYN5KPepf3UExw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-1.2.3.tgz} + name: '@tauri-apps/cli-win32-x64-msvc' + version: 1.2.3 + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + registry.npmmirror.com/classnames/2.3.2: + resolution: {integrity: sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/classnames/-/classnames-2.3.2.tgz} + name: classnames + version: 2.3.2 + dev: false + + registry.npmmirror.com/fsevents/2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz} + name: fsevents + version: 2.3.2 + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + optional: true + + registry.npmmirror.com/nanoid/3.3.4: + resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/nanoid/-/nanoid-3.3.4.tgz} + name: nanoid + version: 3.3.4 + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + registry.npmmirror.com/picocolors/1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz} + name: picocolors + version: 1.0.0 + + registry.npmmirror.com/postcss/8.4.21: + resolution: {integrity: sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/postcss/-/postcss-8.4.21.tgz} + name: postcss + version: 8.4.21 + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: registry.npmmirror.com/nanoid/3.3.4 + picocolors: registry.npmmirror.com/picocolors/1.0.0 + source-map-js: registry.npmmirror.com/source-map-js/1.0.2 + + registry.npmmirror.com/source-map-js/1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz} + name: source-map-js + version: 1.0.2 + engines: {node: '>=0.10.0'} diff --git a/gui/src-tauri/tauri.conf.json b/gui/src-tauri/tauri.conf.json index 99a0ebd..d1a4f6c 100644 --- a/gui/src-tauri/tauri.conf.json +++ b/gui/src-tauri/tauri.conf.json @@ -39,9 +39,9 @@ }, "fs": { "scope": [ - "$APPCONFIG/*", - "$APPDATA/*", - "$APPCACHE/*" + "$APPCONFIG/**/*", + "$APPDATA/**/*", + "$APPCACHE/**/*" ], "all": true }, diff --git a/gui/src/components/ErrorContent.tsx b/gui/src/components/ErrorContent.tsx new file mode 100644 index 0000000..bdf9b59 --- /dev/null +++ b/gui/src/components/ErrorContent.tsx @@ -0,0 +1,26 @@ +import React from 'react' +import { useTranslation } from 'react-i18next' +import { AiOutlineWarning } from 'react-icons/ai' + +type ErrorContentProps = { + error: any + retry?: () => void +} + +export const ErrorContent: React.FC = ({ error, retry }) => { + const { t } = useTranslation(); + + if (!error) { + return <>; + } + + return
+ + +
+
{t('发生了错误')}{retry && }
+ {String(error)} +
+
+
+} diff --git a/gui/src/hooks/usePromise.ts b/gui/src/hooks/usePromise.ts index a89ce41..c2d8698 100644 --- a/gui/src/hooks/usePromise.ts +++ b/gui/src/hooks/usePromise.ts @@ -2,9 +2,7 @@ import { useState } from "react"; /** * A hook that returns a promise and its state. - * - * The promise is only created once, and the state is updated when the promise resolves or rejects. - * + * * @param factory A function that returns a promise. * @returns An object containing the promise's state and result. * @example @@ -20,21 +18,67 @@ import { useState } from "react"; * return

Result: {result}

; */ export function usePromise(factory: () => Promise) { - const [loading, setLoading] = useState(true); - const [result, setResult] = useState(undefined); - const [error, setError] = useState(undefined); - const [promise] = useState(() => { + const init = () => { const promise = factory(); if (!promise || typeof promise.then !== "function") { throw new Error("The factory function must return a promise."); } return promise - .then(setResult) - .catch(setError) - .finally(() => { + .then(r => { + setResult(r); setLoading(false); + return r; + }) + .catch(e => { + setError(e); + setLoading(false); + throw e; }); - }); + } + const [loading, setLoading] = useState(true); + const [result, setResult] = useState(undefined); + const [error, setError] = useState(undefined); + const [promise, setPromise] = useState(init); + const retry = () => { + setLoading(true); + setResult(undefined); + setError(undefined); + setPromise(init); + } - return { loading, result, error, promise }; + return { loading, result, error, promise, retry }; +} + +/** + * A hook that returns a promise and its state. + */ +export function usePromiseLazy(factory: (...args: Args) => Promise) { + const init = (promise: Promise) => { + if (!promise || typeof promise.then !== "function") { + throw new Error("The factory function must return a promise."); + } + return promise + .then(r => { + setResult(r); + setLoading(false); + return r; + }) + .catch(e => { + setError(e); + setLoading(false); + throw e; + }); + } + const [loading, setLoading] = useState(false); + const [result, setResult] = useState(undefined); + const [error, setError] = useState(undefined); + const [promise, setPromise] = useState | undefined>(undefined); + const execute = (...args: Args) => { + setLoading(true); + setResult(undefined); + setError(undefined); + setPromise(init(factory(...args))); + } + + return [execute, { loading, result, error, promise }] as const; } diff --git a/gui/src/pages/Settings.tsx b/gui/src/pages/Settings.tsx index 0e112f9..62eef60 100644 --- a/gui/src/pages/Settings.tsx +++ b/gui/src/pages/Settings.tsx @@ -1,41 +1,105 @@ +import { ErrorContent } from 'components/ErrorContent'; import { Loading } from 'components/Loading'; -import { usePromise } from 'hooks/usePromise'; -import React from 'react' +import { usePromise, usePromiseLazy } from 'hooks/usePromise'; +import React, { useState } from 'react' import { useTranslation } from 'react-i18next'; import { AiOutlineLeft } from 'react-icons/ai'; import { useNavigate } from 'react-router-dom'; -import { getConfig } from 'services/config'; +import { Config, getConfig, getProfile, Profile, setConfig, setProfile } from 'services/config'; +import { composeLoadable } from 'utils/composeLoadable'; +import classNames from 'classnames'; -export const Settings: React.FC = () => { - const { loading, result, error } = usePromise(getConfig); - const navigate = useNavigate(); +const Page: React.FC<{ children?: React.ReactNode }> = ({ children }) => { const { t } = useTranslation(); - const onSave = async () => { - } + const navigate = useNavigate(); + return
+

{t('配置')}

+ {children} +
+} - if (loading) { - return
- } +type FormData = { + config: Config, + profile: Profile, +} + +const Form: React.FC<{ + oldValue: FormData, + onSaved?: () => void, +}> = ({ oldValue, onSaved }) => { + const { t } = useTranslation(); + const [value, setValue] = useState(oldValue); + + const changed = JSON.stringify(value) !== JSON.stringify(oldValue); + + const [onSave, { loading, error }] = usePromiseLazy(async () => { + await setProfile(0, value.profile); + await setConfig(value.config); + onSaved?.(); + }) return <> -
-

{t('配置')}

-
-
- - -
+
+
+ + setValue({ + ...value, + profile: { + ...value.profile, + state: { + ...value.profile.state, + statInkApiKey: e.target.value, + } + } + })} + />
- +
+ +
+ +
-} \ No newline at end of file +} + +export const Settings: React.FC = () => { + let { loading, error, retry, result } = composeLoadable({ + config: usePromise(getConfig), + profile: usePromise(() => getProfile(0)), + }); + + if (loading) { + return +
+
+ } + + if (error) { + return + + + } + + return + {result &&
} + +} diff --git a/gui/src/services/config.ts b/gui/src/services/config.ts index 4e9966b..0ab006b 100644 --- a/gui/src/services/config.ts +++ b/gui/src/services/config.ts @@ -12,6 +12,18 @@ export type Profile = { export type Config = { } +// TODO: import from state.ts. +const DEFAULT_STATE: State = { + cacheDir: "./cache", + fGen: "https://api.imink.app/f", + fileExportPath: "./export", + monitorInterval: 500, +}; + +const defaultProfile: Profile = { + state: DEFAULT_STATE, +} + const defaultConfig: Config = { } @@ -22,8 +34,8 @@ export async function initFiles() { initFiles().catch(console.error); export async function getConfig(): Promise { - const config = await fs.readTextFile(await configFile); try { + const config = await fs.readTextFile(await configFile); return JSON.parse(config); } catch (e) { return defaultConfig; @@ -33,3 +45,16 @@ export async function getConfig(): Promise { export async function setConfig(config: Config) { await fs.writeTextFile(await configFile, JSON.stringify(config)); } + +export async function getProfile(index: number): Promise { + try { + const profile = await fs.readTextFile(await profileDir.then(c => join(c, `${index}.json`))); + return JSON.parse(profile); + } catch (e) { + return defaultProfile; + } +} + +export async function setProfile(index: number, profile: Profile) { + await fs.writeTextFile(await profileDir.then(c => join(c, `${index}.json`)), JSON.stringify(profile)); +} diff --git a/gui/src/utils/composeLoadable.ts b/gui/src/utils/composeLoadable.ts new file mode 100644 index 0000000..40e0a04 --- /dev/null +++ b/gui/src/utils/composeLoadable.ts @@ -0,0 +1,19 @@ +export type Loadable = { + loading: boolean; + result?: T; + error?: any; + retry?: () => void; +} + +export function composeLoadable>>(map: T): Loadable<{ + [P in keyof T]: T[P] extends Loadable ? R : never +}> { + const values = Object.values(map) + + const loading = values.some(v => v.loading); + const error = values.find(v => v.error)?.error; + const result = loading || error ? undefined : Object.fromEntries(Object.entries(map).map(([k, v]) => [k, v.result])) as any; + const retry = values.some(i => !!i.retry) ? () => Object.values(map).forEach(v => v.retry?.()) : undefined; + + return { loading, result, error, retry }; +} diff --git a/gui/src/utils/sleep.ts b/gui/src/utils/sleep.ts new file mode 100644 index 0000000..8a73cf4 --- /dev/null +++ b/gui/src/utils/sleep.ts @@ -0,0 +1,3 @@ +export function sleep(ms: number) { + return new Promise(resolve => setTimeout(resolve, ms)); +}