diff --git a/.editorconfig b/.editorconfig index 4645852..e47a131 100644 --- a/.editorconfig +++ b/.editorconfig @@ -5,10 +5,11 @@ root = true [*] indent_style = space +indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true -[Makefile] -indent_style = tab +[*.rs] +indent_size = 4 diff --git a/.github/ISSUE_TEMPLATE/bug-report.yaml b/.github/ISSUE_TEMPLATE/bug-report.yaml index c729930..bc29800 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yaml +++ b/.github/ISSUE_TEMPLATE/bug-report.yaml @@ -1,32 +1,30 @@ --- name: Bug Report description: File a bug report -title: "[Bug]: " -labels: ["bug"] +title: '[Bug]: ' +labels: ['bug'] body: - type: markdown attributes: value: | Thanks for taking the time to fill out this bug report! - - type: dropdown + - type: input id: version attributes: label: Version description: What version of our software are you running? - options: - - 0.1.0 - - 0.2.0 (Default) - - 0.3.0 (main branch:Next ver.) + placeholder: 'Example: 0.1.0' validations: required: true + - type: textarea id: unexpected-behavior attributes: label: Unexpected behavior here description: May I ask you to tell us about the unexpected behavior? # yamllint disable-line rule:line-length - placeholder: "Example: If '0' is written in settings.toml's duration, the process will go on forever." + placeholder: 'Example: logger is not worked.' validations: required: true - type: textarea @@ -34,7 +32,8 @@ body: attributes: label: Expected behavior description: May I ask you to tell us about the behavior you expect? - placeholder: "Example: Consider falling back to 1 if 0 is set." + # yamllint disable-line rule:line-length + placeholder: 'Example: Reflects the level specification of the logger in the GUI.' validations: required: true - type: textarea @@ -44,12 +43,3 @@ body: # yamllint disable-line rule:line-length description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. render: Shell - - type: checkboxes - id: terms - attributes: - label: Code of Conduct - # yamllint disable-line rule:line-length - description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/SARDONYX-sard/bluetooth-battery-monitor/CODE_OF_CONDUCT.md) - options: - - label: I agree to follow this project's Code of Conduct - required: true diff --git a/.github/ISSUE_TEMPLATE/feature-request.yaml b/.github/ISSUE_TEMPLATE/feature-request.yaml new file mode 100644 index 0000000..4c55d6b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-request.yaml @@ -0,0 +1,24 @@ +--- +name: Feature Request +description: File a feature request +title: '[Feature]: ' +labels: ['enhancement'] + +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this feature request. + - type: textarea + id: expected-behavior + attributes: + label: Expected behavior + description: May I ask you to tell us about the behavior you expect? + placeholder: 'Example: Add progress bar in the GUI.' + validations: + required: true + - type: textarea + id: other + attributes: + label: other + description: About everything else. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index f692ff2..9ee0774 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,23 +1,5 @@ # New Features -- [ ] Add - - - - - - - -- [ ] Implement to - -- [ ] Enable - # Changes and Fixes -- [ ] Change - -- [ ] Fix - -- [ ] Modify - # Refactors - -- [ ] Clean diff --git a/.github/workflows/lint-and-test.yaml b/.github/workflows/lint-and-test.yaml new file mode 100644 index 0000000..6b41db8 --- /dev/null +++ b/.github/workflows/lint-and-test.yaml @@ -0,0 +1,91 @@ +name: Cargo Lint & Test + +on: + push: + branches: ['main'] + pull_request: + branches: '*' + workflow_dispatch: # <- Setting to allow manual execution by button. + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + strategy: + fail-fast: false + matrix: + # platform: [macos-latest, ubuntu-20.04, windows-latest] + platform: [windows-latest] + runs-on: ${{ matrix.platform }} + + steps: + - name: Install dependencies (ubuntu only) + if: matrix.platform == 'ubuntu-20.04' + # You can remove libayatana-appindicator3-dev if you don't use the system tray feature. + run: | + sudo apt-get update + sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libayatana-appindicator3-dev librsvg2-dev + - uses: actions/checkout@v4.1.7 + - name: Rust cache + uses: Swatinem/rust-cache@v2.7.3 + with: + prefix-key: cargo-${{ matrix.platform }} + - name: Install components + run: | + rustup component add clippy + rustup component add rustfmt + - name: Format Check + run: cargo fmt --all -- --check + - name: Lint Check + run: cargo clippy --workspace -- -D warnings + - name: Test(Rust) + run: cargo test --workspace + + - name: Sync node version + uses: actions/setup-node@v4.0.3 + with: + node-version: 'lts/*' + cache: 'npm' + + - name: Node.js cache + uses: actions/cache@v4.0.2 + with: + path: ${{ github.workspace }}/gui/frontend/.next/cache + # Generate a new cache whenever packages or source files change. + key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('dar2oar_gui/frontend/src/**/*.[jt]s', 'dar2oar_gui/frontend/src/**/*.[jt]sx') }} + # If source files changed but packages didn't, rebuild from a prior cache. + restore-keys: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}- + - name: Install frontend dependencies + run: npm ci + + - name: Test(Node.js) + run: npm test + - name: Build Test(GUI) + run: npm run build + + - name: Make outputs dir + run: mkdir -p ./build + - name: Compress outputs(Windows) + shell: pwsh + if: runner.os == 'Windows' + run: | + Move-Item -Path ./target/release/bluetooth_battery_monitor.exe -Destination './build' + + - name: Compress outputs(MacOS) + shell: bash + if: runner.os == 'macOS' + run: | + mv ./target/release/bluetooth_battery_monitor ./build + - name: Compress outputs(Linux) + shell: bash + if: runner.os == 'Linux' + run: | + mv ./target/release/bluetooth_battery_monitor ./build + + - name: Upload a Build Artifact + uses: actions/upload-artifact@v4.3.4 + with: + name: Bluetooth Battery Monitor ${{runner.os}} + path: | + ./build/ diff --git a/.github/workflows/release-gui.yaml b/.github/workflows/release-gui.yaml new file mode 100644 index 0000000..9b323e4 --- /dev/null +++ b/.github/workflows/release-gui.yaml @@ -0,0 +1,60 @@ +name: Release GUI +on: + push: + tags: + - '*' + workflow_dispatch: + +jobs: + release: + permissions: + contents: write + strategy: + fail-fast: false + matrix: + platform: [macos-latest, ubuntu-20.04, windows-latest] + runs-on: ${{ matrix.platform }} + + steps: + - uses: actions/checkout@v4.1.7 + + - name: Install dependencies (ubuntu only) + if: matrix.platform == 'ubuntu-20.04' + # You can remove libayatana-appindicator3-dev if you don't use the system tray feature. + run: | + sudo apt-get update + sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libayatana-appindicator3-dev librsvg2-dev + + - name: Rust setup + uses: dtolnay/rust-toolchain@stable + + - name: Rust cache + uses: Swatinem/rust-cache@v2.7.3 + with: + prefix-key: cargo-${{ matrix.platform }} + + - name: Sync node version and setup cache + uses: actions/setup-node@v4.0.3 + with: + node-version: 'lts/*' + cache: 'npm' + + - name: Node.js cache + uses: actions/cache@v4.0.2 + with: + path: ${{ github.workspace }}/dar2oar_gui/frontend/.next/cache + # Generate a new cache whenever packages or source files change. + key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('dar2oar_gui/frontend/src/**/*.[jt]s', 'dar2oar_gui/frontend/src/**/*.[jt]sx') }} + restore-keys: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}- + - name: Install frontend dependencies + run: npm ci + + - name: Build the app + uses: tauri-apps/tauri-action@action-v0.5.9 + + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + releaseName: 'Bluetooth Battery Monitor v__VERSION__' + tagName: ${{ github.ref_name }} # This only works if your workflow triggers on new tags. + prerelease: false diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml deleted file mode 100644 index 321a885..0000000 --- a/.github/workflows/release.yaml +++ /dev/null @@ -1,46 +0,0 @@ -name: "publish" -on: - push: - tags: "*" - -jobs: - publish-tauri: - permissions: - contents: write - strategy: - fail-fast: false - matrix: - platform: [ - # macos-latest, ubuntu-20.04, #! Unsupported Now... - windows-latest, - ] - - runs-on: ${{ matrix.platform }} - steps: - - uses: actions/checkout@v3 - name: Go to this repository - - - uses: denoland/setup-deno@v1 - name: Install deno - with: - deno-version: "1.32.4" - - - name: Install Rust stable - uses: dtolnay/rust-toolchain@stable - - #! Unsupported Now... - # - name: install dependencies (ubuntu only) - # if: matrix.platform == 'ubuntu-20.04' - # run: | - # sudo apt-get update - # sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf - - - uses: tauri-apps/tauri-action@v0 - name: Create release files - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tagName: __VERSION__ # the action automatically replaces \_\_VERSION\_\_ with the app version - releaseName: "Bluetooth battery monitor v__VERSION__" - releaseDraft: true - prerelease: false diff --git a/.gitignore b/.gitignore index eeca437..3c002d6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,22 @@ -target -WixTools -dist -**/node_modules/ +# dependencies +node_modules/ -devices.json +# next.js +.next/ +.swc +out/ + +# production +build + +# misc +.DS_Store +*.pem +test/data/* +!test/data/*.md +*.log + +# Rust build cache +**/target + +secrets/ diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 0000000..fd1fc27 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,10 @@ +//! NOTE: If this file is not in the root directory, VSCode's prettier extension will not reflect this setting. +//! Use prettier because biome is fast but does not yet support yaml formatting. +// @ts-check + +/** @type {import('prettier').Options} */ +export default { + semi: true, + singleQuote: true, + printWidth: 120, +}; diff --git a/.vscode/extensions.json b/.vscode/extensions.json index ef3a3aa..0fbe39e 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,5 +1,11 @@ { "recommendations": [ - "bradlc.vscode-tailwindcss" + "biomejs.biome", + "editorconfig.editorconfig", + "jayfong.generate-index", + "lokalise.i18n-ally", + "rust-lang.rust-analyzer", + "tamasfe.even-better-toml", + "vitest.explorer" ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 58ce8a2..fe73651 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,64 +1,31 @@ { - "[jsonc]": { - "editor.defaultFormatter": "vscode.json-language-features" + "[javascript][javascriptreact][typescript][typescriptreact]": { + "editor.defaultFormatter": "biomejs.biome" }, - "[markdown]": { - "editor.codeActionsOnSave": { - "source.fixAll.markdownlint": true - }, - "editor.defaultFormatter": "DavidAnson.vscode-markdownlint", - "editor.padding.bottom": 250, - "editor.quickSuggestions": { - "comments": false, - "other": true, - "strings": false - }, - "editor.scrollBeyondLastLine": false + "[json][jsonc]": { + "editor.defaultFormatter": "biomejs.biome" }, - "[rust]": { - "editor.formatOnSave": true + "[yaml]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" }, - "deno.enable": true, - "deno.importMap": "./import_map.json", - "deno.inlayHints.enumMemberValues.enabled": true, - "deno.inlayHints.functionLikeReturnTypes.enabled": true, - "deno.inlayHints.parameterNames.enabled": "all", - "deno.inlayHints.parameterTypes.enabled": true, - "deno.inlayHints.variableTypes.enabled": true, - "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "quickfix.biome": "explicit", + "source.fixAll.eslint": "explicit", + "source.fixAll.sortJSON": "never", + "source.organizeImports.biome": "explicit" + }, + "evenBetterToml.formatter.alignComments": true, + // "rust-analyzer.checkOnSave": false, + // "editor.formatOnSave": false "files.exclude": { - "**/.dccache": true, - "**/.DS_Store": true, - "**/.gdb_history": true, - "**/.git": true, - "**/target": true + ".swc": true, + "**/node_modules": true // optional }, "files.watcherExclude": { - "**/.dccache": true, - "**/.DS_Store": true, - "**/.gdb_history": true, - "**/.git": true, - "**/dist": true, - "**/node_modules": true, - "**/target": true - }, - "git.autoRepositoryDetection": false, - "git.ignoreLimitWarning": true, - "markdownlint.config": { - "default": true, - "MD024": false, - "MD025": false, - "MD033": false, - "no-hard-tabs": false + "**/.git/objects/**": true, + "**/node_modules/**": true, + "**/target/**": true }, - "rust-analyzer.check.command": "clippy", - "rust-analyzer.diagnostics.disabled": [ - "unresolved-proc-macro" - ], - "rust-analyzer.inlayHints.lifetimeElisionHints.enable": "skip_trivial", - "rust-analyzer.inlayHints.lifetimeElisionHints.useParameterNames": true, - "rust-analyzer.linkedProjects": [ - "./src-tauri/Cargo.toml" - ], // For rust-js-interval test error - "rust-analyzer.rustfmt.rangeFormatting.enable": true + "i18n-ally.keystyle": "nested", + "rust-analyzer.check.command": "clippy" } diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..712564b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,399 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [0.7.0] - 2024-04-05 +### :sparkles: New Features +- [`b95ef4d`](https://github.com/SARDONYX-sard/dar-to-oar/commit/b95ef4dd46155c2a98514f1e5866458b3a02c9dc) - **core**: support creature path *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`bf9d448`](https://github.com/SARDONYX-sard/dar-to-oar/commit/bf9d4488ce0e7927b44b43795105562bb45391b3) - **core**: use `not_line_ending` api *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`c6541ff`](https://github.com/SARDONYX-sard/dar-to-oar/commit/c6541ff867b75ab2d645b1755394f33031daa9d7) - **core**: support `ActorBase` DAR path format *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :wrench: Chores +- [`d5e101b`](https://github.com/SARDONYX-sard/dar-to-oar/commit/d5e101b1b20e254477ea60bf9ae4f51b7d19347d) - **github-template**: add `0.6.0` *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`b602bd4`](https://github.com/SARDONYX-sard/dar-to-oar/commit/b602bd42cd1e4a1a79dfc669667bfeab257b0f98) - **tools**: add auto version upper script *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + + +## [0.6.0] - 2024-02-17 +### :sparkles: New Features +- [`14894b9`](https://github.com/SARDONYX-sard/dar-to-oar/commit/14894b984c01715a69f7787e30463591b196e809) - **log**: change log display *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`42bb664`](https://github.com/SARDONYX-sard/dar-to-oar/commit/42bb664d666d47e14910924349c56f9b010f22ce) - **frontend-tauri**: add empty string check *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`bd9cd7f`](https://github.com/SARDONYX-sard/dar-to-oar/commit/bd9cd7fcd9d68cd034b09388ae5e03cf4ca69732) - **log**: stop logging thread id's *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`59368a1`](https://github.com/SARDONYX-sard/dar-to-oar/commit/59368a1fe3fd2b908e29d77395627ce69e32ad4c) - **sub_cmd**: add progress report *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`2308e47`](https://github.com/SARDONYX-sard/dar-to-oar/commit/2308e47d121241116f4849a7993de26a9ee05be5) - **front-css**: add css for circular *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`a5dc8d3`](https://github.com/SARDONYX-sard/dar-to-oar/commit/a5dc8d308bb6de8277182662301ab7d1c5511893) - **core**: add `trace!` on error *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`eef2047`](https://github.com/SARDONYX-sard/dar-to-oar/commit/eef2047aeb04081e73bfe312d429500cfceeca0c) - **frontend**: implement new notification *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`abb8699`](https://github.com/SARDONYX-sard/dar-to-oar/commit/abb86998a7785737f5e3cfb8ee4e2302fdd5d5d2) - **front**: change to tabs *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`833dbfd`](https://github.com/SARDONYX-sard/dar-to-oar/commit/833dbfd49e2c724d3b24204a616bf33798fb7b24) - **frontend**: apply bold to `snackbar` *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`a1fdc02`](https://github.com/SARDONYX-sard/dar-to-oar/commit/a1fdc023ca713413554655ecf24b1a0b6ea3f3c6) - **frontend**: implement notice position list *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`7ada442`](https://github.com/SARDONYX-sard/dar-to-oar/commit/7ada4429955c8a22d48fe241ea17f8d2b4d855ac) - **gui**: implement settings import/export system *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`6848d5b`](https://github.com/SARDONYX-sard/dar-to-oar/commit/6848d5ba820485b110d5d2463d9831dff47f1429) - **gui**: avoid `writeTextFile` bug *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`3847839`](https://github.com/SARDONYX-sard/dar-to-oar/commit/38478393e7ab0e16834f4b3b70cc084efdb96d0d) - **locale**: add note *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`80138ac`](https://github.com/SARDONYX-sard/dar-to-oar/commit/80138acff1278a622a952d03fc5fc424bad0d2fb) - **gui-backend**: implement window state store system *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`5816653`](https://github.com/SARDONYX-sard/dar-to-oar/commit/58166535cf602a78ce9e741983fb5393caccc938) - **frontend**: use formatted json *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`58b69fe`](https://github.com/SARDONYX-sard/dar-to-oar/commit/58b69fe25e128d4feed1164615e3eaae3acb4dbc) - **frontend**: implement backup dialog *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`63c13cc`](https://github.com/SARDONYX-sard/dar-to-oar/commit/63c13cca1a3eaf291ea3d39dcbcb7e058db7ccea) - **frontend**: implement notice limit settings *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`213dd1a`](https://github.com/SARDONYX-sard/dar-to-oar/commit/213dd1aa47493e8dadd011931a4df269718d4ce3) - **frontend**: change `all clear` handler *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`07f3b51`](https://github.com/SARDONYX-sard/dar-to-oar/commit/07f3b51232e3c844334a99c2b8c262847d461f88) - **frontend**: add autoReload *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`985c7c0`](https://github.com/SARDONYX-sard/dar-to-oar/commit/985c7c080cdb3058ab4ad4384573d482023bd9f6) - **frontend-style**: add `indicator` color settings *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :bug: Bug Fixes +- [`243e497`](https://github.com/SARDONYX-sard/dar-to-oar/commit/243e497d573ab003083bb83c230bb71d3cd500bb) - **front-tauri**: fix progress bar not worked *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`4a7a048`](https://github.com/SARDONYX-sard/dar-to-oar/commit/4a7a0488ac7e691d5f20b6b8f2d793721a8330a6) - **locale**: fix errors in behavior description *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`e9e2dcf`](https://github.com/SARDONYX-sard/dar-to-oar/commit/e9e2dcff381613d5f06a6122b05eb3c83eb6ebde) - **front**: fix cache key *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`bf21a7b`](https://github.com/SARDONYX-sard/dar-to-oar/commit/bf21a7badfc62667b3841608593f528909e0b04f) - **front-form**: fix subcommand errors due to getting `old` values. *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`9510911`](https://github.com/SARDONYX-sard/dar-to-oar/commit/951091100f271873e10b06a5696c91ab210e0fb1) - **locale**: fix japanese statement *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`58a91f2`](https://github.com/SARDONYX-sard/dar-to-oar/commit/58a91f20916d33a8a8198617407e3e33b65f2bf7) - **front**: fix cache key *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :zap: Performance Improvements +- [`7460726`](https://github.com/SARDONYX-sard/dar-to-oar/commit/74607262e081288d07fc94f424b0731acad1a0a7) - **backend**: use `Small String Optimization` *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :recycle: Refactors +- [`e50c0aa`](https://github.com/SARDONYX-sard/dar-to-oar/commit/e50c0aa94433549900ce9a6cb3190bf0dfd80c0b) - **front**: separate callback *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`028c7f1`](https://github.com/SARDONYX-sard/dar-to-oar/commit/028c7f14c8b5b7096adbe37cd40109a255999e08) - **core**: change unnecessary code *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`419da2d`](https://github.com/SARDONYX-sard/dar-to-oar/commit/419da2d912dcfe9b3b81a69de7289601c3f66f1c) - **front**: rename provider *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`a9e0382`](https://github.com/SARDONYX-sard/dar-to-oar/commit/a9e038287b9cb4f595f286bce6b41afefee96ad2) - **frontend**: rename notice list *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`ba98e00`](https://github.com/SARDONYX-sard/dar-to-oar/commit/ba98e000cb12d45ef849ec401781eda5de4c967a) - **core**: apply lint fix *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`57d24d3`](https://github.com/SARDONYX-sard/dar-to-oar/commit/57d24d3d00054c4f8625cd27e77db9881fd52718) - **core**: apply lint fix *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`50b0570`](https://github.com/SARDONYX-sard/dar-to-oar/commit/50b0570196d590eeddba26195b462ebdd7f0b6b2) - **frontend**: rename tab's labels *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`e6ec0ee`](https://github.com/SARDONYX-sard/dar-to-oar/commit/e6ec0ee3888d6b7a7082a8bc243b1949b19ebec4) - **frontend**: change label in lists *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`a17d5d0`](https://github.com/SARDONYX-sard/dar-to-oar/commit/a17d5d07be08f67d62df75aa44192d553762f6c9) - **frontend**: use `localStorage` wrapper *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`d323347`](https://github.com/SARDONYX-sard/dar-to-oar/commit/d32334745ef9a8dfa7e5095cb517a4b44ae48f32) - **core**: change serde code *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :white_check_mark: Tests +- [`90d5614`](https://github.com/SARDONYX-sard/dar-to-oar/commit/90d561453dc0b928fea54d830279dc283b5f509c) - **front**: remove `remove-oar` test *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`88ccab9`](https://github.com/SARDONYX-sard/dar-to-oar/commit/88ccab953eae21a525ecc180145d180f7575eea3) - **front**: remove unused test *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :wrench: Chores +- [`e767366`](https://github.com/SARDONYX-sard/dar-to-oar/commit/e767366b6c31c136566c652696f5da25e970585a) - **core**: remove unnecessary comment *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`73a85fe`](https://github.com/SARDONYX-sard/dar-to-oar/commit/73a85feb8b76c9cbb3c7b9a2f792df4fd9cc36bd) - **sample**: change sample code *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`5e5f39f`](https://github.com/SARDONYX-sard/dar-to-oar/commit/5e5f39f52579fc86597c5399fb877b1739415b75) - **front**: remove unnecessary files *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`86f61e1`](https://github.com/SARDONYX-sard/dar-to-oar/commit/86f61e122d82df19869ea006cb8757abf6a20f59) - **locale**: change to `Notice Position` *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`673d21d`](https://github.com/SARDONYX-sard/dar-to-oar/commit/673d21df2db47a2e5423df2347be64eca74dadd9) - **core**: change macro to private *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`b70e373`](https://github.com/SARDONYX-sard/dar-to-oar/commit/b70e3733d5ef1aa0a3c2abdc83effdd6eeb5db20) - **vscode**: add `--cache` in eslint *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`bd3a119`](https://github.com/SARDONYX-sard/dar-to-oar/commit/bd3a11943287e347d8ee2c6ed7bdea7fb28ea58c) - **core**: merge previous lint settings *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`e433123`](https://github.com/SARDONYX-sard/dar-to-oar/commit/e433123f4014baad530499ee5d92a81add2cce95) - **cargo**: add readme meta *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`3e73da9`](https://github.com/SARDONYX-sard/dar-to-oar/commit/3e73da939b86454a873e10fa7bda2f57e304970e) - **gui-backend**: remove unnecessary commands *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`f321117`](https://github.com/SARDONYX-sard/dar-to-oar/commit/f3211178e14b679e46f15a4f0757a1ccdc2595a7) - **vscode**: correct eslint settings *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`ebd24df`](https://github.com/SARDONYX-sard/dar-to-oar/commit/ebd24dfcff1b9e5d3dd1f7a083a338b755da16a8) - **script**: add danger samples *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`1df3383`](https://github.com/SARDONYX-sard/dar-to-oar/commit/1df33832fb518cbf0b164398eaa6308f66d99cd0) - add sample `g_dar2oar_settings.json` *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`dad4d66`](https://github.com/SARDONYX-sard/dar-to-oar/commit/dad4d663cdffc088ad4d5ca899ab812c32570e5e) - change samples *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`51b8680`](https://github.com/SARDONYX-sard/dar-to-oar/commit/51b86802bfa777ffa3006c8e029c803c27da8f11) - **samples**: change samples *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`61a84f9`](https://github.com/SARDONYX-sard/dar-to-oar/commit/61a84f904d0d898b5ea1e40b81ca84e68ada127f) - **samples**: fix docs *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + + +## [0.5.0] - 2024-01-20 +### :boom: BREAKING CHANGES +- due to [`1f1433e`](https://github.com/SARDONYX-sard/dar-to-oar/commit/1f1433e22b863d490f8eac1842786721f316caf4) - change from `dist` to `dst` *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))*: + + dist -> dst + dist == distribution + dst == destination + + +### :sparkles: New Features +- [`3458226`](https://github.com/SARDONYX-sard/dar-to-oar/commit/3458226f5d9fcbb2710bd2171a75751f60a29dd2) - **cli-subcommand**: change `convert` arg name *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`ac7b373`](https://github.com/SARDONYX-sard/dar-to-oar/commit/ac7b373c493e79a261a2bcd125243e67cca4b711) - **core**: change behavior when an invalid DAR path is passed *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :bug: Bug Fixes +- [`df60d47`](https://github.com/SARDONYX-sard/dar-to-oar/commit/df60d47dcfbe373640026760c7e339c6a6fbf4c5) - **front-lang**: fix a path error when canceling *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`deb2ac6`](https://github.com/SARDONYX-sard/dar-to-oar/commit/deb2ac6d6fa03d39b8c93a256ba8d7929c7943ce) - **front**: fix test *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`1f1433e`](https://github.com/SARDONYX-sard/dar-to-oar/commit/1f1433e22b863d490f8eac1842786721f316caf4) - **word**: change from `dist` to `dst` *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`890a71e`](https://github.com/SARDONYX-sard/dar-to-oar/commit/890a71e75c2cf11b6fc4115ee16850f100c1c1d8) - **i18n**: change `dist` word *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :white_check_mark: Tests +- [`ca532fd`](https://github.com/SARDONYX-sard/dar-to-oar/commit/ca532fd93c9865a05ec1ca6bee5f04fdc06773d2) - **core**: remove `.mohidden` *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + + +## [0.4.1] - 2024-01-19 +### :sparkles: New Features +- [`7b3d215`](https://github.com/SARDONYX-sard/dar-to-oar/commit/7b3d215756b11b77c60352c94f5a7306ac047468) - **core**: make logs easier to read *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`6c00e4c`](https://github.com/SARDONYX-sard/dar-to-oar/commit/6c00e4ce0a6fe54ae11ea43aa6c81f09bf6d15fa) - **lang**: implement `import language button` *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`3767e22`](https://github.com/SARDONYX-sard/dar-to-oar/commit/3767e229bb680d813c055178948050ab9f56bbef) - **core**: enable strict checking of conditional statements *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`1ea96a2`](https://github.com/SARDONYX-sard/dar-to-oar/commit/1ea96a26bc93efc736367367497bdbb5a4295cb0) - **core**: change not to panic *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :bug: Bug Fixes +- [`b37b29f`](https://github.com/SARDONYX-sard/dar-to-oar/commit/b37b29f82d98f59ab42304c0d21c707100d78602) - **cli**: avoid double write error log *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`809dd4c`](https://github.com/SARDONYX-sard/dar-to-oar/commit/809dd4cdfeb876028cf9bf611bcb9fff5022baac) - **front-style**: more clear background color *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`cecbf88`](https://github.com/SARDONYX-sard/dar-to-oar/commit/cecbf885351e7b73f5479377111d3e43a9e8fa44) - **locale-ja**: fix `平行` to `並行` in ja-Jp.json *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`69bd3ae`](https://github.com/SARDONYX-sard/dar-to-oar/commit/69bd3aec6059e6ecae09098b64b4631b1aafbb5d) - **core**: fix `IsEquippedShout` forgetting OAR parse *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :recycle: Refactors +- [`7935810`](https://github.com/SARDONYX-sard/dar-to-oar/commit/7935810fe414016b86302952c18d69d5f0fd3843) - **core-macro**: change macros to private *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :white_check_mark: Tests +- [`929803a`](https://github.com/SARDONYX-sard/dar-to-oar/commit/929803a07ed9df5887a296697989d968cf61b511) - **core**: fix test name *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :wrench: Chores +- [`9bdb16a`](https://github.com/SARDONYX-sard/dar-to-oar/commit/9bdb16a2a6bb791263f9f0fd506ebddbea1e20de) - **vscode**: add default i18n settings *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`0df0c79`](https://github.com/SARDONYX-sard/dar-to-oar/commit/0df0c79d101a3ea739ac3b755f89d4bf9ecef5ce) - **vscode**: add recommend extensions *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`8542bf6`](https://github.com/SARDONYX-sard/dar-to-oar/commit/8542bf6e9d2afedf433056bcffcd980bfce00c9b) - **sample**: change i18n js sample *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + + +## [0.4.0] - 2024-01-16 +### :boom: BREAKING CHANGES +- due to [`026c438`](https://github.com/SARDONYX-sard/dar-to-oar/commit/026c4384992218560dc95c0be160855a8d66df2b) - implement cli sub commands *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))*: + + Subcommands have been added, so command usage has changed. + - Implement `unhide-dar` command + - Implement `remove-oar` command + - Color CLI(Implemented by downgrading clap to v3.) + + +### :sparkles: New Features +- [`805b3da`](https://github.com/SARDONYX-sard/dar-to-oar/commit/805b3dafa8bc41528731a809380554fa9bd14e81) - **translation**: add translation items *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`29d567c`](https://github.com/SARDONYX-sard/dar-to-oar/commit/29d567c844a883d196b8b34efd43b35137828127) - **core**: add oar check *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`5ff1c7b`](https://github.com/SARDONYX-sard/dar-to-oar/commit/5ff1c7bb730ecb23971b83a31c91c46fe7cbfe86) - **backend**: add mapping path error *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`2586523`](https://github.com/SARDONYX-sard/dar-to-oar/commit/25865236ddeb69403842e12b2a3e173d7c54c181) - **frontend**: implement `open log dir` button *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`67feb7f`](https://github.com/SARDONYX-sard/dar-to-oar/commit/67feb7f05c9ede2d89402a611acf746edd0d7d5d) - **frontend**: implement custom translation system *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`026c438`](https://github.com/SARDONYX-sard/dar-to-oar/commit/026c4384992218560dc95c0be160855a8d66df2b) - **cli**: implement cli sub commands *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`c3b6d0e`](https://github.com/SARDONYX-sard/dar-to-oar/commit/c3b6d0e079edab48215ee79ffe09d7debe512d7a) - **frontend**: support autofill color *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`7e06480`](https://github.com/SARDONYX-sard/dar-to-oar/commit/7e06480230bb84f6bdf5b502336384155b325fa4) - **frontend**: add `preset4` *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`66d6c88`](https://github.com/SARDONYX-sard/dar-to-oar/commit/66d6c88da38a6bdc9b6f6b0379b7b3f0dbf297d2) - **tauri**: change GUI height for i18n *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :bug: Bug Fixes +- [`1c77b35`](https://github.com/SARDONYX-sard/dar-to-oar/commit/1c77b353103e80183ed7c883ceabc921cf0f6eee) - **core**: fix unnecessarily strict Ordering *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`620ae7d`](https://github.com/SARDONYX-sard/dar-to-oar/commit/620ae7d33bf80abb9d5e728eb496d64133c58436) - **support_cmd**: fix sub cmd *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`ec853bb`](https://github.com/SARDONYX-sard/dar-to-oar/commit/ec853bb951a422185e81e0d1f693892200c86be6) - **core-path**: fix path test *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`6639048`](https://github.com/SARDONYX-sard/dar-to-oar/commit/663904832ab779f8c8357fcca4cd3e679ed0712d) - **frontend**: fix jump to link *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :recycle: Refactors +- [`aad536a`](https://github.com/SARDONYX-sard/dar-to-oar/commit/aad536ae531ac6ad616c6e84df634b47e91684a6) - **core**: organize by linter *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :white_check_mark: Tests +- [`aeaa96a`](https://github.com/SARDONYX-sard/dar-to-oar/commit/aeaa96a341df14b67e26b63fe492af6011510385) - **frontend**: fix test *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`31ae7ac`](https://github.com/SARDONYX-sard/dar-to-oar/commit/31ae7acf8cbdecec8751359a19518e1105485176) - **e2e**: add e2e test files & change path *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :wrench: Chores +- [`21202eb`](https://github.com/SARDONYX-sard/dar-to-oar/commit/21202ebf49872cbc5ec7af15a5d85f8adcae14ba) - **vscode**: migrate new setting way *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`d933fdb`](https://github.com/SARDONYX-sard/dar-to-oar/commit/d933fdbae60e71f098d9759fd537a583c3a1c246) - **locale**: change locale help order *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`4c6450c`](https://github.com/SARDONYX-sard/dar-to-oar/commit/4c6450c66f2fe5bd1ed4e6e67f11e498145f15c1) - **samples**: add css sample *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`e4262f4`](https://github.com/SARDONYX-sard/dar-to-oar/commit/e4262f492618ea6ecbacd67386550cbfbc1d5a43) - **locale-en-US**: change locale explain *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`a358475`](https://github.com/SARDONYX-sard/dar-to-oar/commit/a3584757c1340f43b3b49997465c317350657ddf) - rename test/data docs *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`f9bbcb7`](https://github.com/SARDONYX-sard/dar-to-oar/commit/f9bbcb7b1f3a5c4adaf73ee7cd69a5958ca14319) - **sample**: change sample script *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`3ef5b33`](https://github.com/SARDONYX-sard/dar-to-oar/commit/3ef5b33c52f0c2e98ae1765f8833342c45980da0) - **sample**: add preset4 i18n *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + + +## [0.3.0] - 2024-01-07 +### :sparkles: New Features +- [`3f9fcb4`](https://github.com/SARDONYX-sard/dar-to-oar/commit/3f9fcb4a3970218ba81bc67f540bef0b2078f74f) - **core-converter**: change error *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`ad640b7`](https://github.com/SARDONYX-sard/dar-to-oar/commit/ad640b793852ecc3292dc6cc5dfce22d9e18994b) - **cli**: add elapsed time *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`a48c613`](https://github.com/SARDONYX-sard/dar-to-oar/commit/a48c6130806ab7d18ba48853081c90af1885ce60) - **core**: support ident only function call DAR syntax *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :bug: Bug Fixes +- [`646e9d8`](https://github.com/SARDONYX-sard/dar-to-oar/commit/646e9d8076d713769014eda7396d161e898ddcf1) - **front**: fix to show NaN *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`abf37d4`](https://github.com/SARDONYX-sard/dar-to-oar/commit/abf37d45f383df668d04e96c896c4af4e6559f4d) - **core**: fix non parsed remain comments *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`a6bfc90`](https://github.com/SARDONYX-sard/dar-to-oar/commit/a6bfc90a49908e49c4ea86133010b80d141a8bc2) - **core**: ignore remain but set warn *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`ae73f9a`](https://github.com/SARDONYX-sard/dar-to-oar/commit/ae73f9a73fd47795251c5e8ef231ee9f63d90a62) - **core**: support for the tail comment is complete *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`83a81fb`](https://github.com/SARDONYX-sard/dar-to-oar/commit/83a81fb3e6ac4527a09fe0769d86a9a9be35d2e0) - **core**: fix multi \n *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`3cf6cf5`](https://github.com/SARDONYX-sard/dar-to-oar/commit/3cf6cf57435e7b4fb44984388f3a28f254ee6029) - **front**: fix progress *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`3417ddb`](https://github.com/SARDONYX-sard/dar-to-oar/commit/3417ddbff452ccfc1b5e3d7d663e3cb3744244e6) - **backend**: fix false multithread mode *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :recycle: Refactors +- [`3eef3ab`](https://github.com/SARDONYX-sard/dar-to-oar/commit/3eef3ab6daeccd640cb2859e911a328623aeae5a) - **tauri**: into macros *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`47c5ab6`](https://github.com/SARDONYX-sard/dar-to-oar/commit/47c5ab67326973c0fde0b3cf5da80ceddbbd6754) - **core-test**: remove unnecessary atomic *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :white_check_mark: Tests +- [`3350239`](https://github.com/SARDONYX-sard/dar-to-oar/commit/335023922f731e06eb8534fc1426b49986a0bd08) - change test movement *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`5ed18aa`](https://github.com/SARDONYX-sard/dar-to-oar/commit/5ed18aacba5874adccd65b090ad56e968acf44b1) - **core**: Change to `FormID` for non prefix hex *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :wrench: Chores +- [`ca5306d`](https://github.com/SARDONYX-sard/dar-to-oar/commit/ca5306dee9e6adec66e48044e3060ec243b88c95) - **release-ci**: rename to `Node.js cache` *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`8f3ea14`](https://github.com/SARDONYX-sard/dar-to-oar/commit/8f3ea140f85b04ca67447f3cdba116bbe3a11701) - try debug style *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + + +## [0.2.3] - 2023-11-17 +### :sparkles: New Features +- [`8a3ffd4`](https://github.com/SARDONYX-sard/dar-to-oar/commit/8a3ffd47b6218f490f3e9435fe4fb32fcf4c108e) - **front-settings**: change to centering *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`2c6095b`](https://github.com/SARDONYX-sard/dar-to-oar/commit/2c6095bf7b2a47ed8181a6ba946851bdeae7ec3c) - **core-error**: change error handling in `parse_dar2oar` *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`90cd2a9`](https://github.com/SARDONYX-sard/dar-to-oar/commit/90cd2a905a9fe482b0e5d3b88f4c8486474ce131) - **translation**: add errMsg in tauri_cmd *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`7a216db`](https://github.com/SARDONYX-sard/dar-to-oar/commit/7a216db15c6c262fbd496efd71cf0f885050ca20) - **github-yml**: add versions *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :bug: Bug Fixes +- [`6107305`](https://github.com/SARDONYX-sard/dar-to-oar/commit/6107305165ba4d21f66e30ece3d92c1d91032d05) - **locale-ja**: fix translation *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`8f272b0`](https://github.com/SARDONYX-sard/dar-to-oar/commit/8f272b0df6938c2e548b39a8116d5f321190f955) - **tauri**: fix log rotation *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`6950905`](https://github.com/SARDONYX-sard/dar-to-oar/commit/6950905c8c8439313ddfb25165b249ea691bdf43) - **core**: fix uncovered remain error *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`ad5e9a5`](https://github.com/SARDONYX-sard/dar-to-oar/commit/ad5e9a5f17884d3a8215227ba700e9b5dcbadcae) - **ci-dev**: fix trigger *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`0f355a5`](https://github.com/SARDONYX-sard/dar-to-oar/commit/0f355a54526944f5b2019d9fdbda0a5af6c2c710) - **docs**: add feature *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`2f158c8`](https://github.com/SARDONYX-sard/dar-to-oar/commit/2f158c8025e0976cad450cebbdc21890c18c6422) - **docs**: remove invalid comma *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`8fd0b6d`](https://github.com/SARDONYX-sard/dar-to-oar/commit/8fd0b6d64f5fc1268463df74f753c4daade89ca2) - **front**: fix inconsistencies in notification design *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`e601651`](https://github.com/SARDONYX-sard/dar-to-oar/commit/e601651922a975347225c1cae8c268b4e0b27063) - **front**: fix error path & lint *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`f9619ea`](https://github.com/SARDONYX-sard/dar-to-oar/commit/f9619eaacd64ae43263c6b478df487e56d085131) - **npm**: fix command *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`12ceb19`](https://github.com/SARDONYX-sard/dar-to-oar/commit/12ceb1928561c018a29b7cdf6a71896a302aedb5) - **ci**: fix npm cache *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`37f03d9`](https://github.com/SARDONYX-sard/dar-to-oar/commit/37f03d943f0b4725178291b4aafe8e9603ddb34b) - **ci**: fix cond & add build test(CLI) *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`82296ec`](https://github.com/SARDONYX-sard/dar-to-oar/commit/82296ec729eadc0f753ed7ae5f50f4fa6ec5d013) - **ci**: add mkdir *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`b4be419`](https://github.com/SARDONYX-sard/dar-to-oar/commit/b4be419ae192ce7f86c864adb774e48954b553af) - **ci**: fix compress process *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`8676d2c`](https://github.com/SARDONYX-sard/dar-to-oar/commit/8676d2c683a0e0fd1594b2a1799cc4f30a1e4782) - **ci**: fix os branch *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`fe1705c`](https://github.com/SARDONYX-sard/dar-to-oar/commit/fe1705c3d62ee69311109f21da42fe8f874e079f) - **ci**: fix file path *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`9402d99`](https://github.com/SARDONYX-sard/dar-to-oar/commit/9402d99de1c526f50b3ba6d3c84cc732c46cf02a) - **ci**: fix path *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`0c223f2`](https://github.com/SARDONYX-sard/dar-to-oar/commit/0c223f23356f204fce521a8063e39c59e88ba62a) - **ci**: fix os name *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`fbf2808`](https://github.com/SARDONYX-sard/dar-to-oar/commit/fbf2808879bc52fb63ab27f4135ba794b06f46cb) - **ci**: fix cache path *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`6b58e63`](https://github.com/SARDONYX-sard/dar-to-oar/commit/6b58e633443bee56b3d9467574539ab2658bdf90) - **cargo**: fix repo url *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :zap: Performance Improvements +- [`66077b8`](https://github.com/SARDONYX-sard/dar-to-oar/commit/66077b869ce78bae3ef8054dd1d4afba403f7d62) - implement filter *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :recycle: Refactors +- [`09e3e7b`](https://github.com/SARDONYX-sard/dar-to-oar/commit/09e3e7ba6c8e473b415fd2c659803d7419da6070) - **tauri**: change to macro *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`67ea522`](https://github.com/SARDONYX-sard/dar-to-oar/commit/67ea522d3f2f8be2261c68ac1efb67249956e134) - **core-logger**: organize log msg *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`c6a1d36`](https://github.com/SARDONYX-sard/dar-to-oar/commit/c6a1d363b16ff3a0a087aab180d6bd2a333907fd) - **frontend**: add `as const` *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`6b26f0f`](https://github.com/SARDONYX-sard/dar-to-oar/commit/6b26f0f443172476b16eba29224eaf6dbab3818e) - **core**: non use unwrap *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`6910a8d`](https://github.com/SARDONYX-sard/dar-to-oar/commit/6910a8deefcc708da7e59edd9cadae76ab69115e) - **front**: refactor by prettier & me *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :white_check_mark: Tests +- [`db71093`](https://github.com/SARDONYX-sard/dar-to-oar/commit/db710934414d10b1fea69e7cf883fc39cb556fee) - **front**: add lint & test *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`9ee01ec`](https://github.com/SARDONYX-sard/dar-to-oar/commit/9ee01ece28c8aa188505b9995e82b9884518af31) - **bench**: fix bench runner *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :wrench: Chores +- [`0bc56f5`](https://github.com/SARDONYX-sard/dar-to-oar/commit/0bc56f5756547363fe33935a89cc5388a396d588) - **ci**: rename cache runner name *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`4c1c877`](https://github.com/SARDONYX-sard/dar-to-oar/commit/4c1c87739de6ad31838c4f1e9cf3619498ea660a) - **ci**: rename build path *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + + +## [0.2.2] - 2023-11-05 +### :bug: Bug Fixes +- [`9fb7259`](https://github.com/SARDONYX-sard/dar-to-oar/commit/9fb7259e793e247fd2c250f5eb09969329e09933) - **front**: fix trans key *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`765fa8f`](https://github.com/SARDONYX-sard/dar-to-oar/commit/765fa8f7bf4046e4b7358ab5c0dec15d725f7852) - **front**: fix trans `convert-form-mapping-1st-label` *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`5f6f04a`](https://github.com/SARDONYX-sard/dar-to-oar/commit/5f6f04a5463818dd8c114464b0dada09b3addc07) - **front**: fix localization *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`460eaa2`](https://github.com/SARDONYX-sard/dar-to-oar/commit/460eaa21d7cbe9a5b86605e7139e62a1bbaf976b) - **core**: correct the forgetting to add `negated` *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :recycle: Refactors +- [`0957ea1`](https://github.com/SARDONYX-sard/dar-to-oar/commit/0957ea1db0f07de56a898c43e0dfab698fc0d81a) - **front-form**: separate code *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`58be2dd`](https://github.com/SARDONYX-sard/dar-to-oar/commit/58be2dd8c9826fa80056fa46291e469c131f6c13) - **locale**: rename by BCP-47 standard *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + + +## [0.2.1] - 2023-11-05 +### :bug: Bug Fixes +- [`6e38434`](https://github.com/SARDONYX-sard/dar-to-oar/commit/6e38434bd88705932de9a0234ff96aa79919d54d) - **front**: fix trans key *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`f4e622f`](https://github.com/SARDONYX-sard/dar-to-oar/commit/f4e622fdcbb6c327e809d4493a1b5eafeaa7b944) - **front**: add default *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`a5333b4`](https://github.com/SARDONYX-sard/dar-to-oar/commit/a5333b405ebf2f74af0c50a7ed338828aef5a349) - **front**: fix display error *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + + +## [0.2.0] - 2023-11-05 +### :sparkles: New Features +- [`84cdfb2`](https://github.com/SARDONYX-sard/dar-to-oar/commit/84cdfb21136671f8aa49cbd8f6e2d479ea783485) - **front**: support miniSize monitor *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`4f8c71e`](https://github.com/SARDONYX-sard/dar-to-oar/commit/4f8c71e5677b712abb6089534002ffb40d6bbc64) - **core**: accept non-numeric PRIORITY dir names *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`c7ded3d`](https://github.com/SARDONYX-sard/dar-to-oar/commit/c7ded3dcbf89125a46674506366787aac85ab1e7) - add mpsc channel mode *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`20d645a`](https://github.com/SARDONYX-sard/dar-to-oar/commit/20d645a9159cf871e9c6c2ad887877e85ced625e) - change sender to async fn *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`5ed6322`](https://github.com/SARDONYX-sard/dar-to-oar/commit/5ed63229968b3784e4a071c3ed5f8aa64dcb2733) - **tauri**: separate logLevel fn *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`1b23e2c`](https://github.com/SARDONYX-sard/dar-to-oar/commit/1b23e2caf0ae6ee68f6a1d6ba98bef70a1d6268e) - **gui**: implement progress-bar *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`8ccbc8f`](https://github.com/SARDONYX-sard/dar-to-oar/commit/8ccbc8f1fc89f575c4afe1669a29f13552f82342) - **tauri**: implement rotation gui logger *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`7e0cd6f`](https://github.com/SARDONYX-sard/dar-to-oar/commit/7e0cd6fdb9221e670b7a0585c559dd1f27a1d137) - **front**: implement i18n system *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`fe897c7`](https://github.com/SARDONYX-sard/dar-to-oar/commit/fe897c7298c96ddecdec2f18a68a0bd97aa79101) - **front**: add i18n data *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :bug: Bug Fixes +- [`09ef816`](https://github.com/SARDONYX-sard/dar-to-oar/commit/09ef816ead2e51245e4598612489d28b85938001) - **core**: fix remover condition *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`844d8d7`](https://github.com/SARDONYX-sard/dar-to-oar/commit/844d8d73786ae86e15bae7f0598743fb2abe74be) - **core**: fix test path *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :zap: Performance Improvements +- [`1bd6d24`](https://github.com/SARDONYX-sard/dar-to-oar/commit/1bd6d242df4d016741904899f16fc5fd4244ae2b) - use async *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :recycle: Refactors +- [`9917ebd`](https://github.com/SARDONYX-sard/dar-to-oar/commit/9917ebdb51e9c276e113fb4683c7a24812dcafcd) - **cli**: refactor macro *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`b7e0461`](https://github.com/SARDONYX-sard/dar-to-oar/commit/b7e046185fb1f9c916acd0bba218ff1138488085) - **backend**: refactor imports *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`3a429f0`](https://github.com/SARDONYX-sard/dar-to-oar/commit/3a429f03429e08ccd75c645f23eaf97d41ca8c69) - **core**: remove unnecessary `clone` *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`edd2a4d`](https://github.com/SARDONYX-sard/dar-to-oar/commit/edd2a4d60e528cc04005f3bf2eab99baa36c2da9) - **tauri**: remove unnecessary field `show_progress` *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`bb25909`](https://github.com/SARDONYX-sard/dar-to-oar/commit/bb259099e0294b8f324ba0811363b5ee7db66b91) - **core**: change log level *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`d20c03a`](https://github.com/SARDONYX-sard/dar-to-oar/commit/d20c03a9e3e130b3a0f8473a3f82ef21cba29710) - **core**: change log level *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`9e6edb7`](https://github.com/SARDONYX-sard/dar-to-oar/commit/9e6edb74738e194e5c3650a6c49092d8dcf52475) - **front**: refactor `StyleList` *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`1651d43`](https://github.com/SARDONYX-sard/dar-to-oar/commit/1651d43663b9e716bfcb638692e112d6546f5ba3) - **front**: refactor path *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`1535e9c`](https://github.com/SARDONYX-sard/dar-to-oar/commit/1535e9cf66c237527dd4996d17d82995175a7f7d) - **front**: separate component *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :white_check_mark: Tests +- [`77f216b`](https://github.com/SARDONYX-sard/dar-to-oar/commit/77f216b4a713d7e55960e352d0683b956142aae7) - **core**: add ignore *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + + +## [0.1.6] - 2023-10-27 +### :sparkles: New Features +- [`b42d5ed`](https://github.com/SARDONYX-sard/dar-to-oar/commit/b42d5ed9c4bc297e180f6fe88139bb1268d8e107) - **front**: add icon & change msg *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :bug: Bug Fixes +- [`15f6c9e`](https://github.com/SARDONYX-sard/dar-to-oar/commit/15f6c9e183cbca864b24b8441b08252054285bed) - **ci**: change bot email *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`bc6425f`](https://github.com/SARDONYX-sard/dar-to-oar/commit/bc6425f00e577c3360fe64ae0187dfb4a00e676c) - **front**: add `overflowX` *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`d842b6b`](https://github.com/SARDONYX-sard/dar-to-oar/commit/d842b6b704631ee0a24f265671eb01e68d5e8036) - **core**: wrapping PluginValue in "form" *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`68e62d4`](https://github.com/SARDONYX-sard/dar-to-oar/commit/68e62d46b6384b798a4a93eb0a27c63a9bcff8ad) - **ci**: fix commit name *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :recycle: Refactors +- [`9bacf29`](https://github.com/SARDONYX-sard/dar-to-oar/commit/9bacf29d1e8758cf9fc57db0f874d273971346cb) - **core**: change assert order *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`5719787`](https://github.com/SARDONYX-sard/dar-to-oar/commit/5719787a455e8bb1a536f65bedfc861a39434905) - **front**: remove `overflowX` *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :wrench: Chores +- [`05928a0`](https://github.com/SARDONYX-sard/dar-to-oar/commit/05928a0b27e2a8e0ee5fa4a85f8b453f7063ed84) - **cargo**: organize item *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`687a385`](https://github.com/SARDONYX-sard/dar-to-oar/commit/687a38540421e5f44b530f66e5d2ec12547f6684) - update `CHANGELOG.md` *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + + +## [0.1.5] - 2023-10-13 +### :sparkles: New Features +- [`32c3150`](https://github.com/SARDONYX-sard/dar-to-oar/commit/32c31505303d1e04b52615c1f26e6147b09d3705) - **front**: add experimental customJS system *(commit by @SARDONYX-sard)* +- [`9e41f60`](https://github.com/SARDONYX-sard/dar-to-oar/commit/9e41f60e30e4b985b0ca0c8c87233c7277a907d9) - **core**: add sentinel in converter *(commit by @SARDONYX-sard)* +- [`ae852d0`](https://github.com/SARDONYX-sard/dar-to-oar/commit/ae852d0757a0a7515856bf09ffbabf2c9c9a0a6e) - implement DAR hinder & OAR remover *(commit by @SARDONYX-sard)* + +### :bug: Bug Fixes +- [`92563f2`](https://github.com/SARDONYX-sard/dar-to-oar/commit/92563f2c6ff50c4c6dc47bbd1a0d165874be242b) - **front**: fix design *(commit by @SARDONYX-sard)* +- [`330041f`](https://github.com/SARDONYX-sard/dar-to-oar/commit/330041f1de0b8bd0cb59fb063e5a2d622b822c0f) - **front**: fix problem with navigation focus not changing color after pressing `alt+->` *(commit by @SARDONYX-sard)* +- [`7231c65`](https://github.com/SARDONYX-sard/dar-to-oar/commit/7231c65515febf95637110203bb67421c4fb5bda) - **ci**: remove draft option in release *(commit by @SARDONYX-sard)* +- [`8af1069`](https://github.com/SARDONYX-sard/dar-to-oar/commit/8af1069a9c3d51724f53c8d74c63c764ddb61226) - **core-test**: revert to dyn read file *(commit by @SARDONYX-sard)* + +### :recycle: Refactors +- [`20c3c59`](https://github.com/SARDONYX-sard/dar-to-oar/commit/20c3c59109bc08dd90c8b180f7f817cab17e7acc) - **front**: remove unused import *(commit by @SARDONYX-sard)* + +### :wrench: Chores +- [`85542ea`](https://github.com/SARDONYX-sard/dar-to-oar/commit/85542ea5820c0810be1c7a4a3e42e22943cbf523) - **bug-report**: add version selectors *(commit by @SARDONYX-sard)* + +## [0.1.4] - 2023-10-09 +### :sparkles: New Features +- [`20a64c4`](https://github.com/SARDONYX-sard/dar-to-oar/commit/20a64c485b02956647b299e6ba30e5b36f02b8e6) - add dev build ci & new form help text in GUI *(PR [#8](https://github.com/SARDONYX-sard/dar-to-oar/pull/8) by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :wrench: Chores +- [`0b0af17`](https://github.com/SARDONYX-sard/dar-to-oar/commit/0b0af17571a05d4cd9d7512312e3b2bfa383338d) - add license files *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + + +## [0.1.3] - 2023-10-08 +### :sparkles: New Features +- [`7d3605c`](https://github.com/SARDONYX-sard/dar-to-oar/commit/7d3605c168310ebbc6f1d0d74382cbca1d7105f3) - impl parallel walk dir(but this is slow) *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`b94c041`](https://github.com/SARDONYX-sard/dar-to-oar/commit/b94c041f3120ffbcf9c83abfe64dc270759fb220) - **core**: returns Err instead of unwrap *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`dc1ede7`](https://github.com/SARDONYX-sard/dar-to-oar/commit/dc1ede732155e534b4c2a80050904ff77546ed0f) - **core-dar-syntax**: support empty `_condition.txt` *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`7f818b4`](https://github.com/SARDONYX-sard/dar-to-oar/commit/7f818b48a8e16dadb9926f53ac9a0a9d387bbd4a) - **frontend**: implement new GUI Design *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`1300486`](https://github.com/SARDONYX-sard/dar-to-oar/commit/1300486aad17b9fbc0d02affbced47efa4aae8f9) - **backend**: return the default converter to single *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`118d272`](https://github.com/SARDONYX-sard/dar-to-oar/commit/118d2729a128d5065934ec7307302577205701bf) - **front**: remove css hook *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`78cf04f`](https://github.com/SARDONYX-sard/dar-to-oar/commit/78cf04f6d37bef00274043e025aef4189df25077) - **front**: add parallel mode checkbox *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`711d412`](https://github.com/SARDONYX-sard/dar-to-oar/commit/711d4124206e404c6beca03f5f6fc9fad2c35245) - **cli**: change to bool arg *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :bug: Bug Fixes +- [`504b793`](https://github.com/SARDONYX-sard/dar-to-oar/commit/504b793551aac5ecbdefa7e54664565f8e554d95) - **ci**: fix tag name *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`b5370d0`](https://github.com/SARDONYX-sard/dar-to-oar/commit/b5370d0e1782c446c010750fe26b1edc1c0d1d32) - **core**: support "0X" prefix & eof condition *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`3a10598`](https://github.com/SARDONYX-sard/dar-to-oar/commit/3a1059838e13781fb13e875432bdff88430ce6da) - **core**: add `IsActorValueLessThan` condition *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :recycle: Refactors +- [`4d55fd6`](https://github.com/SARDONYX-sard/dar-to-oar/commit/4d55fd60f9be8fdc5763b4d2556fc64cb774359d) - **core-dar-syntax**: remove redundant stmt *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + + +## [0.1.2] - 2023-10-07 +### :zap: Performance Improvements +- [`3ab1c35`](https://github.com/SARDONYX-sard/dar-to-oar/commit/3ab1c35aa69a6c95fb548f747f69bafb98c5b63e) - **front**: implement `useDynStyle` hook *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :recycle: Refactors +- [`4d310e9`](https://github.com/SARDONYX-sard/dar-to-oar/commit/4d310e9df68b3c8f66194760db10da1515584800) - **front**: sort imports *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`d0aeca3`](https://github.com/SARDONYX-sard/dar-to-oar/commit/d0aeca324645c55633fdb91e30f38e2975aa74cd) - **front**: merge state to `useDynStyle` *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* +- [`564598c`](https://github.com/SARDONYX-sard/dar-to-oar/commit/564598cf06cdef10c0906339fb4d72dcfdb51330) - **tauri**: change to a simplified stmt *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + +### :wrench: Chores +- [`4490178`](https://github.com/SARDONYX-sard/dar-to-oar/commit/4490178193487fecb52d83605b47430b62924a28) - **github**: add feature request issue template *(commit by [@SARDONYX-sard](https://github.com/SARDONYX-sard))* + + +[0.1.2]: https://github.com/SARDONYX-sard/dar-to-oar/compare/0.1.1...0.1.2 +[0.1.3]: https://github.com/SARDONYX-sard/dar-to-oar/compare/0.1.2...0.1.3 +[0.1.4]: https://github.com/SARDONYX-sard/dar-to-oar/compare/0.1.3...0.1.4 +[0.1.5]: https://github.com/SARDONYX-sard/dar-to-oar/compare/0.1.4...0.1.5 + +[0.1.6]: https://github.com/SARDONYX-sard/dar-to-oar/compare/0.1.5...0.1.6 +[0.2.0]: https://github.com/SARDONYX-sard/dar-to-oar/compare/0.1.6...0.2.0 +[0.2.1]: https://github.com/SARDONYX-sard/dar-to-oar/compare/0.2.0...0.2.1 +[0.2.2]: https://github.com/SARDONYX-sard/dar-to-oar/compare/0.2.1...0.2.2 +[0.2.3]: https://github.com/SARDONYX-sard/dar-to-oar/compare/0.2.2...0.2.3 +[0.3.0]: https://github.com/SARDONYX-sard/dar-to-oar/compare/0.2.3...0.3.0 +[0.4.0]: https://github.com/SARDONYX-sard/dar-to-oar/compare/0.3.0...0.4.0 +[0.4.1]: https://github.com/SARDONYX-sard/dar-to-oar/compare/0.4.0...0.4.1 +[0.5.0]: https://github.com/SARDONYX-sard/dar-to-oar/compare/0.4.1...0.5.0 +[0.6.0]: https://github.com/SARDONYX-sard/dar-to-oar/compare/0.5.0...0.6.0 +[0.7.0]: https://github.com/SARDONYX-sard/dar-to-oar/compare/0.6.0...0.7.0 \ No newline at end of file diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index d7389cf..0000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,133 +0,0 @@ - -# Contributor Covenant Code of Conduct - -## Our Pledge - -We as members, contributors, and leaders pledge to make participation in our -community a harassment-free experience for everyone, regardless of age, body -size, visible or invisible disability, ethnicity, sex characteristics, gender -identity and expression, level of experience, education, socio-economic status, -nationality, personal appearance, race, caste, color, religion, or sexual identity -and orientation. - -We pledge to act and interact in ways that contribute to an open, welcoming, -diverse, inclusive, and healthy community. - -## Our Standards - -Examples of behavior that contributes to a positive environment for our -community include: - -* Demonstrating empathy and kindness toward other people -* Being respectful of differing opinions, viewpoints, and experiences -* Giving and gracefully accepting constructive feedback -* Accepting responsibility and apologizing to those affected by our mistakes, - and learning from the experience -* Focusing on what is best not just for us as individuals, but for the - overall community - -Examples of unacceptable behavior include: - -* The use of sexualized language or imagery, and sexual attention or - advances of any kind -* Trolling, insulting or derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or email - address, without their explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Enforcement Responsibilities - -Community leaders are responsible for clarifying and enforcing our standards of -acceptable behavior and will take appropriate and fair corrective action in -response to any behavior that they deem inappropriate, threatening, offensive, -or harmful. - -Community leaders have the right and responsibility to remove, edit, or reject -comments, commits, code, wiki edits, issues, and other contributions that are -not aligned to this Code of Conduct, and will communicate reasons for moderation -decisions when appropriate. - -## Scope - -This Code of Conduct applies within all community spaces, and also applies when -an individual is officially representing the community in public spaces. -Examples of representing our community include using an official e-mail address, -posting via an official social media account, or acting as an appointed -representative at an online or offline event. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported to the community leaders responsible for enforcement at -`SARDONYX-sard@users.noreply.github.com`. -All complaints will be reviewed and investigated promptly and fairly. - -All community leaders are obligated to respect the privacy and security of the -reporter of any incident. - -## Enforcement Guidelines - -Community leaders will follow these Community Impact Guidelines in determining -the consequences for any action they deem in violation of this Code of Conduct: - -### 1. Correction - -**Community Impact**: Use of inappropriate language or other behavior deemed -unprofessional or unwelcome in the community. - -**Consequence**: A private, written warning from community leaders, providing -clarity around the nature of the violation and an explanation of why the -behavior was inappropriate. A public apology may be requested. - -### 2. Warning - -**Community Impact**: A violation through a single incident or series -of actions. - -**Consequence**: A warning with consequences for continued behavior. No -interaction with the people involved, including unsolicited interaction with -those enforcing the Code of Conduct, for a specified period of time. This -includes avoiding interactions in community spaces as well as external channels -like social media. Violating these terms may lead to a temporary or -permanent ban. - -### 3. Temporary Ban - -**Community Impact**: A serious violation of community standards, including -sustained inappropriate behavior. - -**Consequence**: A temporary ban from any sort of interaction or public -communication with the community for a specified period of time. No public or -private interaction with the people involved, including unsolicited interaction -with those enforcing the Code of Conduct, is allowed during this period. -Violating these terms may lead to a permanent ban. - -### 4. Permanent Ban - -**Community Impact**: Demonstrating a pattern of violation of community -standards, including sustained inappropriate behavior, harassment of an -individual, or aggression toward or disparagement of classes of individuals. - -**Consequence**: A permanent ban from any sort of public interaction within -the community. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], -version 2.0, available at -[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0]. - -Community Impact Guidelines were inspired by -[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. - -For answers to common questions about this code of conduct, see the FAQ at -[https://www.contributor-covenant.org/faq][FAQ]. Translations are available -at [https://www.contributor-covenant.org/translations][translations]. - -[homepage]: https://www.contributor-covenant.org -[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html -[Mozilla CoC]: https://github.com/mozilla/diversity -[FAQ]: https://www.contributor-covenant.org/faq -[translations]: https://www.contributor-covenant.org/translations diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 281f9ba..0000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,198 +0,0 @@ -# Guidelines for contribution - -## Table of Contents - -- [Guidelines for contribution](#guidelines-for-contribution) - - [Table of Contents](#table-of-contents) - - [Language](#language) - - [Git branch flow](#git-branch-flow) - - [Git commit message conventions](#git-commit-message-conventions) - - [``](#type) - - [`[optional scope]`](#optional-scope) - - [``](#description) - - [`[optional body]`](#optional-body) - - [`[optional footer]`](#optional-footer) - - [About breaking changes](#about-breaking-changes) - -## Language - -Git branch names, commit messages, and GitHub pull requests must be written in English so that developers around the world can read them. - -## Git branch flow - -- The [GitHub Flow](http://scottchacon.com/2011/08/31/github-flow.html) is used for the development of this project. - -- Anything in the `main` branch is deployable. - -- To work on something new, you create a branch and add `feature/` as a prefix to its name. - -- The branch name should start with a verb and be as concise and clear as possible. - -```bash -# Example -feature/implement-xxx -feature/support-xxx-for-xxx -feature/fix-xxx-bugs -``` - -See here for more details. -[GitHub Flow - Scott Chacon](http://scottchacon.com/2011/08/31/github-flow.html) - -## Git commit message conventions - -The commit format follows [Conventional Commits](https://www.conventionalcommits.org/). -Here's an overview - -```bash -# Format. -[optional scope]: - -[optional body]. - -[optional footer]. -``` - -### `` - -There is only one purpose for a commit, and that is to add the following commit type to the beginning of the first line of the commit message Add the message. - -| `` | usage | -| :--------: | :---------------------------------------------------------------------------------------------------- | -| `feat` | new feature | -| `fix` | bug fix | -| `docs` | changes to documentation only | -| `style` | changes that do not affect the meaning of the code (whitespace, formatting, missing semicolons, etc.) | -| `refactor` | code changes that do not fix bugs and do not add functionality | -| `perf` | code changes that improve performance | -| `test` | add missing tests or fix existing tests | -| `build` | changes that affect the build system or external dependencies (scope examples: gulp, brocooli, npm) | -| `ci` | changes to CI configuration files and scripts (scope examples: gulp, brocooli, npm) | -| `chore` | other changes that do not change src or test files | -| `revert` | revert a previous commit | - -```bash -# Example -feat: allow provided config object to extend other configs - - -# Bad example -feat:Allow provided config object to extend other configs # No space between `` and ``. - - allow provided config object to extend other configs # No need for `<` and `>`. - -Feat: allow provided config object to extend other configs # `type` is uppercase - -chore allow provided config object to extend other configs # No colon `:` between `` and ``. -``` - -### `[optional scope]` - -`[optional scope]` - -```bash -feat(lang): add polish language -``` - -### `` - -- The `` (summary) is a summary of the changes. - -- It should be no more than 50 characters long, including the commit type. - -- Do not include the period. - -- Start with a lowercase letter. - -```bash -# Example -feat: allow provided config object to extend other configs. - - -# Bad example. -FEAT: feat: allow provided config object to extend other configs # `` is uppercase. - -feat: Implement sign up system. Because ... # Summary is too long. -``` - -### `[optional body]` - -- `[optional body]` is a description of what was changed in that commit. - -- It should be written with a single blank line between it and ``. - -- Do not include the period. - -- Start with a capital letter, and write one line at a time. - -```bash -# Example -fix: correct minor typos in code - -typos fixed - - -# Bad example 1: no blank line between lines 1 and 2. -fix: correct minor typos in code -see the issue for details on the typos fixed - - -# Bad example 2: period in code -fix: correct minor typos in code - -see the issue for details on the typos fixed. - - -# Bad example 3: not starting with a lowercase letter -fix: correct minor typos in code - -See the issue for details on the typos fixed -``` - -### `[optional footer]` - -- `[optional footer]` is the issue number for destructive or code changes. - -- It should be written with one blank line between it and the `[optional body]`. - -- Do not include the period. - -- Start with a capital letter, and write one line at a time. - -```bash -# Example -fix: prevent racing of requests - -Introduce a request id and a reference to latest request. -Dismiss incoming responses other than from latest request. - -Remove timeouts which were used to mitigate the racing issue but are obsolete now. -Remove timeouts which were used to mitigate the racing issue but are obsolete now. - -Reviewed-by: Z -Refs: #123 - - -# Example 2 -feat: allow provided config object to extend other configs - -BREAKING CHANGE: `extends` key in config file is now used for extending other config files -``` - -### About breaking changes - -- In the case of BreakingChange, you can do something like this. - -```bash -# To draw attention to a breaking change, add `!`. -feat!: send an email to the customer when a product is shipped - - -# Commit the message with scope and use `!` to draw attention to disruptive changes -feat(api)!: send an email to the customer when a product is shipped - - -# `!` and the `BREAKING CHANGE` footer to commit the message -chore!: drop support for Node 6 - -BREAKING CHANGE: use JavaScript features not available in Node 6. -``` diff --git a/src-tauri/Cargo.lock b/Cargo.lock similarity index 62% rename from src-tauri/Cargo.lock rename to Cargo.lock index 28543db..1cde87e 100644 --- a/src-tauri/Cargo.lock +++ b/Cargo.lock @@ -3,41 +3,50 @@ version = 3 [[package]] -name = "adler" -version = "1.0.2" +name = "addr2line" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +dependencies = [ + "gimli", +] [[package]] -name = "adler32" -version = "1.2.0" +name = "adler" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aho-corasick" -version = "0.7.18" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "alloc-no-stdlib" -version = "2.0.3" +version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35ef4730490ad1c4eae5c4325b2a95f521d023e5c885853ff7aca0a6a1631db3" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" [[package]] name = "alloc-stdlib" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697ed7edc0f1711de49ce108c541623a0af97c6c60b2f6e2b65229847ac843c2" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" dependencies = [ "alloc-no-stdlib", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -48,112 +57,159 @@ dependencies = [ ] [[package]] -name = "ansi_term" -version = "0.12.1" +name = "anyhow" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] -name = "anyhow" -version = "1.0.70" +name = "arrayvec" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "async-broadcast" -version = "0.4.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bbd92a9bd0e9c1298118ecf8a2f825e86b12c3ec9e411573e34aaf3a0c03cdd" +checksum = "20cd0e2e25ea8e5f7e9df04578dc6cf5c83577fd09b1a46aaf5c85e1c33f2a7e" dependencies = [ - "easy-parallel", "event-listener", + "event-listener-strategy", "futures-core", - "parking_lot 0.11.2", + "pin-project-lite", ] [[package]] name = "async-channel" -version = "1.7.1" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14485364214912d3b19cc3435dde4df66065127f05fa0d75c712f36f12c2f28" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" dependencies = [ "concurrent-queue", - "event-listener", + "event-listener-strategy", "futures-core", + "pin-project-lite", ] [[package]] name = "async-executor" -version = "1.4.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965" +checksum = "c8828ec6e544c02b0d6691d21ed9f9218d0384a82542855073c2a3f58304aaf0" dependencies = [ "async-task", "concurrent-queue", "fastrand", "futures-lite", - "once_cell", "slab", ] +[[package]] +name = "async-fs" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" +dependencies = [ + "async-lock", + "blocking", + "futures-lite", +] + [[package]] name = "async-io" -version = "1.10.0" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8121296a9f05be7f34aa4196b1747243b3b62e048bb7906f644f3fbfc490cf7" +checksum = "0d6baa8f0178795da0e71bc42c9e5d13261aac7ee549853162e66a241ba17964" dependencies = [ "async-lock", - "autocfg", + "cfg-if", "concurrent-queue", + "futures-io", "futures-lite", - "libc", - "log", "parking", "polling", + "rustix", "slab", - "socket2", - "waker-fn", - "winapi", + "tracing", + "windows-sys 0.52.0", ] [[package]] name = "async-lock" -version = "2.7.0" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +dependencies = [ + "event-listener", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-process" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa24f727524730b077666307f2734b4a1a1c57acb79193127dcc8914d5242dd7" +checksum = "f7eda79bbd84e29c2b308d1dc099d7de8dcc7035e48f4bf5dc4a531a44ff5e2a" dependencies = [ + "async-channel", + "async-io", + "async-lock", + "async-signal", + "async-task", + "blocking", + "cfg-if", "event-listener", + "futures-lite", + "rustix", + "tracing", + "windows-sys 0.52.0", ] [[package]] name = "async-recursion" -version = "0.3.2" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7d78656ba01f1b93024b7c3a0467f1608e4be67d725749fdcd7d2c7678fd7a2" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 1.0.95", + "syn 2.0.66", +] + +[[package]] +name = "async-signal" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "794f185324c2f00e771cd9f1ae8b5ac68be2ca7abb129a87afd6e86d228bc54d" +dependencies = [ + "async-io", + "async-lock", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix", + "signal-hook-registry", + "slab", + "windows-sys 0.52.0", ] [[package]] name = "async-task" -version = "4.4.0" +version = "4.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.68" +version = "0.1.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.66", ] [[package]] @@ -177,62 +233,64 @@ dependencies = [ "glib-sys", "gobject-sys", "libc", - "system-deps 6.0.2", + "system-deps 6.2.2", ] [[package]] -name = "attohttpc" -version = "0.22.0" +name = "atomic-waker" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fcf00bc6d5abb29b5f97e3c61a90b6d3caa12f3faf897d4a3e3607c050a35a7" -dependencies = [ - "flate2", - "http", - "log", - "native-tls", - "serde", - "serde_json", - "serde_urlencoded", - "url", -] +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "auto-launch" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5904a4d734f0235edf29aab320a14899f3e090446e594ff96508a6215f76f89c" +checksum = "1f012b8cc0c850f34117ec8252a44418f2e34a2cf501de89e29b241ae5f79471" dependencies = [ "dirs", "thiserror", - "winreg", + "winreg 0.10.1", ] [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "backtrace" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17c6a35df3749d2e8bb1b7b21a976d82b15548788d2735b9d82f329268f71a11" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] [[package]] name = "base64" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.0" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] -name = "bincode" -version = "1.3.3" +name = "base64" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bitflags" @@ -242,9 +300,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.0.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487f1e0fcbe47deb8b0574e646def1c903389d95241dd1bbcc6ce4a715dfc0c1" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "block" @@ -254,38 +312,70 @@ checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" [[package]] name = "block-buffer" -version = "0.10.2" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] [[package]] -name = "bluetooth-battery-monitor" +name = "blocking" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +dependencies = [ + "async-channel", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + +[[package]] +name = "bluetooth" +version = "0.3.0" +dependencies = [ + "chrono", + "num-derive", + "num-traits", + "parse-display", + "pretty_assertions", + "quick_tracing", + "serde", + "serde_json", + "serde_with", + "snafu", + "tracing", + "windows 0.58.0", +] + +[[package]] +name = "bluetooth_battery_monitor_gui" version = "0.3.0" dependencies = [ "anyhow", - "bincode", - "env_logger", - "log", + "bluetooth", + "chrono", "once_cell", + "pretty_assertions", "serde", "serde_json", "tauri", "tauri-build", "tauri-plugin-autostart", - "tauri-plugin-window-state", - "tokio", - "toml 0.7.3", - "windows 0.48.0", + "temp-dir", + "timer", + "tracing", + "tracing-appender", + "tracing-subscriber", ] [[package]] name = "brotli" -version = "3.3.4" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" +checksum = "d640d25bc63c50fb1f0b545ffd80207d2e10a4c965530809b40ba3386825c391" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -294,9 +384,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "2.3.2" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ad2d4653bf5ca36ae797b1f4bb4dbddb60ce49ca4aed8a2ce4829f60425b80" +checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -304,48 +394,43 @@ dependencies = [ [[package]] name = "bstr" -version = "0.2.17" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" dependencies = [ "memchr", + "serde", ] [[package]] name = "bumpalo" -version = "3.9.1" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.9.1" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdead85bdec19c194affaeeb670c0e41fe23de31459efd1c174d049269cf02cc" +checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" - -[[package]] -name = "cache-padded" -version = "1.3.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "981520c98f422fcc584dc1a95c334e6953900b9106bc47a9839b81790009eb21" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "cairo-rs" -version = "0.15.11" +version = "0.15.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62be3562254e90c1c6050a72aa638f6315593e98c5cdaba9017cedbabf0a5dee" +checksum = "c76ee391b03d35510d9fa917357c7f1855bd9a6659c95a1b392e33f49b3369bc" dependencies = [ "bitflags 1.3.2", "cairo-sys-rs", @@ -362,24 +447,24 @@ checksum = "3c55d429bef56ac9172d25fecb85dc8068307d17acd74b377866b7a1ef25d3c8" dependencies = [ "glib-sys", "libc", - "system-deps 6.0.2", + "system-deps 6.2.2", ] [[package]] name = "cargo_toml" -version = "0.13.3" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497049e9477329f8f6a559972ee42e117487d01d1e8c2cc9f836ea6fa23a9e1a" +checksum = "599aa35200ffff8f04c1925aa1acc92fa2e08874379ef42e210a80e527e60838" dependencies = [ "serde", - "toml 0.5.9", + "toml 0.7.8", ] [[package]] name = "cc" -version = "1.0.79" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" [[package]] name = "cesu8" @@ -409,11 +494,12 @@ dependencies = [ [[package]] name = "cfg-expr" -version = "0.10.3" +version = "0.15.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aacacf4d96c24b2ad6eb8ee6df040e4f27b0d0b39a5710c30091baa830485db" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" dependencies = [ "smallvec", + "target-lexicon", ] [[package]] @@ -422,24 +508,32 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + [[package]] name = "chrono" -version = "0.4.24" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ + "android-tzdata", "iana-time-zone", - "num-integer", + "js-sys", "num-traits", "serde", - "winapi", + "wasm-bindgen", + "windows-targets 0.52.6", ] [[package]] name = "cocoa" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f63902e9223530efb4e26ccd0cf55ec30d592d3b42e21a28defc42a9586e832" +checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a" dependencies = [ "bitflags 1.3.2", "block", @@ -453,15 +547,14 @@ dependencies = [ [[package]] name = "cocoa-foundation" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318" +checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" dependencies = [ "bitflags 1.3.2", "block", "core-foundation", "core-graphics-types", - "foreign-types", "libc", "objc", ] @@ -474,9 +567,9 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "combine" -version = "4.6.4" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a604e93b79d1808327a6fca85a6f2d69de66461e7620f5a4cbf5fb4d1d7c948" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" dependencies = [ "bytes", "memchr", @@ -484,11 +577,11 @@ dependencies = [ [[package]] name = "concurrent-queue" -version = "1.2.4" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af4780a44ab5696ea9e28294517f1fffb421a83a25af521333c838635509db9c" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ - "cache-padded", + "crossbeam-utils", ] [[package]] @@ -499,9 +592,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "core-foundation" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -509,9 +602,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.3" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "core-graphics" @@ -528,59 +621,72 @@ dependencies = [ [[package]] name = "core-graphics-types" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" dependencies = [ "bitflags 1.3.2", "core-foundation", - "foreign-types", "libc", ] [[package]] name = "cpufeatures" -version = "0.2.2" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-channel" -version = "0.5.4" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] -name = "crossbeam-utils" -version = "0.8.8" +name = "crossbeam-deque" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", - "lazy_static", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", ] +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + [[package]] name = "crypto-common" -version = "0.1.3" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", "typenum", @@ -600,40 +706,34 @@ dependencies = [ "proc-macro2", "quote", "smallvec", - "syn 1.0.95", + "syn 1.0.109", ] [[package]] name = "cssparser-macros" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfae75de57f2b2e85e8768c3ea840fd159c8f33e2b6522c7835b7abac81be16e" +checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 1.0.95", + "syn 2.0.66", ] [[package]] name = "ctor" -version = "0.1.22" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f877be4f7c9f246b183111634f75baa039715e3f46ce860677d3b19a69fb229c" +checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f" dependencies = [ "quote", - "syn 1.0.95", + "syn 2.0.66", ] -[[package]] -name = "cty" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" - [[package]] name = "darling" -version = "0.20.1" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944" +checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" dependencies = [ "darling_core", "darling_macro", @@ -641,47 +741,91 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.1" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb" +checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "strsim", - "syn 2.0.16", + "strsim 0.11.1", + "syn 2.0.66", ] [[package]] name = "darling_macro" -version = "0.20.1" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" +checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ "darling_core", "quote", - "syn 2.0.16", + "syn 2.0.66", ] [[package]] -name = "deflate" -version = "1.0.0" +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "deluxe" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c86f7e25f518f4b81808a2cf1c50996a61f5c2eb394b2393bd87f2a4780a432f" +checksum = "8ed332aaf752b459088acf3dd4eca323e3ef4b83c70a84ca48fb0ec5305f1488" dependencies = [ - "adler32", + "deluxe-core", + "deluxe-macros", + "once_cell", + "proc-macro2", + "syn 2.0.66", ] [[package]] -name = "derivative" -version = "2.2.0" +name = "deluxe-core" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddada51c8576df9d6a8450c351ff63042b092c9458b8ac7d20f89cbd0ffd313" +dependencies = [ + "arrayvec", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 2.0.66", +] + +[[package]] +name = "deluxe-macros" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +checksum = "f87546d9c837f0b7557e47b8bd6eae52c3c223141b76aa233c345c9ab41d9117" dependencies = [ + "deluxe-core", + "heck 0.4.1", + "if_chain", + "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 1.0.95", + "syn 2.0.66", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", + "serde", ] [[package]] @@ -693,15 +837,21 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "rustc_version 0.4.0", - "syn 1.0.95", + "rustc_version", + "syn 1.0.109", ] +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + [[package]] name = "digest" -version = "0.10.3" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", "crypto-common", @@ -754,32 +904,51 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" +[[package]] +name = "displaydoc" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "dtoa" -version = "0.4.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" +checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" [[package]] name = "dtoa-short" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bde03329ae10e79ede66c9ce4dc930aa8599043b0743008548680f25b91502d6" +checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" dependencies = [ "dtoa", ] [[package]] name = "dunce" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bd4b30a6560bbd9b4620f4de34c3f14f60848e58a9b7216801afcb4c7b31c3c" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" [[package]] -name = "easy-parallel" -version = "3.3.0" +name = "embed-resource" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4604923390fcaf8b65a1e10b430cc34a3f87958a3b35ebea978b529d776e001" +checksum = "c6985554d0688b687c5cb73898a34fbe3ad6c24c58c238a4d91d5e840670ee9d" +dependencies = [ + "cc", + "memchr", + "rustc_version", + "toml 0.8.14", + "vswhom", + "winreg 0.52.0", +] [[package]] name = "embed_plist" @@ -789,18 +958,24 @@ checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" [[package]] name = "encoding_rs" -version = "0.8.31" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] +[[package]] +name = "endi" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf" + [[package]] name = "enumflags2" -version = "0.7.7" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c041f5090df68b32bcd905365fd51769c8b9d553fe87fde0b683534f10c01bd2" +checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" dependencies = [ "enumflags2_derive", "serde", @@ -808,95 +983,96 @@ dependencies = [ [[package]] name = "enumflags2_derive" -version = "0.7.7" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e9a1f9f7d83e59740248a6e14ecf93929ade55027844dfcea78beafccc15745" +checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.66", ] [[package]] -name = "env_logger" -version = "0.10.0" +name = "equivalent" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" -dependencies = [ - "humantime", - "is-terminal", - "log", - "regex", - "termcolor", -] +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.1" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ - "errno-dragonfly", "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] -name = "errno-dragonfly" -version = "0.1.2" +name = "event-listener" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" dependencies = [ - "cc", - "libc", + "concurrent-queue", + "parking", + "pin-project-lite", ] [[package]] -name = "event-listener" -version = "2.5.3" +name = "event-listener-strategy" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" +dependencies = [ + "event-listener", + "pin-project-lite", +] [[package]] name = "fastrand" -version = "1.7.0" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + +[[package]] +name = "fdeflate" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" dependencies = [ - "instant", + "simd-adler32", ] [[package]] name = "field-offset" -version = "0.3.4" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e1c54951450cbd39f3dbcf1005ac413b49487dabf18a720ad2383eccfeffb92" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" dependencies = [ - "memoffset", - "rustc_version 0.3.3", + "memoffset 0.9.1", + "rustc_version", ] [[package]] name = "filetime" -version = "0.2.16" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0408e2626025178a6a7f7ffc05a25bc47103229f19c113755de7bf63816290c" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if", "libc", - "redox_syscall", - "winapi", + "redox_syscall 0.4.1", + "windows-sys 0.52.0", ] [[package]] name = "flate2" -version = "1.0.23" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39522e96686d38f4bc984b9198e3a0613264abaebaff2c5c918bfa6b6da09af" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" dependencies = [ - "cfg-if", "crc32fast", - "libc", "miniz_oxide", ] @@ -923,11 +1099,10 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.0.1" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ - "matches", "percent-encoding", ] @@ -943,24 +1118,24 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.21" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.21" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.21" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -969,58 +1144,58 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.21" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-lite" -version = "1.13.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" dependencies = [ "fastrand", "futures-core", "futures-io", - "memchr", "parking", "pin-project-lite", - "waker-fn", ] [[package]] name = "futures-macro" -version = "0.3.21" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 1.0.95", + "syn 2.0.66", ] [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.21" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.21" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-core", + "futures-io", "futures-macro", "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", "slab", @@ -1074,7 +1249,7 @@ dependencies = [ "glib-sys", "gobject-sys", "libc", - "system-deps 6.0.2", + "system-deps 6.2.2", ] [[package]] @@ -1091,7 +1266,7 @@ dependencies = [ "libc", "pango-sys", "pkg-config", - "system-deps 6.0.2", + "system-deps 6.2.2", ] [[package]] @@ -1105,7 +1280,7 @@ dependencies = [ "gobject-sys", "libc", "pkg-config", - "system-deps 6.0.2", + "system-deps 6.2.2", ] [[package]] @@ -1117,28 +1292,28 @@ dependencies = [ "gdk-sys", "glib-sys", "libc", - "system-deps 6.0.2", + "system-deps 6.2.2", "x11", ] [[package]] name = "generator" -version = "0.7.0" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1d9279ca822891c1a4dae06d185612cf8fc6acfe5dff37781b41297811b12ee" +checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" dependencies = [ "cc", "libc", "log", "rustversion", - "winapi", + "windows 0.48.0", ] [[package]] name = "generic-array" -version = "0.14.5" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -1157,20 +1332,26 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.6" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", - "wasi 0.10.2+wasi-snapshot-preview1", + "wasi 0.11.0+wasi-snapshot-preview1", ] +[[package]] +name = "gimli" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" + [[package]] name = "gio" -version = "0.15.11" +version = "0.15.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f132be35e05d9662b9fa0fee3f349c6621f7782e0105917f4cc73c1bf47eceb" +checksum = "68fdbc90312d462781a395f7a16d96a2b379bb6ef8cd6310a2df272771c4283b" dependencies = [ "bitflags 1.3.2", "futures-channel", @@ -1192,15 +1373,15 @@ dependencies = [ "glib-sys", "gobject-sys", "libc", - "system-deps 6.0.2", + "system-deps 6.2.2", "winapi", ] [[package]] name = "glib" -version = "0.15.11" +version = "0.15.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd124026a2fa8c33a3d17a3fe59c103f2d9fa5bd92c19e029e037736729abeab" +checksum = "edb0306fbad0ab5428b0ca674a23893db909a98582969c9b537be4ced78c505d" dependencies = [ "bitflags 1.3.2", "futures-channel", @@ -1218,17 +1399,17 @@ dependencies = [ [[package]] name = "glib-macros" -version = "0.15.11" +version = "0.15.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25a68131a662b04931e71891fb14aaf65ee4b44d08e8abc10f49e77418c86c64" +checksum = "10c6ae9f6fa26f4fb2ac16b528d138d971ead56141de489f8111e259b9df3c4a" dependencies = [ "anyhow", - "heck 0.4.0", - "proc-macro-crate", + "heck 0.4.1", + "proc-macro-crate 1.3.1", "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.95", + "syn 1.0.109", ] [[package]] @@ -1238,26 +1419,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef4b192f8e65e9cf76cbf4ea71fa8e3be4a0e18ffe3d68b8da6836974cc5bad4" dependencies = [ "libc", - "system-deps 6.0.2", + "system-deps 6.2.2", ] [[package]] name = "glob" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "globset" -version = "0.4.8" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" dependencies = [ "aho-corasick", "bstr", - "fnv", "log", - "regex", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", ] [[package]] @@ -1268,7 +1449,7 @@ checksum = "0d57ce44246becd17153bd035ab4d32cfee096a657fc01f2231c9278378d1e0a" dependencies = [ "glib-sys", "libc", - "system-deps 6.0.2", + "system-deps 6.2.2", ] [[package]] @@ -1309,21 +1490,21 @@ dependencies = [ "gobject-sys", "libc", "pango-sys", - "system-deps 6.0.2", + "system-deps 6.2.2", ] [[package]] name = "gtk3-macros" -version = "0.15.4" +version = "0.15.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24f518afe90c23fba585b2d7697856f9e6a7bbc62f65588035e66f6afb01a2e9" +checksum = "684c0456c086e8e7e9af73ec5b84e35938df394712054550e81558d21c44ab0d" dependencies = [ "anyhow", - "proc-macro-crate", + "proc-macro-crate 1.3.1", "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.95", + "syn 1.0.109", ] [[package]] @@ -1332,6 +1513,12 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + [[package]] name = "heck" version = "0.3.3" @@ -1343,24 +1530,21 @@ dependencies = [ [[package]] name = "heck" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] -name = "hermit-abi" -version = "0.1.19" +name = "heck" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.3.1" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -1370,27 +1554,27 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "html5ever" -version = "0.25.2" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5c13fb08e5d4dfc151ee5e88bae63f7773d61852f3bdc73c9f4b9e1bde03148" +checksum = "bea68cab48b8459f17cf1c944c67ddc572d272d9f2b274140f223ecb1da4a3b7" dependencies = [ "log", "mac", "markup5ever", "proc-macro2", "quote", - "syn 1.0.95", + "syn 1.0.109", ] [[package]] name = "http" -version = "0.2.8" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", - "itoa 1.0.2", + "itoa 1.0.11", ] [[package]] @@ -1399,24 +1583,18 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - [[package]] name = "iana-time-zone" -version = "0.1.56" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows 0.48.0", + "windows-core 0.52.0", ] [[package]] @@ -1448,6 +1626,124 @@ dependencies = [ "png", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f8ac670d7422d7f76b32e17a5db556510825b29ec9154f235977c9caba61036" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -1456,55 +1752,69 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.2.3" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +checksum = "4716a3a0933a1d01c2f72450e89596eb51dd34ef3c211ccd875acdf1f8fe47ed" dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", + "icu_normalizer", + "icu_properties", + "smallvec", + "utf8_iter", ] +[[package]] +name = "if_chain" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" + [[package]] name = "ignore" -version = "0.4.18" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713f1b139373f96a2e0ce3ac931cd01ee973c3c5dd7c40c0c2efe96ad2b6751d" +checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" dependencies = [ - "crossbeam-utils", + "crossbeam-deque", "globset", - "lazy_static", "log", "memchr", - "regex", + "regex-automata 0.4.7", "same-file", - "thread_local", "walkdir", "winapi-util", ] [[package]] name = "image" -version = "0.24.2" +version = "0.24.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28edd9d7bc256be2502e325ac0628bde30b7001b9b52e0abe31a1a9dc2701212" +checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" dependencies = [ "bytemuck", "byteorder", "color_quant", - "num-iter", - "num-rational", "num-traits", ] [[package]] name = "indexmap" -version = "1.9.1" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown 0.14.5", "serde", ] @@ -1519,45 +1829,22 @@ dependencies = [ [[package]] name = "infer" -version = "0.12.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a898e4b7951673fce96614ce5751d13c40fc5674bc2d759288e46c3ab62598b3" +checksum = "f551f8c3a39f68f986517db0d1759de85881894fdc7db798bd2a9df9cb04b7fc" dependencies = [ "cfb", ] [[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", ] -[[package]] -name = "io-lifetimes" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" -dependencies = [ - "hermit-abi 0.3.1", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "is-terminal" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" -dependencies = [ - "hermit-abi 0.3.1", - "io-lifetimes", - "rustix", - "windows-sys 0.48.0", -] - [[package]] name = "itoa" version = "0.4.8" @@ -1566,9 +1853,9 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "itoa" -version = "1.0.2" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "javascriptcore-rs" @@ -1615,44 +1902,33 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "js-sys" -version = "0.3.57" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] [[package]] name = "json-patch" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f995a3c8f2bc3dd52a18a583e90f9ec109c047fa1603a853e46bcda14d2e279d" -dependencies = [ - "serde", - "serde_json", - "treediff 3.0.2", -] - -[[package]] -name = "json-patch" -version = "1.0.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f54898088ccb91df1b492cc80029a6fdf1c48ca0db7c6822a8babad69c94658" +checksum = "ec9ad60d674508f3ca8f380a928cfe7b096bc729c4e2dbfe3852bc45da3ab30b" dependencies = [ "serde", "serde_json", "thiserror", - "treediff 4.0.2", ] [[package]] -name = "kuchiki" -version = "0.8.1" +name = "kuchikiki" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ea8e9c6e031377cff82ee3001dc8026cdf431ed4e2e6b51f98ab8c73484a358" +checksum = "f29e4755b7b995046f510a7520c42b2fed58b77bd94d5a87a8eb43d2fd126da8" dependencies = [ "cssparser", "html5ever", + "indexmap 1.9.3", "matches", "selectors", ] @@ -1689,9 +1965,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.141" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libloading" @@ -1704,25 +1980,38 @@ dependencies = [ ] [[package]] -name = "line-wrap" -version = "0.1.1" +name = "libredox" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30344350a2a51da54c1d53be93fade8a237e545dbcc4bdbe635413f2117cab9" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "safemem", + "bitflags 2.5.0", + "libc", ] +[[package]] +name = "line-wrap" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd1bc4d24ad230d21fb898d1116b1801d7adfc449d42026475862ab48b11e70e" + [[package]] name = "linux-raw-sys" -version = "0.3.1" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "litemap" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" +checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" [[package]] name = "lock_api" -version = "0.4.7" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -1730,12 +2019,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "loom" @@ -1760,9 +2046,9 @@ checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" [[package]] name = "mac-notification-sys" -version = "0.5.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "297c13fc8ff9fa8b2d0e53850f80e0aa962628e865d447031ce58cdb062e5b29" +checksum = "51fca4d74ff9dbaac16a01b924bc3693fa2bba0862c2c633abc73f9a8ea21f64" dependencies = [ "cc", "dirs-next", @@ -1782,13 +2068,13 @@ dependencies = [ [[package]] name = "markup5ever" -version = "0.10.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a24f40fb03852d1cdd84330cddcaf98e9ec08a7b7768e952fad3b4cf048ec8fd" +checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016" dependencies = [ "log", - "phf 0.8.0", - "phf_codegen", + "phf 0.10.1", + "phf_codegen 0.10.0", "string_cache", "string_cache_codegen", "tendril", @@ -1800,55 +2086,47 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" dependencies = [ - "regex-automata", + "regex-automata 0.1.10", ] [[package]] name = "matches" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" [[package]] name = "memchr" -version = "2.5.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "memoffset" -version = "0.6.5" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" dependencies = [ "autocfg", ] [[package]] -name = "miniz_oxide" -version = "0.5.1" +name = "memoffset" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" dependencies = [ - "adler", + "autocfg", ] [[package]] -name = "native-tls" -version = "0.2.10" +name = "miniz_oxide" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9" +checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", + "adler", + "simd-adler32", ] [[package]] @@ -1881,21 +2159,33 @@ dependencies = [ [[package]] name = "new_debug_unreachable" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" [[package]] name = "nix" -version = "0.23.2" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" dependencies = [ "bitflags 1.3.2", - "cc", "cfg-if", "libc", - "memoffset", + "memoffset 0.7.1", +] + +[[package]] +name = "nix" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +dependencies = [ + "bitflags 2.5.0", + "cfg-if", + "cfg_aliases", + "libc", + "memoffset 0.9.1", ] [[package]] @@ -1906,97 +2196,82 @@ checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" [[package]] name = "notify-rust" -version = "4.5.8" +version = "4.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a995a3d2834cefa389218e7a35156e8ce544bc95f836900da01ee0b26a07e9d4" +checksum = "5312f837191c317644f313f7b2b39f9cb1496570c74f7c17152dd3961219551f" dependencies = [ + "log", "mac-notification-sys", "serde", - "winrt-notification", + "tauri-winrt-notification", "zbus", - "zvariant", - "zvariant_derive", ] [[package]] -name = "num-integer" -version = "0.1.45" +name = "nu-ansi-term" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" dependencies = [ - "autocfg", - "num-traits", + "overload", + "winapi", ] [[package]] -name = "num-iter" -version = "0.1.43" +name = "num-conv" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] -name = "num-rational" -version = "0.4.0" +name = "num-derive" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ - "autocfg", - "num-integer", - "num-traits", + "proc-macro2", + "quote", + "syn 2.0.66", ] [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "num_cpus" -version = "1.13.1" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.1.19", + "hermit-abi", "libc", ] [[package]] name = "num_enum" -version = "0.5.7" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf5395665662ef45796a4ff5486c5d41d29e0c09640af4c5f17fd94ee2c119c9" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" dependencies = [ "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.5.7" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 1.0.95", -] - -[[package]] -name = "num_threads" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" -dependencies = [ - "libc", + "syn 1.0.109", ] [[package]] @@ -2038,11 +2313,20 @@ dependencies = [ "objc", ] +[[package]] +name = "object" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" -version = "1.17.1" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "open" @@ -2055,84 +2339,34 @@ dependencies = [ ] [[package]] -name = "openssl" -version = "0.10.40" +name = "ordered-stream" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb81a6430ac911acb25fe5ac8f1d2af1b4ea8a4fdfda0f1ee4292af2e2d8eb0e" +checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" dependencies = [ - "bitflags 1.3.2", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", + "futures-core", + "pin-project-lite", ] [[package]] -name = "openssl-macros" -version = "0.1.0" +name = "os_pipe" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +checksum = "29d73ba8daf8fac13b0501d1abeddcfe21ba7401ada61a819144b6c2a4f32209" dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.95", + "libc", + "windows-sys 0.52.0", ] [[package]] -name = "openssl-probe" -version = "0.1.5" +name = "overload" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] -name = "openssl-sys" -version = "0.9.73" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5fd19fb3e0a8191c1e34935718976a3e70c112ab9a24af6d7cadccd9d90bc0" -dependencies = [ - "autocfg", - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "ordered-stream" -version = "0.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44630c059eacfd6e08bdaa51b1db2ce33119caa4ddc1235e923109aa5f25ccb1" -dependencies = [ - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "os_info" -version = "3.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4750134fb6a5d49afc80777394ad5d95b04bc12068c6abb92fae8f43817270f" -dependencies = [ - "log", - "serde", - "winapi", -] - -[[package]] -name = "os_pipe" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c92f2b54f081d635c77e7120862d48db8e91f7f21cef23ab1b4fe9971c59f55" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "pango" -version = "0.15.10" +name = "pango" +version = "0.15.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22e4045548659aee5313bde6c582b0d83a627b7904dd20dc2d9ef0895d414e4f" dependencies = [ @@ -2152,61 +2386,61 @@ dependencies = [ "glib-sys", "gobject-sys", "libc", - "system-deps 6.0.2", + "system-deps 6.2.2", ] [[package]] name = "parking" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" [[package]] name = "parking_lot" -version = "0.11.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ - "instant", "lock_api", - "parking_lot_core 0.8.6", + "parking_lot_core", ] [[package]] -name = "parking_lot" -version = "0.12.0" +name = "parking_lot_core" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ - "lock_api", - "parking_lot_core 0.9.3", + "cfg-if", + "libc", + "redox_syscall 0.5.1", + "smallvec", + "windows-targets 0.52.6", ] [[package]] -name = "parking_lot_core" -version = "0.8.6" +name = "parse-display" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +checksum = "914a1c2265c98e2446911282c6ac86d8524f495792c38c5bd884f80499c7538a" dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall", - "smallvec", - "winapi", + "parse-display-derive", + "regex", + "regex-syntax 0.8.4", ] [[package]] -name = "parking_lot_core" -version = "0.9.3" +name = "parse-display-derive" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +checksum = "2ae7800a4c974efd12df917266338e79a7a74415173caf7e70aa0a0707345281" dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-sys 0.36.1", + "proc-macro2", + "quote", + "regex", + "regex-syntax 0.8.4", + "structmeta", + "syn 2.0.66", ] [[package]] @@ -2217,18 +2451,9 @@ checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" [[package]] name = "percent-encoding" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" - -[[package]] -name = "pest" -version = "2.1.3" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" -dependencies = [ - "ucd-trie", -] +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "phf" @@ -2247,9 +2472,17 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" dependencies = [ - "phf_macros 0.10.0", "phf_shared 0.10.0", - "proc-macro-hack", +] + +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros 0.11.2", + "phf_shared 0.11.2", ] [[package]] @@ -2262,6 +2495,16 @@ dependencies = [ "phf_shared 0.8.0", ] +[[package]] +name = "phf_codegen" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", +] + [[package]] name = "phf_generator" version = "0.8.0" @@ -2282,6 +2525,16 @@ dependencies = [ "rand 0.8.5", ] +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared 0.11.2", + "rand 0.8.5", +] + [[package]] name = "phf_macros" version = "0.8.0" @@ -2293,21 +2546,20 @@ dependencies = [ "proc-macro-hack", "proc-macro2", "quote", - "syn 1.0.95", + "syn 1.0.109", ] [[package]] name = "phf_macros" -version = "0.10.0" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" dependencies = [ - "phf_generator 0.10.0", - "phf_shared 0.10.0", - "proc-macro-hack", + "phf_generator 0.11.2", + "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 1.0.95", + "syn 2.0.66", ] [[package]] @@ -2328,11 +2580,20 @@ dependencies = [ "siphasher", ] +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -2340,57 +2601,76 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "piper" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1d5c74c9876f070d3e8fd503d748c7d974c3e48da8f41350fa5222ef9b4391" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + [[package]] name = "pkg-config" -version = "0.3.25" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "plist" -version = "1.3.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd39bc6cdc9355ad1dc5eeedefee696bb35c34caf21768741e81826c0bbd7225" +checksum = "d9d34169e64b3c7a80c8621a48adaf44e0cf62c78a9b25dd9dd35f1881a17cf9" dependencies = [ - "base64 0.13.0", - "indexmap", + "base64 0.21.7", + "indexmap 2.2.6", "line-wrap", + "quick-xml", "serde", "time", - "xml-rs", ] [[package]] name = "png" -version = "0.17.5" +version = "0.17.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc38c0ad57efb786dd57b9864e5b18bae478c00c824dc55a38bbc9da95dde3ba" +checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" dependencies = [ "bitflags 1.3.2", "crc32fast", - "deflate", + "fdeflate", + "flate2", "miniz_oxide", ] [[package]] name = "polling" -version = "2.5.2" +version = "3.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22122d5ec4f9fe1b3916419b76be1e80bcb93f618d071d2edf841b137b2a2bd6" +checksum = "5e6a007746f34ed64099e88783b0ae369eaa3da6392868ba262e2af9b8fbaea1" dependencies = [ - "autocfg", "cfg-if", - "libc", - "log", - "wepoll-ffi", - "windows-sys 0.42.0", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix", + "tracing", + "windows-sys 0.52.0", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "precomputed-hash" @@ -2398,14 +2678,33 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +[[package]] +name = "pretty_assertions" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +dependencies = [ + "diff", + "yansi", +] + [[package]] name = "proc-macro-crate" -version = "1.1.3" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ - "thiserror", - "toml 0.5.9", + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit 0.21.1", ] [[package]] @@ -2417,7 +2716,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn 1.0.95", + "syn 1.0.109", "version_check", ] @@ -2434,24 +2733,57 @@ dependencies = [ [[package]] name = "proc-macro-hack" -version = "0.5.19" +version = "0.5.20+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.58" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa1fb82fc0c281dd9671101b66b771ebbe1eaf967b96ac8740dcba4b70005ca8" +checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" dependencies = [ "unicode-ident", ] +[[package]] +name = "quick-xml" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" +dependencies = [ + "memchr", +] + +[[package]] +name = "quick_tracing" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad66124d69ce8125da5c9dacbc92a07b94d12c98003bef061bfdb5bb6d33bcec" +dependencies = [ + "quick_tracing_derive", + "tracing", + "tracing-appender", + "tracing-subscriber", +] + +[[package]] +name = "quick_tracing_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea36c74b7f417887bd1ee81ba6c2c8f97cc85d71b6dce3f0257c694b155bcccf" +dependencies = [ + "deluxe", + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "quote" -version = "1.0.26" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -2478,7 +2810,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha 0.3.1", - "rand_core 0.6.3", + "rand_core 0.6.4", ] [[package]] @@ -2498,7 +2830,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.3", + "rand_core 0.6.4", ] [[package]] @@ -2512,11 +2844,11 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.6", + "getrandom 0.2.15", ] [[package]] @@ -2539,42 +2871,49 @@ dependencies = [ [[package]] name = "raw-window-handle" -version = "0.5.0" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" + +[[package]] +name = "redox_syscall" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed7e3d950b66e19e0c372f3fa3fbbcf85b1746b571f74e0c2af6042a5c93420a" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ - "cty", + "bitflags 1.3.2", ] [[package]] name = "redox_syscall" -version = "0.2.13" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", ] [[package]] name = "redox_users" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ - "getrandom 0.2.6", - "redox_syscall", + "getrandom 0.2.15", + "libredox", "thiserror", ] [[package]] name = "regex" -version = "1.7.3" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", ] [[package]] @@ -2583,7 +2922,18 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" dependencies = [ - "regex-syntax", + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.4", ] [[package]] @@ -2593,13 +2943,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] -name = "remove_dir_all" -version = "0.5.3" +name = "regex-syntax" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "rfd" @@ -2626,13 +2973,10 @@ dependencies = [ ] [[package]] -name = "rustc_version" -version = "0.3.3" +name = "rustc-demangle" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" -dependencies = [ - "semver 0.11.0", -] +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc_version" @@ -2640,40 +2984,33 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.9", + "semver", ] [[package]] name = "rustix" -version = "0.37.11" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85597d61f83914ddeba6a47b3b8ffe7365107221c2e557ed94426489fefb5f77" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", "errno", - "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "rustversion" -version = "1.0.6" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "ryu" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" - -[[package]] -name = "safemem" -version = "0.3.3" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -2684,50 +3021,17 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "schannel" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" -dependencies = [ - "lazy_static", - "windows-sys 0.36.1", -] - [[package]] name = "scoped-tls" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" [[package]] name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "security-framework" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.6.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" -dependencies = [ - "core-foundation-sys", - "libc", -] +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "selectors" @@ -2742,7 +3046,7 @@ dependencies = [ "log", "matches", "phf 0.8.0", - "phf_codegen", + "phf_codegen 0.8.0", "precomputed-hash", "servo_arc", "smallvec", @@ -2751,105 +3055,78 @@ dependencies = [ [[package]] name = "semver" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver" -version = "1.0.9" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cb243bdfdb5936c8dc3c45762a19d12ab4550cdc753bc247637d4ec35a040fd" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" dependencies = [ "serde", ] -[[package]] -name = "semver-parser" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" -dependencies = [ - "pest", -] - [[package]] name = "serde" -version = "1.0.159" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.159" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.66", ] [[package]] name = "serde_json" -version = "1.0.95" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ - "itoa 1.0.2", + "indexmap 2.2.6", + "itoa 1.0.11", "ryu", "serde", ] [[package]] name = "serde_repr" -version = "0.1.8" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2ad84e47328a31223de7fed7a4f5087f2d6ddfe586cf3ca25b7a165bc0a5aed" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 1.0.95", + "syn 2.0.66", ] [[package]] name = "serde_spanned" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" dependencies = [ - "form_urlencoded", - "itoa 1.0.2", - "ryu", "serde", ] [[package]] name = "serde_with" -version = "2.3.3" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" +checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857" dependencies = [ - "base64 0.13.0", + "base64 0.22.1", "chrono", "hex", - "indexmap", + "indexmap 1.9.3", + "indexmap 2.2.6", "serde", + "serde_derive", "serde_json", "serde_with_macros", "time", @@ -2857,14 +3134,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "2.3.3" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" +checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.66", ] [[package]] @@ -2886,7 +3163,7 @@ checksum = "74064874e9f6a15f04c1f3cb627902d0e6b410abbf36668afa873c61889f1763" dependencies = [ "proc-macro2", "quote", - "syn 1.0.95", + "syn 1.0.109", ] [[package]] @@ -2901,24 +3178,20 @@ dependencies = [ [[package]] name = "sha1" -version = "0.6.1" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ - "sha1_smol", + "cfg-if", + "cpufeatures", + "digest", ] -[[package]] -name = "sha1_smol" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" - [[package]] name = "sha2" -version = "0.10.2" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", @@ -2927,9 +3200,9 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.4" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ "lazy_static", ] @@ -2944,32 +3217,61 @@ dependencies = [ "winapi", ] +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + [[package]] name = "siphasher" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" [[package]] name = "slab" -version = "0.4.6" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] [[package]] name = "smallvec" -version = "1.8.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] -name = "socket2" -version = "0.4.9" +name = "snafu" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "418b8136fec49956eba89be7da2847ec1909df92a9ae4178b5ff0ff092c8d95e" dependencies = [ - "libc", - "winapi", + "snafu-derive", +] + +[[package]] +name = "snafu-derive" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a4812a669da00d17d8266a0439eddcacbc88b17f732f927e52eeb9d196f7fb5" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.66", ] [[package]] @@ -3023,13 +3325,13 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "string_cache" -version = "0.8.4" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213494b7a2b503146286049378ce02b482200519accc31872ee8be91fa820a08" +checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" dependencies = [ "new_debug_unreachable", "once_cell", - "parking_lot 0.12.0", + "parking_lot", "phf_shared 0.10.0", "precomputed-hash", "serde", @@ -3054,31 +3356,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] -name = "strum" -version = "0.22.0" +name = "strsim" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7ac893c7d471c8a21f31cfe213ec4f6d9afeed25537c772e08ef3f005f8729e" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "structmeta" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e1575d8d40908d70f6fd05537266b90ae71b15dbbe7a8b7dffa2b759306d329" dependencies = [ - "strum_macros", + "proc-macro2", + "quote", + "structmeta-derive", + "syn 2.0.66", ] [[package]] -name = "strum_macros" -version = "0.22.0" +name = "structmeta-derive" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "339f799d8b549e3744c7ac7feb216383e4005d94bdb22561b3ab8f3b808ae9fb" +checksum = "152a0b65a590ff6c3da95cabe2353ee04e6167c896b28e3b14478c2636c922fc" dependencies = [ - "heck 0.3.3", "proc-macro2", "quote", - "syn 1.0.95", + "syn 2.0.66", ] [[package]] name = "syn" -version = "1.0.95" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", @@ -3087,15 +3397,26 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.16" +version = "2.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "system-deps" version = "5.0.0" @@ -3105,28 +3426,28 @@ dependencies = [ "cfg-expr 0.9.1", "heck 0.3.3", "pkg-config", - "toml 0.5.9", + "toml 0.5.11", "version-compare 0.0.11", ] [[package]] name = "system-deps" -version = "6.0.2" +version = "6.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a45a1c4c9015217e12347f2a411b57ce2c4fc543913b14b6fe40483328e709" +checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" dependencies = [ - "cfg-expr 0.10.3", - "heck 0.4.0", + "cfg-expr 0.15.8", + "heck 0.5.0", "pkg-config", - "toml 0.5.9", - "version-compare 0.1.0", + "toml 0.8.14", + "version-compare 0.2.0", ] [[package]] name = "tao" -version = "0.16.1" +version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd3cde9c0cd2b872616bba26b818e0d6469330196869d7e5000dba96ce9431df" +checksum = "575c856fc21e551074869dcfaad8f706412bd5b803dfa0fbf6881c4ff4bfafab" dependencies = [ "bitflags 1.3.2", "cairo-rs", @@ -3158,7 +3479,7 @@ dependencies = [ "ndk-sys", "objc", "once_cell", - "parking_lot 0.12.0", + "parking_lot", "png", "raw-window-handle", "scopeguard", @@ -3167,59 +3488,66 @@ dependencies = [ "unicode-segmentation", "uuid", "windows 0.39.0", - "windows-implement", + "windows-implement 0.39.0", "x11-dl", ] [[package]] name = "tao-macros" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b27a4bcc5eb524658234589bdffc7e7bfb996dbae6ce9393bfd39cb4159b445" +checksum = "ec114582505d158b669b136e6851f85840c109819d77c42bb7c0709f727d18c2" dependencies = [ "proc-macro2", "quote", - "syn 1.0.95", + "syn 1.0.109", ] [[package]] name = "tar" -version = "0.4.38" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" +checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909" dependencies = [ "filetime", "libc", "xattr", ] +[[package]] +name = "target-lexicon" +version = "0.12.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" + [[package]] name = "tauri" -version = "1.3.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d42ba3a2e8556722f31336a0750c10dbb6a81396a1c452977f515da83f69f842" +checksum = "336bc661a3f3250853fa83c6e5245449ed1c26dce5dcb28bdee7efedf6278806" dependencies = [ "anyhow", - "attohttpc", "cocoa", "dirs-next", + "dunce", "embed_plist", "encoding_rs", "flate2", "futures-util", + "getrandom 0.2.15", "glib", "glob", "gtk", - "heck 0.4.0", + "heck 0.5.0", "http", "ico 0.2.0", "ignore", "infer 0.9.0", + "nix 0.26.4", "notify-rust", "objc", "once_cell", "open", - "os_info", "os_pipe", "percent-encoding", "png", @@ -3227,7 +3555,7 @@ dependencies = [ "raw-window-handle", "regex", "rfd", - "semver 1.0.9", + "semver", "serde", "serde_json", "serde_repr", @@ -3251,36 +3579,39 @@ dependencies = [ [[package]] name = "tauri-build" -version = "1.2.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8807c85d656b2b93927c19fe5a5f1f1f348f96c2de8b90763b3c2d561511f9b4" +checksum = "ab30cba12974d0f9b09794f61e72cad6da2142d3ceb81e519321bab86ce53312" dependencies = [ "anyhow", "cargo_toml", - "heck 0.4.0", - "json-patch 0.2.6", - "semver 1.0.9", + "dirs-next", + "heck 0.5.0", + "json-patch", + "semver", + "serde", "serde_json", "tauri-utils", - "winres", + "tauri-winres", + "walkdir", ] [[package]] name = "tauri-codegen" -version = "1.3.0" +version = "1.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a2105f807c6f50b2fa2ce5abd62ef207bc6f14c9fcc6b8caec437f6fb13bde" +checksum = "c1aed706708ff1200ec12de9cfbf2582b5d8ec05f6a7293911091effbd22036b" dependencies = [ - "base64 0.21.0", + "base64 0.21.7", "brotli", "ico 0.3.0", - "json-patch 1.0.0", + "json-patch", "plist", "png", "proc-macro2", "quote", "regex", - "semver 1.0.9", + "semver", "serde", "serde_json", "sha2", @@ -3293,22 +3624,22 @@ dependencies = [ [[package]] name = "tauri-macros" -version = "1.3.0" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8784cfe6f5444097e93c69107d1ac5e8f13d02850efa8d8f2a40fe79674cef46" +checksum = "b88f831d2973ae4f81a706a0004e67dac87f2e4439973bbe98efbd73825d8ede" dependencies = [ - "heck 0.4.0", + "heck 0.5.0", "proc-macro2", "quote", - "syn 1.0.95", + "syn 1.0.109", "tauri-codegen", "tauri-utils", ] [[package]] name = "tauri-plugin-autostart" -version = "0.1.0" -source = "git+https://github.com/tauri-apps/plugins-workspace?branch=dev#cea1d4f7b54b94354e8100daf804b810c680efd7" +version = "0.0.0" +source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v1#bd3d9ca152ee8b55e3e669dac68476ce6150c57f" dependencies = [ "auto-launch", "log", @@ -3318,25 +3649,11 @@ dependencies = [ "thiserror", ] -[[package]] -name = "tauri-plugin-window-state" -version = "0.1.0" -source = "git+https://github.com/tauri-apps/plugins-workspace?branch=dev#cea1d4f7b54b94354e8100daf804b810c680efd7" -dependencies = [ - "bincode", - "bitflags 2.0.2", - "log", - "serde", - "serde_json", - "tauri", - "thiserror", -] - [[package]] name = "tauri-runtime" -version = "0.13.0" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3b80ea3fcd5fefb60739a3b577b277e8fc30434538a2f5bba82ad7d4368c422" +checksum = "3068ed62b63dedc705558f4248c7ecbd5561f0f8050949859ea0db2326f26012" dependencies = [ "gtk", "http", @@ -3355,9 +3672,9 @@ dependencies = [ [[package]] name = "tauri-runtime-wry" -version = "0.13.0" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1c396950b1ba06aee1b4ffe6c7cd305ff433ca0e30acbc5fa1a2f92a4ce70f1" +checksum = "d4c3db170233096aa30330feadcd895bf9317be97e624458560a20e814db7955" dependencies = [ "cocoa", "gtk", @@ -3375,44 +3692,71 @@ dependencies = [ [[package]] name = "tauri-utils" -version = "1.3.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a6f9c2dafef5cbcf52926af57ce9561bd33bb41d7394f8bb849c0330260d864" +checksum = "2826db448309d382dac14d520f0c0a40839b87b57b977e59cf5f296b3ace6a93" dependencies = [ "brotli", "ctor", + "dunce", "glob", - "heck 0.4.0", + "heck 0.5.0", "html5ever", - "infer 0.12.0", - "json-patch 1.0.0", - "kuchiki", + "infer 0.13.0", + "json-patch", + "kuchikiki", + "log", "memchr", - "phf 0.10.1", + "phf 0.11.2", "proc-macro2", "quote", - "semver 1.0.9", + "semver", "serde", "serde_json", "serde_with", "thiserror", "url", "walkdir", - "windows 0.39.0", + "windows-version", ] +[[package]] +name = "tauri-winres" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5993dc129e544393574288923d1ec447c857f3f644187f4fbf7d9a875fbfc4fb" +dependencies = [ + "embed-resource", + "toml 0.7.8", +] + +[[package]] +name = "tauri-winrt-notification" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f89f5fb70d6f62381f5d9b2ba9008196150b40b75f3068eb24faeddf1c686871" +dependencies = [ + "quick-xml", + "windows 0.56.0", + "windows-version", +] + +[[package]] +name = "temp-dir" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f227968ec00f0e5322f9b8173c7a0cbcff6181a0a5b28e9892491c286277231" + [[package]] name = "tempfile" -version = "3.3.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", + "rustix", + "windows-sys 0.52.0", ] [[package]] @@ -3426,15 +3770,6 @@ dependencies = [ "utf-8", ] -[[package]] -name = "termcolor" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" -dependencies = [ - "winapi-util", -] - [[package]] name = "thin-slice" version = "0.1.1" @@ -3443,181 +3778,255 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" [[package]] name = "thiserror" -version = "1.0.40" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.40" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.66", ] [[package]] name = "thread_local" -version = "1.1.4" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ + "cfg-if", "once_cell", ] [[package]] name = "time" -version = "0.3.15" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d634a985c4d4238ec39cacaed2e7ae552fbd3c476b552c1deac3021b7d7eaf0c" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ - "itoa 1.0.2", - "libc", - "num_threads", + "deranged", + "itoa 1.0.11", + "num-conv", + "powerfmt", "serde", + "time-core", + "time-macros", ] [[package]] -name = "tinyvec" -version = "1.6.0" +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ - "tinyvec_macros", + "num-conv", + "time-core", ] [[package]] -name = "tinyvec_macros" -version = "0.1.0" +name = "timer" +version = "0.3.0" +dependencies = [ + "dashmap", + "once_cell", + "pretty_assertions", + "quick_tracing", + "snafu", + "tokio", + "tracing", +] + +[[package]] +name = "tinystr" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] [[package]] name = "tokio" -version = "1.27.0" +version = "1.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001" +checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" dependencies = [ - "autocfg", + "backtrace", "bytes", "num_cpus", "pin-project-lite", "tokio-macros", - "windows-sys 0.45.0", ] [[package]] name = "tokio-macros" -version = "2.0.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce" +checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.66", ] [[package]] name = "toml" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ "serde", ] [[package]] name = "toml" -version = "0.7.3" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.19.15", +] + +[[package]] +name = "toml" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b403acf6f2bb0859c93c7f0d967cb4a75a7ac552100f9322faf64dc047669b21" +checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_edit 0.22.14", ] [[package]] name = "toml_datetime" -version = "0.6.1" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.19.8" +version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap", + "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap 2.2.6", + "toml_datetime", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.22.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" +dependencies = [ + "indexmap 2.2.6", + "serde", + "serde_spanned", + "toml_datetime", + "winnow 0.6.13", ] [[package]] name = "tracing" -version = "0.1.34" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "pin-project-lite", "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-appender" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" +dependencies = [ + "crossbeam-channel", + "thiserror", + "time", + "tracing-subscriber", +] + [[package]] name = "tracing-attributes" -version = "0.1.21" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 1.0.95", + "syn 2.0.66", ] [[package]] name = "tracing-core" -version = "0.1.26" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ - "lazy_static", + "once_cell", "valuable", ] [[package]] name = "tracing-log" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" dependencies = [ - "lazy_static", "log", + "once_cell", "tracing-core", ] [[package]] name = "tracing-subscriber" -version = "0.3.11" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bc28f93baff38037f64e6f43d34cfa1605f27a49c34e8a04c5e78b0babf2596" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ - "ansi_term", - "lazy_static", "matchers", + "nu-ansi-term", + "once_cell", "regex", "sharded-slab", "smallvec", @@ -3627,78 +4036,40 @@ dependencies = [ "tracing-log", ] -[[package]] -name = "treediff" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "761e8d5ad7ce14bb82b7e61ccc0ca961005a275a060b9644a2431aa11553c2ff" -dependencies = [ - "serde_json", -] - -[[package]] -name = "treediff" -version = "4.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52984d277bdf2a751072b5df30ec0377febdb02f7696d64c2d7d54630bac4303" -dependencies = [ - "serde_json", -] - [[package]] name = "typenum" -version = "1.15.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" - -[[package]] -name = "ucd-trie" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "uds_windows" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce65604324d3cce9b966701489fbd0cf318cb1f7bd9dd07ac9a4ee6fb791930d" +checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" dependencies = [ + "memoffset 0.9.1", "tempfile", "winapi", ] -[[package]] -name = "unicode-bidi" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" - [[package]] name = "unicode-ident" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" - -[[package]] -name = "unicode-normalization" -version = "0.1.19" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" -dependencies = [ - "tinyvec", -] +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "url" -version = "2.3.0" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22fe195a4f217c25b25cb5058ced57059824a678474874038dc88d211bf508d3" +checksum = "f7c25da092f0a868cdf09e8674cd3b7ef3a7d92a24253e663a2fb85e2496de56" dependencies = [ "form_urlencoded", "idna", @@ -3712,13 +4083,25 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "uuid" -version = "1.3.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" dependencies = [ - "getrandom 0.2.6", + "getrandom 0.2.15", ] [[package]] @@ -3727,12 +4110,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "version-compare" version = "0.0.11" @@ -3741,30 +4118,43 @@ checksum = "1c18c859eead79d8b95d09e4678566e8d70105c4e7b251f707a03df32442661b" [[package]] name = "version-compare" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe88247b92c1df6b6de80ddc290f3976dbdf2f5f5d3fd049a9fb598c6dd5ca73" +checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "vswhom" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b" +dependencies = [ + "libc", + "vswhom-sys", +] [[package]] -name = "waker-fn" -version = "1.1.0" +name = "vswhom-sys" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" +checksum = "d3b17ae1f6c8a2b28506cd96d412eebf83b4a0ff2cbefeeb952f2f9dfa44ba18" +dependencies = [ + "cc", + "libc", +] [[package]] name = "walkdir" -version = "2.3.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", - "winapi", "winapi-util", ] @@ -3776,15 +4166,15 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.80" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3792,24 +4182,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.80" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", - "lazy_static", "log", + "once_cell", "proc-macro2", "quote", - "syn 1.0.95", + "syn 2.0.66", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.30" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f741de44b75e14c35df886aff5f1eb73aa114fa5d4d00dcd37b5e01259bf3b2" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -3819,9 +4209,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.80" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3829,28 +4219,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.80" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 1.0.95", + "syn 2.0.66", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.80" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "web-sys" -version = "0.3.57" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -3900,7 +4290,7 @@ dependencies = [ "pango-sys", "pkg-config", "soup2-sys", - "system-deps 6.0.2", + "system-deps 6.2.2", ] [[package]] @@ -3912,7 +4302,7 @@ dependencies = [ "webview2-com-macros", "webview2-com-sys", "windows 0.39.0", - "windows-implement", + "windows-implement 0.39.0", ] [[package]] @@ -3923,7 +4313,7 @@ checksum = "eaebe196c01691db62e9e4ca52c5ef1e4fd837dcae27dae3ada599b5a8fd05ac" dependencies = [ "proc-macro2", "quote", - "syn 1.0.95", + "syn 1.0.109", ] [[package]] @@ -3941,15 +4331,6 @@ dependencies = [ "windows-metadata", ] -[[package]] -name = "wepoll-ffi" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" -dependencies = [ - "cc", -] - [[package]] name = "winapi" version = "0.3.9" @@ -3968,11 +4349,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -3981,18 +4362,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9f39345ae0c8ab072c0ac7fe8a8b411636aa34f89be19ddd0d9226544f13944" -dependencies = [ - "windows_i686_gnu 0.24.0", - "windows_i686_msvc 0.24.0", - "windows_x86_64_gnu 0.24.0", - "windows_x86_64_msvc 0.24.0", -] - [[package]] name = "windows" version = "0.37.0" @@ -4012,7 +4381,7 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1c4bd0a50ac6020f65184721f758dba47bb9fbc2133df715ec74a237b26794a" dependencies = [ - "windows-implement", + "windows-implement 0.39.0", "windows_aarch64_msvc 0.39.0", "windows_i686_gnu 0.39.0", "windows_i686_msvc 0.39.0", @@ -4026,7 +4395,27 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets 0.48.0", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1de69df01bdf1ead2f4ac895dc77c9351aefff65b2f3db429a343f9cbf05e132" +dependencies = [ + "windows-core 0.56.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core 0.58.0", + "windows-targets 0.52.6", ] [[package]] @@ -4039,16 +4428,94 @@ dependencies = [ "windows-tokens", ] +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4698e52ed2d08f8658ab0c39512a7c00ee5fe2688c65f8c0a4f06750d729f2a6" +dependencies = [ + "windows-implement 0.56.0", + "windows-interface 0.56.0", + "windows-result 0.1.2", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement 0.58.0", + "windows-interface 0.58.0", + "windows-result 0.2.0", + "windows-strings", + "windows-targets 0.52.6", +] + [[package]] name = "windows-implement" version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba01f98f509cb5dc05f4e5fc95e535f78260f15fea8fe1a8abdd08f774f1cee7" dependencies = [ - "syn 1.0.95", + "syn 1.0.109", "windows-tokens", ] +[[package]] +name = "windows-implement" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6fc35f58ecd95a9b71c4f2329b911016e6bec66b3f2e6a4aad86bd2e99e2f9b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "windows-interface" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08990546bf4edef8f431fa6326e032865f27138718c587dc21bc0265bbcb57cc" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "windows-metadata" version = "0.39.0" @@ -4056,16 +4523,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ee5e275231f07c6e240d14f34e1b635bf1faa1c76c57cfd59a5cdb9848e4278" [[package]] -name = "windows-sys" -version = "0.36.1" +name = "windows-result" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" dependencies = [ - "windows_aarch64_msvc 0.36.1", - "windows_i686_gnu 0.36.1", - "windows_i686_msvc 0.36.1", - "windows_x86_64_gnu 0.36.1", - "windows_x86_64_msvc 0.36.1", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result 0.2.0", + "windows-targets 0.52.6", ] [[package]] @@ -4085,50 +4567,51 @@ dependencies = [ [[package]] name = "windows-sys" -version = "0.45.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.42.2", + "windows-targets 0.48.5", ] [[package]] name = "windows-sys" -version = "0.48.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.48.0", + "windows-targets 0.52.6", ] [[package]] name = "windows-targets" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -4137,6 +4620,15 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f838de2fe15fe6bac988e74b798f26499a8b21a9d97edec321e79b28d1d7f597" +[[package]] +name = "windows-version" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6998aa457c9ba8ff2fb9f13e9d2a930dabcea28f1d0ab94d687d8b3654844515" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -4145,15 +4637,15 @@ checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] -name = "windows_aarch64_msvc" -version = "0.36.1" +name = "windows_aarch64_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -4175,21 +4667,15 @@ checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" - -[[package]] -name = "windows_i686_gnu" -version = "0.24.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0866510a3eca9aed73a077490bbbf03e5eaac4e1fd70849d89539e5830501fd" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] -name = "windows_i686_gnu" -version = "0.36.1" +name = "windows_aarch64_msvc" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -4211,21 +4697,21 @@ checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] -name = "windows_i686_msvc" -version = "0.24.0" +name = "windows_i686_gnu" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf0ffed56b7e9369a29078d2ab3aaeceea48eb58999d2cff3aa2494a275b95c6" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] -name = "windows_i686_msvc" -version = "0.36.1" +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -4247,21 +4733,15 @@ checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] -name = "windows_x86_64_gnu" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "384a173630588044205a2993b6864a2f56e5a8c1e7668c07b93ec18cf4888dc4" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.36.1" +name = "windows_i686_msvc" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -4283,33 +4763,33 @@ checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" +name = "windows_x86_64_gnu" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] -name = "windows_x86_64_msvc" -version = "0.24.0" +name = "windows_x86_64_gnullvm" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bd8f062d8ca5446358159d79a90be12c543b3a965c847c8f3eedf14b321d399" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] -name = "windows_x86_64_msvc" -version = "0.36.1" +name = "windows_x86_64_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -4331,15 +4811,30 @@ checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.4.1" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" dependencies = [ "memchr", ] @@ -4354,32 +4849,34 @@ dependencies = [ ] [[package]] -name = "winres" -version = "0.1.12" +name = "winreg" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b68db261ef59e9e52806f688020631e987592bd83619edccda9c47d42cde4f6c" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" dependencies = [ - "toml 0.5.9", + "cfg-if", + "windows-sys 0.48.0", ] [[package]] -name = "winrt-notification" -version = "0.5.1" +name = "write16" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "007a0353840b23e0c6dc73e5b962ff58ed7f6bc9ceff3ce7fe6fbad8d496edf4" -dependencies = [ - "strum", - "windows 0.24.0", - "xml-rs", -] +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" [[package]] name = "wry" -version = "0.24.3" +version = "0.24.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33748f35413c8a98d45f7a08832d848c0c5915501803d1faade5a4ebcd258cea" +checksum = "00711278ed357350d44c749c286786ecac644e044e4da410d466212152383b45" dependencies = [ - "base64 0.13.0", + "base64 0.13.1", "block", "cocoa", "core-graphics", @@ -4391,7 +4888,7 @@ dependencies = [ "gtk", "html5ever", "http", - "kuchiki", + "kuchikiki", "libc", "log", "objc", @@ -4408,14 +4905,14 @@ dependencies = [ "webkit2gtk-sys", "webview2-com", "windows 0.39.0", - "windows-implement", + "windows-implement 0.39.0", ] [[package]] name = "x11" -version = "2.19.1" +version = "2.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dd0565fa8bfba8c5efe02725b14dff114c866724eff2cfd44d76cea74bcd87a" +checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e" dependencies = [ "libc", "pkg-config", @@ -4423,56 +4920,89 @@ dependencies = [ [[package]] name = "x11-dl" -version = "2.20.0" +version = "2.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c83627bc137605acc00bb399c7b908ef460b621fc37c953db2b09f88c449ea6" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" dependencies = [ - "lazy_static", "libc", + "once_cell", "pkg-config", ] [[package]] name = "xattr" -version = "0.2.3" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc" +checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" dependencies = [ "libc", + "linux-raw-sys", + "rustix", ] [[package]] -name = "xml-rs" -version = "0.8.4" +name = "xdg-home" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca91dcf8f93db085f3a0a29358cd0b9d670915468f4290e8b85d118a34211ab8" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "yansi" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + +[[package]] +name = "yoke" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", + "synstructure", +] [[package]] name = "zbus" -version = "2.3.2" +version = "4.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d8f1a037b2c4a67d9654dc7bdfa8ff2e80555bbefdd3c1833c1d1b27c963a6b" +checksum = "989c3977a7aafa97b12b9a35d21cdcff9b0d2289762b14683f45d66b1ba6c48f" dependencies = [ "async-broadcast", - "async-channel", "async-executor", + "async-fs", "async-io", "async-lock", + "async-process", "async-recursion", "async-task", "async-trait", - "byteorder", - "derivative", - "dirs", + "blocking", "enumflags2", "event-listener", "futures-core", "futures-sink", "futures-util", "hex", - "lazy_static", - "nix", - "once_cell", + "nix 0.28.0", "ordered-stream", "rand 0.8.5", "serde", @@ -4481,7 +5011,8 @@ dependencies = [ "static_assertions", "tracing", "uds_windows", - "winapi", + "windows-sys 0.52.0", + "xdg-home", "zbus_macros", "zbus_names", "zvariant", @@ -4489,37 +5020,79 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "2.3.2" +version = "4.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f8fb5186d1c87ae88cf234974c240671238b4a679158ad3b94ec465237349a6" +checksum = "6fe9de53245dcf426b7be226a4217dd5e339080e5d46e64a02d6e5dcbf90fca1" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "regex", - "syn 1.0.95", + "syn 2.0.66", + "zvariant_utils", ] [[package]] name = "zbus_names" -version = "2.2.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41a408fd8a352695690f53906dc7fd036be924ec51ea5e05666ff42685ed0af5" +checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c" dependencies = [ "serde", "static_assertions", "zvariant", ] +[[package]] +name = "zerofrom" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", + "synstructure", +] + +[[package]] +name = "zerovec" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb2cc8827d6c0994478a15c53f374f46fbd41bea663d809b14744bc42e6b109c" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97cf56601ee5052b4417d90c8755c6683473c926039908196cf35d99f893ebe7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "zvariant" -version = "3.7.1" +version = "4.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b794fb7f59af4105697b0449ba31731ee5dbb3e773a17dbdf3d36206ea1b1644" +checksum = "9aa6d31a02fbfb602bfde791de7fedeb9c2c18115b3d00f3a36e489f46ffbbc7" dependencies = [ - "byteorder", + "endi", "enumflags2", - "libc", "serde", "static_assertions", "zvariant_derive", @@ -4527,12 +5100,24 @@ dependencies = [ [[package]] name = "zvariant_derive" -version = "3.7.1" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "642bf1b6b6d527988b3e8193d20969d53700a36eac734d21ae6639db168701c8" +dependencies = [ + "proc-macro-crate 3.1.0", + "proc-macro2", + "quote", + "syn 2.0.66", + "zvariant_utils", +] + +[[package]] +name = "zvariant_utils" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd58d4b6c8e26d3dd2149c8c40c6613ef6451b9885ff1296d1ac86c388351a54" +checksum = "fc242db087efc22bd9ade7aa7809e4ba828132edc312871584a6b4391bdf8786" dependencies = [ - "proc-macro-crate", "proc-macro2", "quote", - "syn 1.0.95", + "syn 2.0.66", ] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..878335e --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,10 @@ +[workspace.package] +version = "0.3.0" +description = "Bluetooth battery monitor" +repository = "https://github.com/SARDONYX-sard/bluetooth-battery-monitor" +readme = "README.md" + +[workspace] +members = ["crates/bluetooth", "crates/timer", "gui/backend"] +default-members = ["crates/bluetooth"] +resolver = "2" diff --git a/LICENSE-MIT b/LICENSE-MIT index ee6066b..2ffb4c1 100644 --- a/LICENSE-MIT +++ b/LICENSE-MIT @@ -7,3 +7,4 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/Makefile b/Makefile deleted file mode 100644 index 52dbaed..0000000 --- a/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -default: dev - -# info|debug|error(default: debug) -LOG_LEVEL?=debug - -dev: deps - @echo "develop mode: log level(${LOG_LEVEL})" - @export RUST_LOG=${LOG_LEVEL} && cargo tauri dev - -build: deps - cargo tauri build - -gen-icon: - cargo tauri icon ./src-tauri/icons/icon.png - -deps: - cargo install tauri-cli - -update: - deno task esm:update - -fmt: - deno fmt www - cargo fmt - -lint: - deno lint www - cargo clippy - -.PHONY: dev build deps update fmt lint diff --git a/assets/default_settings.toml b/assets/default_settings.toml deleted file mode 100644 index 1c9a5f0..0000000 --- a/assets/default_settings.toml +++ /dev/null @@ -1,4 +0,0 @@ -[base] -autostart = true -battery_query_duration_minutes = 60 -notify_battery_level = 20 diff --git a/biome.jsonc b/biome.jsonc new file mode 100644 index 0000000..5786efa --- /dev/null +++ b/biome.jsonc @@ -0,0 +1,49 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.8.3/schema.json", + "extends": [], + "files": { + "ignore": ["out", ".next", "node_modules", "target", "./test"], + "ignoreUnknown": true + }, + "organizeImports": { + "enabled": true + }, + "formatter": { + "enabled": true, + "formatWithErrors": true, + "indentWidth": 2, + "indentStyle": "space", + "lineWidth": 120 + }, + "linter": { + "ignore": ["./tools/version_up.js"], + "rules": { + "all": true, + "performance": { + "noBarrelFile": "off", + "noReExportAll": "off" + }, + "style": { + "noDefaultExport": "off", + "noImplicitBoolean": "off" + } + } + }, + "javascript": { + "formatter": { + "quoteStyle": "single", + "jsxQuoteStyle": "single", + "trailingCommas": "all", + "semicolons": "always", + "arrowParentheses": "always" + }, + "globals": ["test", "it", "expect", "describe", "afterEach"] // Avoid warnings when calling the test functions. + }, + "json": { + "parser": { "allowComments": true }, + "formatter": { + "enabled": true, + "indentStyle": "space" + } + } +} diff --git a/bundle.ts b/bundle.ts deleted file mode 100644 index 711e59b..0000000 --- a/bundle.ts +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Usage: - * - * - * - dev: - * deno run -A ./bundle.ts --dev - * - * - watch-release: - * deno run -A ./bundle.ts --dev --release - * - * - build: - * deno run -A ./bundle.ts --build - * - * - build-release: - * deno run -A ./bundle.ts --release - */ - -import * as esbuild from "https://deno.land/x/esbuild@v0.17.14/mod.js"; -import { denoPlugin } from "https://deno.land/x/esbuild_deno_loader@0.6.0/mod.ts"; -import { parse } from "https://deno.land/std@0.181.0/flags/mod.ts"; - -const common_opts: esbuild.BuildOptions = { - plugins: [ - denoPlugin({ - // See: https://github.com/lucacasonato/esbuild_deno_loader/issues/29#issuecomment-1458880891 - importMapURL: new URL("./import_map.json", import.meta.url), - }) as unknown as esbuild.Plugin, - ], - entryPoints: ["./www/index.tsx"], - outfile: "./www/dist/main.js", - format: "esm", - bundle: true, -}; - -const dev_opts: esbuild.BuildOptions = { - sourcemap: true, -}; - -const release_opts: esbuild.BuildOptions = { - minify: true, - sourcemap: false, -}; - -async function build(opts: esbuild.BuildOptions) { - await esbuild.build({ ...common_opts, ...opts }); - esbuild.stop(); -} - -async function dev(opts: esbuild.BuildOptions) { - // https://github.com/evanw/esbuild/blob/main/CHANGELOG.md#0170 - const context = await esbuild.context({ - ...common_opts, - ...dev_opts, // overwrite common - ...opts, - }); - await context.watch(); - await context.serve({ - port: 3000, - servedir: "www", - }); -} - -const flags = parse(Deno.args, { - boolean: ["build", "dev", "release"], -}); - -const overwrite_opts = flags.release ? release_opts : {}; -if (flags.dev) { - dev(overwrite_opts); -} else if (flags.build || flags.release) { - build(overwrite_opts); -} diff --git a/crates/bluetooth/Cargo.toml b/crates/bluetooth/Cargo.toml new file mode 100644 index 0000000..8ff5048 --- /dev/null +++ b/crates/bluetooth/Cargo.toml @@ -0,0 +1,50 @@ +[package] +name = "bluetooth" +version.workspace = true +description = "Bluetooth" +authors = ["SARDONYX-sard"] +readme = "./readme.md" +license = "MIT OR Apache-2.0" +repository.workspace = true +edition = "2021" +rust-version = "1.70" + + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[features] +default = ["json", "tracing"] +tracing = ["dep:tracing"] +serde = ["dep:serde", "dep:serde_with"] +json = ["serde", "dep:serde_json"] + +[dependencies] +chrono = "0.4.38" +num-derive = "0.4" +num-traits = "0.2" +parse-display = "0.9.1" # Display derive +serde = { version = "1.0.204", features = [ + "derive", +], optional = true } # Implement (De)Serializer +serde_with = { version = "3.9.0", optional = true } +serde_json = { version = "1.0.120", optional = true } # Json converter +snafu = "0.8.3" # Define errors +tracing = { version = "0.1.40", optional = true } # Logger + +[target.'cfg(windows)'.dependencies] +windows = { version = "0.58.0", features = [ + "Devices_Bluetooth_Rfcomm", + "Devices_Enumeration", + "Foundation", + "Foundation_Collections", + "Win32_Devices_Bluetooth", + "Win32_Foundation", + "Win32_Networking_WinSock", + "Win32_System_Rpc", + "Win32_System_Threading", + "Win32_System_Registry", +] } + + +[dev-dependencies] +pretty_assertions = "1.4.0" +quick_tracing = { version = "0.1.5", features = ["derive"] } diff --git a/crates/bluetooth/readme.md b/crates/bluetooth/readme.md new file mode 100644 index 0000000..3f7300f --- /dev/null +++ b/crates/bluetooth/readme.md @@ -0,0 +1 @@ +# Bluetooth diff --git a/src-tauri/scripts/get-bluetooth-battery-all.ps1 b/crates/bluetooth/scripts/get-bluetooth-battery-all.ps1 similarity index 61% rename from src-tauri/scripts/get-bluetooth-battery-all.ps1 rename to crates/bluetooth/scripts/get-bluetooth-battery-all.ps1 index 21f9089..ce99bef 100644 --- a/src-tauri/scripts/get-bluetooth-battery-all.ps1 +++ b/crates/bluetooth/scripts/get-bluetooth-battery-all.ps1 @@ -1,8 +1,10 @@ # https://learn.microsoft.com/windows/client-management/mdm/policy-csp-bluetooth # Bluetooth Base UUID: "00000000-0000-1000-8000-00805F9B34FB" # BTBook.pdf P.8 -$local:BatteryServiceUuid = "0000111E-0000-1000-8000-00805F9B34FB" # Hands Free Profile (HFP)*: 0x111E + BASE UUID $local:BatteryLevel = '{104EA319-6EE2-4701-BD47-8DDBF425BBE5} 2' +$local:BatteryServiceUuid = "0000111E-0000-1000-8000-00805F9B34FB" # Hands Free Profile (HFP)*: 0x111E + BASE UUID $local:BluetoothAddressId = "DEVPKEY_Bluetooth_DeviceAddress" +$local:BluetoothClass = "DEVPKEY_Bluetooth_ClassOfDevice" +$local:LastArraivvalDate = "DEVPKEY_Device_LastArrivalDate" # Probably RFC3339 format # Get-PnpDevice -Class Bluetooth | Get-PnpDeviceProperty -KeyName "DEVPKEY_Bluetooth_LastConnectedTime" # Get-PnpDevice -Class AudioEndpoint | Select-Object FriendlyName, Status, InstanceId # is connected @@ -14,18 +16,30 @@ Get-PnpDevice -InstanceId "BTHENUM\{$local:BatteryServiceUuid}_*" | ForEach-Obje "friendly_name" = $_.friendlyName }; - Get-PnpDeviceProperty -InstanceId $_.InstanceId -KeyName $local:BatteryLevel, $local:BluetoothAddressId | + Get-PnpDeviceProperty -InstanceId $_.InstanceId -KeyName $local:BatteryLevel, $local:BluetoothAddressId, $local:BluetoothClass, $local:LastArraivvalDate | ForEach-Object { $local:data = $_.Data #! Note: Need local variable! otherwise it will be null. $local:keyname = $_.KeyName switch ($_.KeyName) { $local:BatteryLevel { $local:keyname = "battery_level" } $local:BluetoothAddressId { $local:keyname = "bluetooth_address" } + $local:BluetoothClass { $local:keyname = "bluetooth_class" } + $local:LastArraivvalDate { $local:keyname = "last_arrival_date" } + } + + if ($_.KeyName -eq $local:LastArraivvalDate) { + # NOTE: It must be a string or it will become a Date() object. + # 2001-07-08T00:34:60.026490+09:30 ISO 8601 / RFC 3339 date & time format. + # o: %Y-%m-%dT%H:%M:%S%.f%:z + $local:Properties += @{ $local:keyname = $local:data.toString("o") } + } + else { + $local:Properties += @{ $local:keyname = $local:data } } - $local:Properties += @{ $local:keyname = $local:data } } $Result += $Properties } -ConvertTo-Json -InputObject $local:Result + +ConvertTo-Json $local:Result # Read-Host "Press any key." diff --git a/crates/bluetooth/src/categories/category.rs b/crates/bluetooth/src/categories/category.rs new file mode 100644 index 0000000..bee6f9d --- /dev/null +++ b/crates/bluetooth/src/categories/category.rs @@ -0,0 +1,107 @@ +use super::sub_category::{MajorCategory, SubCategory, SubCategory4, SubCategory5}; +use crate::error::BluetoothError; +use num_traits::{FromPrimitive as _, ToPrimitive as _}; +use parse_display::{Display, FromStr}; + +/// `Category` +#[cfg_attr( + feature = "serde", + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Display, FromStr)] +#[display("{major}: {sub}")] +pub struct Category { + /// major category + pub major: MajorCategory, + /// sub category + pub sub: SubCategory, +} + +// This code is inspired from C++. +// See: https://github.com/joric/bluetooth-battery-monitor/blob/master/misc/bt_classic_test.cpp#L6 +impl TryFrom for Category { + type Error = BluetoothError; + + fn try_from(cod: u32) -> Result { + let major = (cod >> 8) & 0b00011111; + let minor = (cod >> 2) & 0b00111111; + + let sub = match major { + 4 => SubCategory::Category4(SubCategory4::from_u32(minor).unwrap_or_default()), + 5 => SubCategory::Category5(SubCategory5::from_u32(minor >> 4).unwrap_or_default()), + _ => SubCategory::None, + }; + let major = MajorCategory::from_u32(major).unwrap_or_default(); + + Ok(Self { major, sub }) + } +} + +impl TryFrom for u32 { + type Error = BluetoothError; + + fn try_from(value: Category) -> Result { + let Category { major, sub } = value; + + let major = MajorCategory::to_u32(&major) + .ok_or(BluetoothError::FailedToCastMajorCatError { major })?; + + let minor: u32 = match sub { + SubCategory::Category4(sub) => { + let minor = SubCategory4::to_u32(&sub) + .ok_or(BluetoothError::FailedToCastCat4Error { sub })?; + (minor & 0b00111111) << 2 + } + SubCategory::Category5(sub) => { + let minor = SubCategory5::to_u32(&sub) + .ok_or(BluetoothError::FailedToCastCat5Error { sub })?; + (minor & 0b00001111) << 4 + } + SubCategory::None => 0, + }; + + Ok((major << 8) | minor) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use pretty_assertions::assert_eq; + + #[test] + fn test_bluetooth_class_try_from_category() { + let category = Category { + major: MajorCategory::AudioVideo, + sub: SubCategory::Category4(SubCategory4::HandsFreeDevice), + }; + + let expected_cod = (MajorCategory::to_u32(&MajorCategory::AudioVideo).unwrap() << 8) + | ((SubCategory4::to_u32(&SubCategory4::HandsFreeDevice).unwrap() & 0b00111111) << 2); + + match u32::try_from(category) { + Ok(bt_class) => assert_eq!(bt_class, expected_cod), + Err(err) => panic!("Failed with error: {:?}", err), + } + } + + #[test] + fn test_category_try_from_bluetooth_class() { + let expected_category = Category { + major: MajorCategory::AudioVideo, + sub: SubCategory::Category4(SubCategory4::WearableHeadsetDevice), + }; + + let bt_class = 2360324; + match Category::try_from(bt_class) { + Ok(category) => assert_eq!(category, expected_category), + Err(err) => panic!("Failed with error: {:?}", err), + }; + + let expected_category = Category { + major: MajorCategory::AudioVideo, + sub: SubCategory::Category4(SubCategory4::Headphones), + }; + assert_eq!(Category::try_from(2360344).unwrap(), expected_category); + } +} diff --git a/crates/bluetooth/src/categories/mod.rs b/crates/bluetooth/src/categories/mod.rs new file mode 100644 index 0000000..1adc555 --- /dev/null +++ b/crates/bluetooth/src/categories/mod.rs @@ -0,0 +1,2 @@ +pub mod category; +pub mod sub_category; diff --git a/crates/bluetooth/src/categories/sub_category.rs b/crates/bluetooth/src/categories/sub_category.rs new file mode 100644 index 0000000..63c3995 --- /dev/null +++ b/crates/bluetooth/src/categories/sub_category.rs @@ -0,0 +1,158 @@ +use num_derive::{FromPrimitive, ToPrimitive}; +use parse_display::{Display, FromStr}; + +/// `MajorCategory` +#[cfg_attr( + feature = "serde", + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[derive( + Debug, + Clone, + Default, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + Display, + FromStr, + ToPrimitive, + FromPrimitive, +)] +pub enum MajorCategory { + Miscellaneous, + Computer, + Phone, + #[display("LAN/Network Access Point")] + LanNetworkAccessPoint, + #[display("Audio/Video")] + AudioVideo, + Peripheral, + Imaging, + Wearable, + Toy, + Health, + + /// This item does not exist in the category. + #[default] + Unknown, +} + +// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/// SubCategory 4 or 5 +#[cfg_attr( + feature = "serde", + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Display, FromStr)] +pub enum SubCategory { + #[display("{0}")] + Category4(SubCategory4), + #[display("{0}")] + Category5(SubCategory5), + #[default] + None, +} + +/// It is used when MajorCategory is 4. +#[cfg_attr( + feature = "serde", + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[derive( + Debug, + Clone, + Default, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + Display, + FromStr, + ToPrimitive, + FromPrimitive, +)] +pub enum SubCategory4 { + #[display("Uncategorized")] + #[default] + Uncategorized = 0, + + #[display("Wearable Headset Device")] + WearableHeadsetDevice = 1, + + #[display("Hands-free Device")] + HandsFreeDevice = 2, + + #[display("Microphone")] + Microphone = 4, + + #[display("Loudspeaker")] + Loudspeaker = 5, + + #[display("Headphones")] + Headphones = 6, + + #[display("Portable Audio")] + PortableAudio = 7, + + #[display("Car audio")] + CarAudio, + + #[display("Set-top box")] + SetTopBox, + + #[display("HiFi Audio Device")] + HiFiAudioDevice, + + #[display("VCR")] + Vcr, + + #[display("Video Camera")] + VideoCamera, + + #[display("Camcorder")] + Camcorder, + + #[display("Video Monitor")] + VideoMonitor, + + #[display("Video Display and Loudspeaker")] + VideoDisplayAndLoudspeaker, + + #[display("Video Conferencing")] + VideoConferencing, + + #[display("Gaming/Toy")] + GamingToy = 18, +} + +/// It is used when MajorCategory is 5. +#[cfg_attr( + feature = "serde", + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[derive( + Debug, + Clone, + Default, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + Display, + FromStr, + ToPrimitive, + FromPrimitive, +)] +pub enum SubCategory5 { + #[default] + Unknown, + Keyboard, + Mouse, + #[display("Keyboard/Mouse Combo")] + KeyboardMouseCombo, +} diff --git a/crates/bluetooth/src/device/device_info.rs b/crates/bluetooth/src/device/device_info.rs new file mode 100644 index 0000000..aa9c5e9 --- /dev/null +++ b/crates/bluetooth/src/device/device_info.rs @@ -0,0 +1,57 @@ +use crate::{categories::category::Category, error::Result}; + +/// Bluetooth battery info +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct BluetoothDeviceInfo { + /// e.g. `E500Pro Hands-Free AG` + pub friendly_name: String, + + /// e.g. `BTHENUM\\{0000111E-0000-1000-8000-00805F9B34FB}_LOCALMFG&005D...` + pub instance_id: String, + + pub address: u64, + + /// e.g. 80(%) + pub battery_level: u64, + + pub category: Category, + + pub is_connected: bool, + + /// Native time + /// e.g. `2024/4/19 22:42:16` + pub last_used: SystemTime, +} + +#[cfg_attr( + feature = "serde", + derive(serde_with::DeserializeFromStr, serde_with::SerializeDisplay,) +)] +#[derive( + Debug, + Clone, + Default, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + parse_display::Display, + parse_display::FromStr, +)] +#[display("{year}/{month}/{day} {hour}:{minute}:{second}")] +pub struct SystemTime { + pub year: u16, + pub month: u16, + pub day: u16, + pub hour: u16, + pub minute: u16, + pub second: u16, +} + +/// Cross-platform common methods +pub trait FindBluetooth { + /// Get Bluetooth devices information. + fn find_devices() -> Result>; +} diff --git a/crates/bluetooth/src/device/mod.rs b/crates/bluetooth/src/device/mod.rs new file mode 100644 index 0000000..64c17ad --- /dev/null +++ b/crates/bluetooth/src/device/mod.rs @@ -0,0 +1,3 @@ +pub mod device_info; +#[cfg(target_os = "windows")] +mod win; diff --git a/crates/bluetooth/src/device/win/battery.rs b/crates/bluetooth/src/device/win/battery.rs new file mode 100644 index 0000000..7d03ccf --- /dev/null +++ b/crates/bluetooth/src/device/win/battery.rs @@ -0,0 +1,71 @@ +use crate::serde_with_date::rfc3339_date_fmt; +use chrono::{DateTime, Utc}; + +/// Bluetooth battery info +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct BatteryInfo { + /// e.g. 80(%) + pub battery_level: u64, + + /// e.g. "00112233aabb" + pub bluetooth_address: String, + + /// e.g. `2360344` + pub bluetooth_class: u64, + + /// e.g. `E500Pro Hands-Free AG` + pub friendly_name: String, + + /// e.g. `BTHENUM\\{0000111E-0000-1000-8000-00805F9B34FB}_LOCALMFG&005D...` + pub instance_id: String, + + /// Probably RFC3339 format. + /// + /// e.g. "2024-06-09T12:43:36.636288+09:00" + #[cfg_attr(feature = "serde", serde(with = "rfc3339_date_fmt"))] + pub last_arrival_date: DateTime, +} + +#[cfg(feature = "json")] +mod device_serde { + use super::*; + use crate::error::Result; + use std::os::windows::process::CommandExt as _; + + /// https://learn.microsoft.com/en-us/windows/win32/procthread/process-creation-flags + struct CreateNoWindow(u32); + const CREATE_NO_WINDOW: CreateNoWindow = CreateNoWindow(0x08000000); + + impl BatteryInfo { + /// Create new Devices info from powershell command. + pub fn news_from_script() -> Result> { + let output = std::process::Command::new("powershell.exe") + .args([ + "-ExecutionPolicy", + "ByPass", + "-Command", + include_str!("../../../scripts/get-bluetooth-battery-all.ps1"), + ]) + .creation_flags(CREATE_NO_WINDOW.0) + .output()?; + let json_str = String::from_utf8_lossy(&output.stdout); + let devices = serde_json::from_str(json_str.trim())?; + + Ok(devices) + } + } +} + +#[cfg(test)] +mod tests { + use super::BatteryInfo; + + #[ignore = "Can't find it on CI."] + #[test] + #[quick_tracing::init] + fn get_devices() -> crate::error::Result<()> { + dbg!(BatteryInfo::news_from_script())?; + Ok(()) + } +} diff --git a/crates/bluetooth/src/device/win/device_searcher.rs b/crates/bluetooth/src/device/win/device_searcher.rs new file mode 100644 index 0000000..ec294d4 --- /dev/null +++ b/crates/bluetooth/src/device/win/device_searcher.rs @@ -0,0 +1,68 @@ +use crate::error::Result; +use std::{collections::HashMap, mem, ptr}; +use windows::Win32::{ + Devices::Bluetooth::{ + BluetoothFindDeviceClose, BluetoothFindFirstDevice, BluetoothFindNextDevice, + BluetoothGetDeviceInfo, BLUETOOTH_DEVICE_SEARCH_PARAMS, + }, + Foundation::{FALSE, HANDLE, TRUE}, +}; + +pub type SysBluetoothDeviceInfo = windows::Win32::Devices::Bluetooth::BLUETOOTH_DEVICE_INFO; + +pub fn get_bluetooth_devices() -> Result> { + // See: https://learn.microsoft.com/windows/win32/api/bluetoothapis/ns-bluetoothapis-bluetooth_device_search_params + let search_params: BLUETOOTH_DEVICE_SEARCH_PARAMS = BLUETOOTH_DEVICE_SEARCH_PARAMS { + // size of the structure (in bytes). + dwSize: core::mem::size_of::() as u32, + // A value indicating that an authenticated Bluetooth device must be returned in the search. + fReturnAuthenticated: FALSE, + // value indicating that a remembered Bluetooth device must be returned in the search. + fReturnRemembered: TRUE, + // value that specifies that the search should return an unknown Bluetooth device. + fReturnUnknown: TRUE, + // a value indicating that the search must return connected Bluetooth devices. + fReturnConnected: FALSE, + // a value indicating that a new inquiry needs to be issued. + fIssueInquiry: TRUE, + // A value indicating the inquiry timeout, expressed in 1.28 second increments. + // For example, the cTimeoutMultiplier value for a 12.8 second inquiry is 10. + // The maximum value for this member is 48. If a value greater than 48 is used, + // the calling function will fail immediately and return E_INVALIDARG. + cTimeoutMultiplier: 2, + // Handle to the radio to perform the query. Set to NULL to perform the query on all local Bluetooth radios. + hRadio: HANDLE(ptr::null_mut()), + }; + + let mut device_info = SysBluetoothDeviceInfo { + dwSize: mem::size_of::() as u32, + ..Default::default() + }; + + let search_handle = unsafe { BluetoothFindFirstDevice(&search_params, &mut device_info)? }; + if search_handle.is_invalid() { + return Err(windows::core::Error::from_win32().into()); + }; + + let mut res = HashMap::new(); + loop { + match unsafe { BluetoothGetDeviceInfo(HANDLE(search_handle.0), &mut device_info) } { + err_code if err_code != 0 => { + #[cfg(feature = "tracing")] + tracing::error!("Error code: {err_code}"); + break; + } + result => result, + }; + let addr = unsafe { device_info.Address.Anonymous.ullLong }; + res.insert(addr, device_info); + + if unsafe { BluetoothFindNextDevice(search_handle, &mut device_info).is_err() } { + break; + } + } + + unsafe { BluetoothFindDeviceClose(search_handle)? }; + + Ok(res) +} diff --git a/crates/bluetooth/src/device/win/mod.rs b/crates/bluetooth/src/device/win/mod.rs new file mode 100644 index 0000000..f2042cb --- /dev/null +++ b/crates/bluetooth/src/device/win/mod.rs @@ -0,0 +1,68 @@ +pub mod battery; +pub mod device_searcher; +mod register; + +use super::device_info::{BluetoothDeviceInfo, FindBluetooth, SystemTime}; +use crate::{categories::category::Category, error::Result}; +use battery::BatteryInfo; +use device_searcher::{get_bluetooth_devices, SysBluetoothDeviceInfo}; +use std::collections::HashMap; + +impl BluetoothDeviceInfo { + fn from(battery_info: BatteryInfo, device_info: SysBluetoothDeviceInfo) -> Result { + Ok(Self { + friendly_name: battery_info.friendly_name, + category: Category::try_from(device_info.ulClassofDevice)?, + battery_level: battery_info.battery_level, + is_connected: device_info.fConnected.as_bool(), + instance_id: battery_info.instance_id, + address: unsafe { device_info.Address.Anonymous.ullLong }, + last_used: SystemTime { + year: device_info.stLastUsed.wYear, + month: device_info.stLastUsed.wMonth, + day: device_info.stLastUsed.wDay, + hour: device_info.stLastUsed.wHour, + minute: device_info.stLastUsed.wMinute, + second: device_info.stLastUsed.wSecond, + }, + }) + } + + /// Merge device info and new device info + fn merge_devices( + batteries: Vec, + devices: HashMap, + ) -> Result> { + let mut res = vec![]; + for battery_info in batteries { + let addr = u64::from_str_radix(&battery_info.bluetooth_address, 16)?; + if let Some(dev) = devices.get(&addr) { + res.push(Self::from(battery_info, *dev)?); + }; + } + Ok(res) + } +} + +// Implement common trait +impl FindBluetooth for BluetoothDeviceInfo { + /// Finds the bluetooth devices. (This is windows edition) + fn find_devices() -> Result> { + let devices = get_bluetooth_devices()?; + let batteries = BatteryInfo::news_from_script()?; + BluetoothDeviceInfo::merge_devices(batteries, devices) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[ignore = "Can't find it on CI."] + #[test] + fn test_get_devices_info() -> Result<()> { + let dev = BluetoothDeviceInfo::find_devices()?; + println!("{:#?}", dev); + Ok(()) + } +} diff --git a/crates/bluetooth/src/device/win/register.rs b/crates/bluetooth/src/device/win/register.rs new file mode 100644 index 0000000..e5874e4 --- /dev/null +++ b/crates/bluetooth/src/device/win/register.rs @@ -0,0 +1,122 @@ +use windows::core::HSTRING; +use windows::core::{imp::CreateEventW, PCWSTR}; +use windows::Win32::Foundation::{CloseHandle, HANDLE, WAIT_OBJECT_0}; +use windows::Win32::System::Registry::{ + RegCloseKey, RegNotifyChangeKeyValue, RegOpenKeyExW, RegQueryValueExW, HKEY, + HKEY_LOCAL_MACHINE, KEY_NOTIFY, KEY_READ, REG_NOTIFY_CHANGE_LAST_SET, REG_NOTIFY_CHANGE_NAME, +}; +use windows::Win32::System::Threading::{ResetEvent, WaitForSingleObject, INFINITE}; + +#[allow(unused)] +pub fn watch(target_key: &str) -> windows::core::Result<()> { + unsafe { + let h_event = HANDLE(CreateEventW( + core::ptr::null(), + 1, + 0, + HSTRING::from("RegistryNotificationEvent").as_ptr(), + )); + if h_event.is_invalid() { + #[cfg(feature = "tracing")] + tracing::error!("CreateEvent error"); + return Ok(()); + } + + #[cfg(feature = "tracing")] + tracing::trace!("RegOpenKeyExW entered"); + let sub_key = HSTRING::from(target_key); + let mut h_key = HKEY::default(); + RegOpenKeyExW( + HKEY_LOCAL_MACHINE, + &sub_key, + 0, + KEY_NOTIFY | KEY_READ, + // KEY_READ, + &mut h_key, + ) + .ok()?; + #[cfg(feature = "tracing")] + tracing::trace!("RegOpenKeyExW passed"); + read_reg_value(h_key)?; + + loop { + // Watch the registry key for a change of value. + RegNotifyChangeKeyValue( + h_key, + true, + REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET, + h_event, + true, + ) + .ok()?; + #[cfg(feature = "tracing")] + tracing::trace!("RegNotifyChangeKeyValue passed"); + + if WaitForSingleObject(h_event, INFINITE) == WAIT_OBJECT_0 { + #[cfg(feature = "tracing")] + tracing::trace!("Registry Change Notification"); + + read_reg_value(h_key)?; + } else { + break; + } + + ResetEvent(h_event)?; + } + + RegCloseKey(h_key).ok()?; + CloseHandle(h_event)?; + #[cfg(feature = "tracing")] + tracing::trace!("Exit"); + } + Ok(()) +} + +/// Retrieve the registry value +unsafe fn read_reg_value(h_key: HKEY) -> windows::core::Result<[u8; 1024]> { + // Retrieve the registry value + let mut data = [0; 1024]; + let mut data_len = data.len() as u32; + + match RegQueryValueExW( + h_key, + PCWSTR::null(), + None, + None, + Some(data.as_mut_ptr() as *mut _), + Some(&mut data_len), + ) + .ok() + { + Ok(_) => { + #[cfg(feature = "tracing")] + { + tracing::debug!("Registry Value: {data:?}"); + } + } + Err(e) => { + #[cfg(feature = "tracing")] + tracing::error!("Failed to get registry value: {e}"); + } + } + Ok(data) +} + +#[cfg(test)] +mod tests { + #[allow(unused)] + use super::*; + + #[ignore = "Can't watch it on CI."] + #[cfg_attr(feature = "tracing", quick_tracing::try_init)] + #[test] + fn watch_test() -> crate::error::Result<()> { + // let instance_id = include_str!("../../../../../secrets/instance_id.txt"); + // let key = &format!( + // r"SYSTEM\Setup\Upgrade\PnP\CurrentControlSet\Control\DeviceMigration\Devices\{instance_id}\Properties\{{104ea319-6ee2-4701-bd47-8ddbf425bbe5}}\0002" + // ); + + // watch(key)?; + Ok(()) + } +} diff --git a/crates/bluetooth/src/error.rs b/crates/bluetooth/src/error.rs new file mode 100644 index 0000000..5d13639 --- /dev/null +++ b/crates/bluetooth/src/error.rs @@ -0,0 +1,30 @@ +//! Error types for Converter + +use crate::categories::sub_category::{MajorCategory, SubCategory4, SubCategory5}; + +/// Each variant of the enum represents a specific type of error, +/// such as error messages or other relevant information. +#[derive(Debug, snafu::Snafu)] +#[snafu(visibility(pub))] +pub enum BluetoothError { + #[snafu(display("Failed to cast major category as u32: {major}"))] + FailedToCastMajorCatError { major: MajorCategory }, + #[snafu(display("Failed to cast sub category4 as u32: {sub}"))] + FailedToCastCat4Error { sub: SubCategory4 }, + #[snafu(display("Failed to cast sub category5 as u32: {sub}"))] + FailedToCastCat5Error { sub: SubCategory5 }, + + #[snafu(transparent)] + ParseIntError { source: core::num::ParseIntError }, + #[snafu(transparent)] + IoError { source: std::io::Error }, + #[snafu(transparent)] + JsonError { source: serde_json::Error }, + + #[snafu(transparent)] + #[cfg(target_os = "windows")] + Error { source: windows::core::Error }, +} + +/// A specialized [Result] type +pub type Result = core::result::Result; diff --git a/crates/bluetooth/src/lib.rs b/crates/bluetooth/src/lib.rs new file mode 100644 index 0000000..d908dc0 --- /dev/null +++ b/crates/bluetooth/src/lib.rs @@ -0,0 +1,7 @@ +#[doc = include_str!("../readme.md")] +mod categories; +pub mod device; +pub mod error; +pub(crate) mod serde_with_date; + +pub use device::device_info::BluetoothDeviceInfo; diff --git a/crates/bluetooth/src/serde_with_date.rs b/crates/bluetooth/src/serde_with_date.rs new file mode 100644 index 0000000..3f2a228 --- /dev/null +++ b/crates/bluetooth/src/serde_with_date.rs @@ -0,0 +1,42 @@ +/// `2001-07-08T00:34:60.026490+09:30` ISO 8601 / RFC 3339 date & time format. +/// +/// See: https://docs.rs/chrono/latest/chrono/format/strftime/index.html +pub mod rfc3339_date_fmt { + use chrono::{DateTime, NaiveDateTime, Utc}; + use serde::{self, Deserialize, Deserializer, Serializer}; + + // `2001-07-08T00:34:60.026490+09:30` ISO 8601 / RFC 3339 date & time format. + const FORMAT: &str = "%Y-%m-%dT%H:%M:%S%.f%:z"; + + // The signature of a serialize_with function must follow the pattern: + // + // fn serialize(&T, S) -> Result + // where + // S: Serializer + // + // although it may also be generic over the input types T. + pub fn serialize(date: &DateTime, serializer: S) -> Result + where + S: Serializer, + { + let s = format!("{}", date.format(FORMAT)); + serializer.serialize_str(&s) + } + + // The signature of a deserialize_with function must follow the pattern: + // + // fn deserialize<'de, D>(D) -> Result + // where + // D: Deserializer<'de> + // + // although it may also be generic over the output types T. + pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> + where + D: Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + tracing::debug!(s); + let dt = NaiveDateTime::parse_from_str(&s, FORMAT).map_err(serde::de::Error::custom)?; + Ok(DateTime::::from_naive_utc_and_offset(dt, Utc)) + } +} diff --git a/crates/timer/Cargo.toml b/crates/timer/Cargo.toml new file mode 100644 index 0000000..89813e3 --- /dev/null +++ b/crates/timer/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "timer" +version.workspace = true +description = "JavaScript like timer." +authors = ["SARDONYX-sard"] +readme = "./readme.md" +license = "MIT OR Apache-2.0" +repository.workspace = true +edition = "2021" +rust-version = "1.70" + + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[dependencies] +dashmap = "5.5.3" # Concurrent Hashmap +once_cell = { version = "1.17.1" } +snafu = "0.8.3" # Define errors +tokio = { version = "1.38.0", features = ["time", "sync"] } + + +[dev-dependencies] +pretty_assertions = "1.4.0" +quick_tracing = { version = "0.1.5", features = ["derive"] } +tokio = { version = "1.38.0", features = ["time", "macros", "rt"] } +tracing = { version = "0.1.40" } # Logger diff --git a/crates/timer/src/lib.rs b/crates/timer/src/lib.rs new file mode 100644 index 0000000..97299b6 --- /dev/null +++ b/crates/timer/src/lib.rs @@ -0,0 +1,132 @@ +use std::sync::{ + atomic::{AtomicU64, Ordering}, + Arc, +}; +use std::time::Duration; +use std::{future::Future, sync::atomic::AtomicBool}; + +use dashmap::DashMap; +use once_cell::sync::Lazy; +use tokio::spawn; +use tokio::task::JoinHandle; +use tokio::time::interval; + +/// Represents a process that executes a callback function at regular intervals. +struct IntervalProcess { + handle: Option>, + running: Arc, +} + +impl IntervalProcess { + fn new() -> Self { + Self { + handle: None, + running: Arc::new(AtomicBool::new(false)), + } + } + + /// Starts the interval process with the given callback and interval duration. + fn start(&mut self, mut callback: F, duration: Duration) + where + F: FnMut() -> Fut + Send + 'static + Sync, + Fut: Future + Send + 'static + Sync, + { + let running = self.running.clone(); + self.handle = Some(spawn(async move { + let mut sleep_time = interval(duration); + loop { + sleep_time.tick().await; + if !running.load(Ordering::Relaxed) { + break; + } + callback().await; + } + })); + self.running.store(true, Ordering::Relaxed); + } + + /// Stops the interval process. + fn stop(&mut self) { + self.running.store(false, Ordering::Relaxed); + if let Some(handle) = self.handle.take() { + tokio::spawn(async move { + handle.abort(); + }); + } + } +} + +static INTERVAL_PROCESSES: Lazy> = Lazy::new(DashMap::new); +static NEXT_ID: AtomicU64 = AtomicU64::new(1); + +/// Registers a callback function to be executed at the specified interval duration. +/// Returns a unique ID for the registered interval. +pub async fn set_interval(callback: F, duration: Duration) -> u64 +where + F: FnMut() -> Fut + Send + 'static + Sync, + Fut: Future + Send + 'static + Sync, +{ + let id = NEXT_ID.fetch_add(1, Ordering::Relaxed); + let mut interval_process = IntervalProcess::new(); + interval_process.start(callback, duration); + INTERVAL_PROCESSES.insert(id, interval_process); + id +} + +/// Stops the interval process associated with the given ID. +pub async fn clear_interval(id: u64) { + if let Some(mut interval_process) = INTERVAL_PROCESSES.remove(&id).map(|e| e.1) { + interval_process.stop(); + } +} + +/// Is running interval process? +pub async fn is_running_interval(id: u64) -> bool { + INTERVAL_PROCESSES + .get(&id) + .map_or(false, |process| process.running.load(Ordering::Relaxed)) +} + +#[cfg(test)] +mod tests { + use crate::{clear_interval, is_running_interval, set_interval}; + use std::time::Duration; + use tokio::sync::mpsc; + + #[tokio::test] + #[quick_tracing::try_init] + async fn test_interval_process() -> std::io::Result<()> { + let (tx, mut rx) = mpsc::channel(4); + let send_array = [1, 2, 3, 4, 5]; + + let mut index = 0; + let id = set_interval( + move || { + let tx = tx.clone(); + let val = send_array[index]; + index = index.wrapping_add(1); + async move { + tracing::trace!("try send: {val}"); + + if let Err(e) = tx.send(val).await { + tracing::error!("{e}"); + }; + } + }, + Duration::from_secs(1), + ) + .await; + + for expected_val in &send_array { + let res_val = rx.recv().await.unwrap(); + + tracing::trace!(res_val); + assert_eq!(res_val, *expected_val); + } + + assert!(is_running_interval(id).await); + clear_interval(id).await; + assert!(!is_running_interval(id).await); + Ok(()) + } +} diff --git a/cspell.json b/cspell.json deleted file mode 100644 index 40079a7..0000000 --- a/cspell.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "words": [ - "Airpods", - "Classof", - "INVALIDARG", - "Kimlim", - "Maximillian", - "SYSTEMTIME", - "Tabler", - "Uncategorized", - "bgcolor", - "bincode", - "clsx", - "fullscreen", - "outfile", - "servedir", - "tauri", - "twind", - "xplorer" - ] -} diff --git a/cspell.jsonc b/cspell.jsonc new file mode 100644 index 0000000..9952447 --- /dev/null +++ b/cspell.jsonc @@ -0,0 +1,15 @@ +{ + "words": [ + "BTHENUM", + "Classof", + "dashmap", + "HKEY", + "HSTRING", + "LOCALMFG", + "PCSTR", + "PCWSTR", + "repr", + "tauri", + "Uncategorized" + ] +} diff --git a/deno.jsonc b/deno.jsonc deleted file mode 100644 index 35026a3..0000000 --- a/deno.jsonc +++ /dev/null @@ -1,24 +0,0 @@ -{ - "compilerOptions": { - "lib": [ - "dom", - "dom.iterable", - "dom.asynciterable", - // https://deno.land/manual@v1.32.2/advanced/typescript/configuration#using-the-lib-property - "deno.ns" // For build scripts - ] - }, - "lint": { - "files": { - "exclude": [ - "www/dist" - ] - } - }, - "importMap": "./import_map.json", - "tasks": { - "esm:add": "deno run -A https://esm.sh/v113 add", - "esm:update": "deno run -A https://esm.sh/v113 update", - "esm:remove": "deno run -A https://esm.sh/v113 remove" - } -} diff --git a/deno.lock b/deno.lock deleted file mode 100644 index d6bb254..0000000 --- a/deno.lock +++ /dev/null @@ -1,93 +0,0 @@ -{ - "version": "2", - "remote": { - "https://deno.land/std@0.139.0/_util/assert.ts": "e94f2eb37cebd7f199952e242c77654e43333c1ac4c5c700e929ea3aa5489f74", - "https://deno.land/std@0.139.0/_util/os.ts": "49b92edea1e82ba295ec946de8ffd956ed123e2948d9bd1d3e901b04e4307617", - "https://deno.land/std@0.139.0/path/_constants.ts": "df1db3ffa6dd6d1252cc9617e5d72165cd2483df90e93833e13580687b6083c3", - "https://deno.land/std@0.139.0/path/_interface.ts": "ee3b431a336b80cf445441109d089b70d87d5e248f4f90ff906820889ecf8d09", - "https://deno.land/std@0.139.0/path/_util.ts": "c1e9686d0164e29f7d880b2158971d805b6e0efc3110d0b3e24e4b8af2190d2b", - "https://deno.land/std@0.139.0/path/common.ts": "bee563630abd2d97f99d83c96c2fa0cca7cee103e8cb4e7699ec4d5db7bd2633", - "https://deno.land/std@0.139.0/path/glob.ts": "cb5255638de1048973c3e69e420c77dc04f75755524cb3b2e160fe9277d939ee", - "https://deno.land/std@0.139.0/path/mod.ts": "d3e68d0abb393fb0bf94a6d07c46ec31dc755b544b13144dee931d8d5f06a52d", - "https://deno.land/std@0.139.0/path/posix.ts": "293cdaec3ecccec0a9cc2b534302dfe308adb6f10861fa183275d6695faace44", - "https://deno.land/std@0.139.0/path/separator.ts": "fe1816cb765a8068afb3e8f13ad272351c85cbc739af56dacfc7d93d710fe0f9", - "https://deno.land/std@0.139.0/path/win32.ts": "31811536855e19ba37a999cd8d1b62078235548d67902ece4aa6b814596dd757", - "https://deno.land/std@0.150.0/_util/assert.ts": "e94f2eb37cebd7f199952e242c77654e43333c1ac4c5c700e929ea3aa5489f74", - "https://deno.land/std@0.150.0/_util/os.ts": "3b4c6e27febd119d36a416d7a97bd3b0251b77c88942c8f16ee5953ea13e2e49", - "https://deno.land/std@0.150.0/path/_constants.ts": "df1db3ffa6dd6d1252cc9617e5d72165cd2483df90e93833e13580687b6083c3", - "https://deno.land/std@0.150.0/path/_interface.ts": "ee3b431a336b80cf445441109d089b70d87d5e248f4f90ff906820889ecf8d09", - "https://deno.land/std@0.150.0/path/_util.ts": "c1e9686d0164e29f7d880b2158971d805b6e0efc3110d0b3e24e4b8af2190d2b", - "https://deno.land/std@0.150.0/path/common.ts": "bee563630abd2d97f99d83c96c2fa0cca7cee103e8cb4e7699ec4d5db7bd2633", - "https://deno.land/std@0.150.0/path/glob.ts": "cb5255638de1048973c3e69e420c77dc04f75755524cb3b2e160fe9277d939ee", - "https://deno.land/std@0.150.0/path/mod.ts": "4945b430b759b0b3d98f2a278542cbcf95e0ad2bd8eaaed3c67322b306b2b346", - "https://deno.land/std@0.150.0/path/posix.ts": "c1f7afe274290ea0b51da07ee205653b2964bd74909a82deb07b69a6cc383aaa", - "https://deno.land/std@0.150.0/path/separator.ts": "fe1816cb765a8068afb3e8f13ad272351c85cbc739af56dacfc7d93d710fe0f9", - "https://deno.land/std@0.150.0/path/win32.ts": "bd7549042e37879c68ff2f8576a25950abbfca1d696d41d82c7bca0b7e6f452c", - "https://deno.land/std@0.156.0/_util/assert.ts": "e94f2eb37cebd7f199952e242c77654e43333c1ac4c5c700e929ea3aa5489f74", - "https://deno.land/std@0.156.0/_util/os.ts": "3b4c6e27febd119d36a416d7a97bd3b0251b77c88942c8f16ee5953ea13e2e49", - "https://deno.land/std@0.156.0/path/_constants.ts": "df1db3ffa6dd6d1252cc9617e5d72165cd2483df90e93833e13580687b6083c3", - "https://deno.land/std@0.156.0/path/_interface.ts": "ee3b431a336b80cf445441109d089b70d87d5e248f4f90ff906820889ecf8d09", - "https://deno.land/std@0.156.0/path/_util.ts": "d16be2a16e1204b65f9d0dfc54a9bc472cafe5f4a190b3c8471ec2016ccd1677", - "https://deno.land/std@0.156.0/path/common.ts": "bee563630abd2d97f99d83c96c2fa0cca7cee103e8cb4e7699ec4d5db7bd2633", - "https://deno.land/std@0.156.0/path/glob.ts": "cb5255638de1048973c3e69e420c77dc04f75755524cb3b2e160fe9277d939ee", - "https://deno.land/std@0.156.0/path/mod.ts": "56fec03ad0ebd61b6ab39ddb9b0ddb4c4a5c9f2f4f632e09dd37ec9ebfd722ac", - "https://deno.land/std@0.156.0/path/posix.ts": "c1f7afe274290ea0b51da07ee205653b2964bd74909a82deb07b69a6cc383aaa", - "https://deno.land/std@0.156.0/path/separator.ts": "fe1816cb765a8068afb3e8f13ad272351c85cbc739af56dacfc7d93d710fe0f9", - "https://deno.land/std@0.156.0/path/win32.ts": "bd7549042e37879c68ff2f8576a25950abbfca1d696d41d82c7bca0b7e6f452c", - "https://deno.land/std@0.181.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462", - "https://deno.land/std@0.181.0/flags/mod.ts": "4d829c5bd1d657799cdeb487c6e418960efc6f4d8ce6cadc38a54b9ce266160a", - "https://deno.land/x/denoflate@1.2.1/mod.ts": "f5628e44b80b3d80ed525afa2ba0f12408e3849db817d47a883b801f9ce69dd6", - "https://deno.land/x/denoflate@1.2.1/pkg/denoflate.js": "b9f9ad9457d3f12f28b1fb35c555f57443427f74decb403113d67364e4f2caf4", - "https://deno.land/x/denoflate@1.2.1/pkg/denoflate_bg.wasm.js": "d581956245407a2115a3d7e8d85a9641c032940a8e810acbd59ca86afd34d44d", - "https://deno.land/x/esbuild@v0.14.39/mod.d.ts": "d43b31f590e0fefd3f0ed8dbb359adbf3a8de43f44be31dcc18bdc9756288d06", - "https://deno.land/x/esbuild@v0.14.39/mod.js": "1647973ebe7c18a72325c782785f8525aec8e303d3a9e656a760493f24b91bbb", - "https://deno.land/x/esbuild@v0.14.51/mod.d.ts": "c142324d0383c39de0d7660cd207a7f7f52c7198a13d7d3281c0d636a070f441", - "https://deno.land/x/esbuild@v0.15.10/mod.d.ts": "12e96a8d05c8e2c5638aa9cb09f24222134d437abb2f3f52de0156adb2270719", - "https://deno.land/x/esbuild@v0.15.8/mod.d.ts": "5fe9b6ab2fc6b10e3b953170df8ad42bd63108dc9bfcc0cdc08c46b3a6e19cd6", - "https://deno.land/x/esbuild@v0.15.8/mod.js": "4ae3449516928ffe46cbf60e62341ad9639d7c93072484dd8319c911d558d25e", - "https://deno.land/x/esbuild@v0.17.14/mod.d.ts": "dc279a3a46f084484453e617c0cabcd5b8bd1920c0e562e4ea02dfc828c8f968", - "https://deno.land/x/esbuild@v0.17.14/mod.js": "d78cf4eb369477e20987c3024c140a53c4d95b7c4f1ecb8132e684c3b6504ddc", - "https://deno.land/x/esbuild_deno_loader@0.4.3/deps.ts": "e56a7fdf5ba7661f775a5708890c82fa8795c0bc9c66443acfb6610331c0c0e2", - "https://deno.land/x/esbuild_deno_loader@0.4.3/mod.ts": "4fb6e08dcd27d5a2a0cf53d9ab78926ecf815c5e6330dc36abbd7e9cdf0dd431", - "https://deno.land/x/esbuild_deno_loader@0.4.3/src/deno.ts": "85afaeccf84c2a57c934a29f823037b6c5d7ea67758658f4e663e5d7dd03b7de", - "https://deno.land/x/esbuild_deno_loader@0.4.3/src/native_loader.ts": "8d648385729b4635d473f019635d1e52f1a6d5a842130b6acf03f1924ae3b0c7", - "https://deno.land/x/esbuild_deno_loader@0.4.3/src/portable_loader.ts": "88b53cf8d6ffcf17f8c7a59724c2f050a33f02db28fe88a89dd2a24886acce78", - "https://deno.land/x/esbuild_deno_loader@0.5.2/deps.ts": "bf83c27b7787b2f245fa0bc0b99f5041aa949c000a81c016cfe828d06b476d37", - "https://deno.land/x/esbuild_deno_loader@0.5.2/mod.ts": "bc111a68f323dbdb6edec68dd558ab732b27866d2ef304708872d763387b65d7", - "https://deno.land/x/esbuild_deno_loader@0.5.2/src/deno.ts": "0e83ccabbe2b004389288e38df2031b79eb347df2d139fce9394d8e88a11f259", - "https://deno.land/x/esbuild_deno_loader@0.5.2/src/native_loader.ts": "343854a566cf510cf25144f7c09fc0c1097780a31830305142a075d12bb697ba", - "https://deno.land/x/esbuild_deno_loader@0.5.2/src/portable_loader.ts": "35b6c526eed8c2c781a3256b23c30aa7cce69c0ef1d583c15528663287ba18a3", - "https://deno.land/x/esbuild_deno_loader@0.5.2/src/shared.ts": "b64749cd8c0f6252a11498bd8758ef1220003e46b2c9b68e16da63fd7e92b13a", - "https://deno.land/x/esbuild_deno_loader@0.6.0/deps.ts": "fe86f62cb954edc2580868cdc3292d4446f22cd2c4eedbf8ee26513fdf74e343", - "https://deno.land/x/esbuild_deno_loader@0.6.0/mod.ts": "5d8a429b26c70f9fd522a8629e751f3bdf63680da473e537bc420d552ee3bf0b", - "https://deno.land/x/esbuild_deno_loader@0.6.0/src/deno.ts": "0e83ccabbe2b004389288e38df2031b79eb347df2d139fce9394d8e88a11f259", - "https://deno.land/x/esbuild_deno_loader@0.6.0/src/native_loader.ts": "343854a566cf510cf25144f7c09fc0c1097780a31830305142a075d12bb697ba", - "https://deno.land/x/esbuild_deno_loader@0.6.0/src/portable_loader.ts": "35b6c526eed8c2c781a3256b23c30aa7cce69c0ef1d583c15528663287ba18a3", - "https://deno.land/x/esbuild_deno_loader@0.6.0/src/shared.ts": "b64749cd8c0f6252a11498bd8758ef1220003e46b2c9b68e16da63fd7e92b13a", - "https://deno.land/x/importmap@0.2.1/_util.ts": "ada9a9618b537e6c0316c048a898352396c882b9f2de38aba18fd3f2950ede89", - "https://deno.land/x/importmap@0.2.1/mod.ts": "ae3d1cd7eabd18c01a4960d57db471126b020f23b37ef14e1359bbb949227ade" - }, - "npm": { - "specifiers": { - "create-serve": "create-serve@1.0.1", - "esbuild-serve": "esbuild-serve@1.0.1" - }, - "packages": { - "create-serve@1.0.1": { - "integrity": "sha512-cDAmBGhkwolS7ihq7SnPE8KwjYUZl5FaI9Pq5ZBwNelSKvFR9OoAA4/B5BfB/NC+eYaykBpX9RVMfuU4DHtrPw==", - "dependencies": {} - }, - "esbuild-serve@1.0.1": { - "integrity": "sha512-VvYDThNuwg+YAuZC+RqAgw9TpEVGoDdcvm2mTL0lU+TxDXr+QGZfJ+zc6m7cXeJ940qijvdTSZl3mQbRGN4/PA==", - "dependencies": { - "create-serve": "create-serve@1.0.1", - "esbuild": "esbuild@0.9.7" - } - }, - "esbuild@0.9.7": { - "integrity": "sha512-VtUf6aQ89VTmMLKrWHYG50uByMF4JQlVysb8dmg6cOgW8JnFCipmz7p+HNBl+RR3LLCuBxFGVauAe2wfnF9bLg==", - "dependencies": {} - } - } - } -} diff --git a/gui/backend/Cargo.toml b/gui/backend/Cargo.toml new file mode 100644 index 0000000..7c52bf5 --- /dev/null +++ b/gui/backend/Cargo.toml @@ -0,0 +1,53 @@ +[package] +name = "bluetooth_battery_monitor_gui" +version.workspace = true +description = "Bluetooth battery monitor GUI" +authors = ["SARDONYX-sard"] +readme = "./readme.md" +license = "MIT OR Apache-2.0" +repository.workspace = true +edition = "2021" +rust-version = "1.60" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[build-dependencies] +tauri-build = { version = "1.5.2", features = [] } + +[dependencies] +anyhow = "1.0.86" +chrono = "0.4.38" +bluetooth = { path = "../../crates/bluetooth", features = ["tracing"] } +once_cell = "1.19.0" +serde = { version = "1.0.204", features = [ + "derive", +] } # Implement (De)Serializer +serde_json = { version = "1.0.120" } # Json converter +tauri-plugin-autostart = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" } +# There is a bug that the window is displayed in the upper state when using a plugin(`tauri-plugin-window-state`) that saves the state. +# see: https://github.com/tauri-apps/tauri/issues/7669#issuecomment-2068731069 +tauri = { version = "1.7.1", features = [ + "devtools", + "dialog-open", + "dialog-save", + "fs-all", + "icon-ico", + "icon-png", + "notification-all", + "path-all", + "shell-all", + "system-tray", +] } # For GUI +tracing = "0.1.40" +tracing-subscriber = "0.3.18" +timer = { path = "../../crates/timer" } + +[dev-dependencies] +pretty_assertions = "1.4.0" +temp-dir = "0.1.13" +tracing-appender = "0.2.3" + +[features] +# this feature is used for production builds or when `devPath` points to the filesystem and the built-in dev server is disabled. +# If you use cargo directly instead of tauri's cli you can use this feature flag to switch between tauri's `dev` and `build` modes. +# DO NOT REMOVE!! +custom-protocol = ["tauri/custom-protocol"] diff --git a/src-tauri/src/build.rs b/gui/backend/build.rs similarity index 100% rename from src-tauri/src/build.rs rename to gui/backend/build.rs diff --git a/gui/backend/icons/128x128.png b/gui/backend/icons/128x128.png new file mode 100644 index 0000000..289a5e7 Binary files /dev/null and b/gui/backend/icons/128x128.png differ diff --git a/gui/backend/icons/128x128@2x.png b/gui/backend/icons/128x128@2x.png new file mode 100644 index 0000000..c92af15 Binary files /dev/null and b/gui/backend/icons/128x128@2x.png differ diff --git a/gui/backend/icons/32x32.png b/gui/backend/icons/32x32.png new file mode 100644 index 0000000..1ee95a1 Binary files /dev/null and b/gui/backend/icons/32x32.png differ diff --git a/gui/backend/icons/Square107x107Logo.png b/gui/backend/icons/Square107x107Logo.png new file mode 100644 index 0000000..218d638 Binary files /dev/null and b/gui/backend/icons/Square107x107Logo.png differ diff --git a/gui/backend/icons/Square142x142Logo.png b/gui/backend/icons/Square142x142Logo.png new file mode 100644 index 0000000..27bf0aa Binary files /dev/null and b/gui/backend/icons/Square142x142Logo.png differ diff --git a/gui/backend/icons/Square150x150Logo.png b/gui/backend/icons/Square150x150Logo.png new file mode 100644 index 0000000..f6bb921 Binary files /dev/null and b/gui/backend/icons/Square150x150Logo.png differ diff --git a/gui/backend/icons/Square284x284Logo.png b/gui/backend/icons/Square284x284Logo.png new file mode 100644 index 0000000..f372baf Binary files /dev/null and b/gui/backend/icons/Square284x284Logo.png differ diff --git a/gui/backend/icons/Square30x30Logo.png b/gui/backend/icons/Square30x30Logo.png new file mode 100644 index 0000000..bbcbf36 Binary files /dev/null and b/gui/backend/icons/Square30x30Logo.png differ diff --git a/gui/backend/icons/Square310x310Logo.png b/gui/backend/icons/Square310x310Logo.png new file mode 100644 index 0000000..43b355a Binary files /dev/null and b/gui/backend/icons/Square310x310Logo.png differ diff --git a/gui/backend/icons/Square44x44Logo.png b/gui/backend/icons/Square44x44Logo.png new file mode 100644 index 0000000..ed7f29f Binary files /dev/null and b/gui/backend/icons/Square44x44Logo.png differ diff --git a/gui/backend/icons/Square71x71Logo.png b/gui/backend/icons/Square71x71Logo.png new file mode 100644 index 0000000..993fa0c Binary files /dev/null and b/gui/backend/icons/Square71x71Logo.png differ diff --git a/gui/backend/icons/Square89x89Logo.png b/gui/backend/icons/Square89x89Logo.png new file mode 100644 index 0000000..366e53b Binary files /dev/null and b/gui/backend/icons/Square89x89Logo.png differ diff --git a/gui/backend/icons/StoreLogo.png b/gui/backend/icons/StoreLogo.png new file mode 100644 index 0000000..48907c9 Binary files /dev/null and b/gui/backend/icons/StoreLogo.png differ diff --git a/gui/backend/icons/battery/battery-0.png b/gui/backend/icons/battery/battery-0.png new file mode 100644 index 0000000..8902d34 Binary files /dev/null and b/gui/backend/icons/battery/battery-0.png differ diff --git a/gui/backend/icons/battery/battery-10.png b/gui/backend/icons/battery/battery-10.png new file mode 100644 index 0000000..d7ad747 Binary files /dev/null and b/gui/backend/icons/battery/battery-10.png differ diff --git a/gui/backend/icons/battery/battery-100.png b/gui/backend/icons/battery/battery-100.png new file mode 100644 index 0000000..d82b008 Binary files /dev/null and b/gui/backend/icons/battery/battery-100.png differ diff --git a/gui/backend/icons/battery/battery-20.png b/gui/backend/icons/battery/battery-20.png new file mode 100644 index 0000000..f2329ef Binary files /dev/null and b/gui/backend/icons/battery/battery-20.png differ diff --git a/gui/backend/icons/battery/battery-30.png b/gui/backend/icons/battery/battery-30.png new file mode 100644 index 0000000..fe121b4 Binary files /dev/null and b/gui/backend/icons/battery/battery-30.png differ diff --git a/gui/backend/icons/battery/battery-40.png b/gui/backend/icons/battery/battery-40.png new file mode 100644 index 0000000..f4a3280 Binary files /dev/null and b/gui/backend/icons/battery/battery-40.png differ diff --git a/gui/backend/icons/battery/battery-50.png b/gui/backend/icons/battery/battery-50.png new file mode 100644 index 0000000..268d894 Binary files /dev/null and b/gui/backend/icons/battery/battery-50.png differ diff --git a/gui/backend/icons/battery/battery-60.png b/gui/backend/icons/battery/battery-60.png new file mode 100644 index 0000000..bec2742 Binary files /dev/null and b/gui/backend/icons/battery/battery-60.png differ diff --git a/gui/backend/icons/battery/battery-70.png b/gui/backend/icons/battery/battery-70.png new file mode 100644 index 0000000..c4070d6 Binary files /dev/null and b/gui/backend/icons/battery/battery-70.png differ diff --git a/gui/backend/icons/battery/battery-80.png b/gui/backend/icons/battery/battery-80.png new file mode 100644 index 0000000..123112f Binary files /dev/null and b/gui/backend/icons/battery/battery-80.png differ diff --git a/gui/backend/icons/battery/battery-90.png b/gui/backend/icons/battery/battery-90.png new file mode 100644 index 0000000..3961df6 Binary files /dev/null and b/gui/backend/icons/battery/battery-90.png differ diff --git a/gui/backend/icons/battery/battery.drawio b/gui/backend/icons/battery/battery.drawio new file mode 100644 index 0000000..60b4455 --- /dev/null +++ b/gui/backend/icons/battery/battery.drawio @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/gui/backend/icons/icon.drawio b/gui/backend/icons/icon.drawio new file mode 100644 index 0000000..af388c7 --- /dev/null +++ b/gui/backend/icons/icon.drawio @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/gui/backend/icons/icon.icns b/gui/backend/icons/icon.icns new file mode 100644 index 0000000..06fac7f Binary files /dev/null and b/gui/backend/icons/icon.icns differ diff --git a/gui/backend/icons/icon.ico b/gui/backend/icons/icon.ico new file mode 100644 index 0000000..1b6773a Binary files /dev/null and b/gui/backend/icons/icon.ico differ diff --git a/gui/backend/icons/icon.png b/gui/backend/icons/icon.png new file mode 100644 index 0000000..7b23698 Binary files /dev/null and b/gui/backend/icons/icon.png differ diff --git a/gui/backend/readme.md b/gui/backend/readme.md new file mode 100644 index 0000000..14e11ec --- /dev/null +++ b/gui/backend/readme.md @@ -0,0 +1 @@ +# GUI Backend diff --git a/gui/backend/src/cmd/battery_reporter.rs b/gui/backend/src/cmd/battery_reporter.rs new file mode 100644 index 0000000..3d6b565 --- /dev/null +++ b/gui/backend/src/cmd/battery_reporter.rs @@ -0,0 +1,72 @@ +use super::bluetooth_info_cache::write_bt_cache; +use super::config::write_config; +use super::supports::{notify, update_tray}; +use super::{config::read_config, find_bluetooth_devices}; +use crate::err_log; +use std::{ + sync::atomic::{AtomicU64, Ordering}, + time::Duration, +}; +use tauri::AppHandle; +use timer::{clear_interval, set_interval}; + +static INTERVAL_ID: AtomicU64 = AtomicU64::new(0); + +/// # NOTE +/// The callback fn cannot return a Result, so write only error log. +#[tauri::command] +pub async fn restart_interval(app: AppHandle) { + let id = INTERVAL_ID.load(Ordering::Acquire); + if id != 0 { + clear_interval(id).await; + }; + + let config = read_config(app.clone()).unwrap_or_else(|_| { + let _ = err_log!(write_config(app.clone(), Default::default())); + Default::default() + }); + let duration = Duration::from_secs(config.battery_query_duration_minutes * 60); // minutes -> seconds + + let id = set_interval( + move || { + // Callbacks in the interval may survive until program termination in the worst case. + // Therefore, they become 'static' and must be cloned. + let app = app.clone(); + let instance_id = config.instance_id.clone(); + async move { + // NOTE: The callback fn cannot return a Result, so write only error log. + match find_bluetooth_devices().await { + Ok(devices) => { + if let Ok(json) = err_log!(serde_json::to_string_pretty(&devices)) { + let _ = err_log!(write_bt_cache(app.clone(), &json)); + }; + + for dev in devices { + if instance_id.is_empty() { + if !dev.is_connected { + continue; + } + } else if instance_id != dev.instance_id { + continue; + }; + + let battery_level = dev.battery_level; + if battery_level <= config.notify_battery_level { + let notify_msg = format!("Battery power is low: {battery_level}%"); + let _ = err_log!(notify(&app, ¬ify_msg)); + } + + let dev_name = &dev.friendly_name; + let _ = err_log!(update_tray(&app, dev_name, battery_level).await); + } + } + Err(e) => tracing::error!(e), + }; + } + }, + duration, + ) + .await; + + INTERVAL_ID.store(id, Ordering::Release); +} diff --git a/gui/backend/src/cmd/bluetooth_info_cache.rs b/gui/backend/src/cmd/bluetooth_info_cache.rs new file mode 100644 index 0000000..ec48e57 --- /dev/null +++ b/gui/backend/src/cmd/bluetooth_info_cache.rs @@ -0,0 +1,22 @@ +use crate::err_log; +use bluetooth::BluetoothDeviceInfo; +use std::path::PathBuf; +use tauri::AppHandle; + +fn get_cache_path(app: &AppHandle) -> Result { + let resolver = app.path_resolver(); + let cache_dir = &resolver.app_cache_dir().ok_or("Not found cache dir")?; + let config_path = cache_dir.join(format!("{}_dev_cache.json", app.package_info().name)); + Ok(config_path) +} + +#[tauri::command] +pub fn write_bt_cache(app: AppHandle, devices_json: &str) -> Result<(), String> { + err_log!(std::fs::write(get_cache_path(&app)?, devices_json)) +} + +#[tauri::command] +pub fn read_bt_cache(app: AppHandle) -> Result, String> { + let s = err_log!(std::fs::read_to_string(get_cache_path(&app)?))?; + err_log!(serde_json::from_str(&s)) +} diff --git a/gui/backend/src/cmd/config.rs b/gui/backend/src/cmd/config.rs new file mode 100644 index 0000000..3b66b39 --- /dev/null +++ b/gui/backend/src/cmd/config.rs @@ -0,0 +1,45 @@ +use std::path::PathBuf; + +use crate::err_log; +use tauri::AppHandle; + +#[derive(Debug, serde::Deserialize, serde::Serialize)] +pub struct Config { + /// e.g. `BTHENUM\\{0000111E-0000-1000-8000-00805F9B34FB}_LOCALMFG&005D...` + pub instance_id: String, + + /// e.g. `60`(minutes) == 1hour + pub battery_query_duration_minutes: u64, + + /// e.g. `20`(%) + pub notify_battery_level: u64, +} + +impl Default for Config { + fn default() -> Self { + Self { + instance_id: Default::default(), + battery_query_duration_minutes: 60, + notify_battery_level: 20, + } + } +} + +fn get_config_path(app: &AppHandle) -> Result { + let resolver = app.path_resolver(); + let config_dir = &resolver.app_config_dir().ok_or("Not found config dir")?; + let config_path = config_dir.join(format!("{}_config.json", app.package_info().name)); + Ok(config_path) +} + +#[tauri::command] +pub fn write_config(app: AppHandle, config: Config) -> Result<(), String> { + let config = err_log!(serde_json::to_string(&config))?; + err_log!(std::fs::write(get_config_path(&app)?, config)) +} + +#[tauri::command] +pub fn read_config(app: AppHandle) -> Result { + let content = err_log!(std::fs::read_to_string(get_config_path(&app)?))?; + err_log!(serde_json::from_str(&content)) +} diff --git a/gui/backend/src/cmd/mod.rs b/gui/backend/src/cmd/mod.rs new file mode 100644 index 0000000..6e75c92 --- /dev/null +++ b/gui/backend/src/cmd/mod.rs @@ -0,0 +1,60 @@ +pub(crate) mod battery_reporter; +mod bluetooth_info_cache; +mod config; +mod supports; + +use crate::err_log; +use bluetooth::{device::device_info::FindBluetooth as _, BluetoothDeviceInfo}; + +#[tauri::command] +pub(crate) async fn update_tray_icon( + app: AppHandle, + device_name: &str, + battery_level: u64, +) -> Result<(), String> { + err_log!(update_tray(&app, device_name, battery_level).await) +} + +#[tauri::command] +pub(crate) async fn find_bluetooth_devices() -> Result, String> { + err_log!(BluetoothDeviceInfo::find_devices()) +} + +#[tauri::command] +pub(crate) async fn change_log_level(log_level: Option<&str>) -> Result<(), String> { + use supports::change_log_level; + tracing::debug!("Selected log level: {:?}", log_level); + err_log!(change_log_level(log_level.unwrap_or("error"))) +} + +/// Define our own `writeTextFile` api for tauri, +/// because there was a bug that contents were not written properly +/// (there was a case that the order of some data in contents was switched). +#[tauri::command] +pub(crate) async fn write_file(path: &str, content: &str) -> Result<(), String> { + err_log!(std::fs::write(path, content)) +} + +use supports::update_tray; +use tauri::{AppHandle, Builder, Wry}; + +pub(crate) trait CommandsRegister { + /// Implements custom commands. + fn impl_commands(self) -> Self; +} + +impl CommandsRegister for Builder { + fn impl_commands(self) -> Self { + self.invoke_handler(tauri::generate_handler![ + change_log_level, + find_bluetooth_devices, + update_tray_icon, + write_file, + battery_reporter::restart_interval, + bluetooth_info_cache::read_bt_cache, + bluetooth_info_cache::write_bt_cache, + config::read_config, + config::write_config, + ]) + } +} diff --git a/gui/backend/src/cmd/supports/logger.rs b/gui/backend/src/cmd/supports/logger.rs new file mode 100644 index 0000000..1e025f1 --- /dev/null +++ b/gui/backend/src/cmd/supports/logger.rs @@ -0,0 +1,18 @@ +use std::str::FromStr as _; +use tracing_subscriber::filter; + +pub(crate) fn change_log_level(log_level: &str) -> anyhow::Result<()> { + let log_level = match log_level { + "trace" | "debug" | "info" | "warn" | "error" => log_level, + unknown_level => { + tracing::warn!("Unknown log level {unknown_level}. Fallback to error"); + "error" + } + }; + match crate::LOG_INSTANCE.get() { + Some(log) => Ok(log.modify(|filter| { + *filter = filter::LevelFilter::from_str(log_level).unwrap_or(filter::LevelFilter::ERROR) + })?), + None => anyhow::bail!("Uninitialized logger."), + } +} diff --git a/gui/backend/src/cmd/supports/mod.rs b/gui/backend/src/cmd/supports/mod.rs new file mode 100644 index 0000000..8dc7174 --- /dev/null +++ b/gui/backend/src/cmd/supports/mod.rs @@ -0,0 +1,7 @@ +mod logger; +mod notify; +mod system_tray; + +pub(super) use logger::change_log_level; +pub(super) use notify::notify; +pub(super) use system_tray::update_tray; diff --git a/gui/backend/src/cmd/supports/notify.rs b/gui/backend/src/cmd/supports/notify.rs new file mode 100644 index 0000000..0d02e0c --- /dev/null +++ b/gui/backend/src/cmd/supports/notify.rs @@ -0,0 +1,13 @@ +use tauri::{api::notification::Notification, AppHandle}; + +/// # Info +/// Write to the log when an error occurs. +/// +/// # Note +/// Need feature [`notification-all`](https://tauri.app/v1/api/js/notification/) +pub fn notify(app: &AppHandle, message: &str) -> tauri::Result<()> { + Ok(Notification::new(&app.config().tauri.bundle.identifier) + .title("[bluetooth battery monitor]") + .body(message) + .show()?) +} diff --git a/gui/backend/src/cmd/supports/system_tray.rs b/gui/backend/src/cmd/supports/system_tray.rs new file mode 100644 index 0000000..fa9f1ca --- /dev/null +++ b/gui/backend/src/cmd/supports/system_tray.rs @@ -0,0 +1,27 @@ +/// Update application tray icon & name +pub async fn update_tray( + app: &tauri::AppHandle, + device_name: &str, + battery_level: u64, +) -> tauri::Result<()> { + tracing::debug!("Change to {battery_level} battery icon",); + + let battery_icon = match battery_level { + 0 => include_bytes!("../../../icons/battery/battery-0.png"), + 1..=10 => include_bytes!("../../../icons/battery/battery-10.png").as_slice(), + 11..=20 => include_bytes!("../../../icons/battery/battery-20.png").as_slice(), + 21..=30 => include_bytes!("../../../icons/battery/battery-30.png").as_slice(), + 31..=40 => include_bytes!("../../../icons/battery/battery-40.png").as_slice(), + 41..=50 => include_bytes!("../../../icons/battery/battery-50.png").as_slice(), + 51..=60 => include_bytes!("../../../icons/battery/battery-60.png").as_slice(), + 61..=70 => include_bytes!("../../../icons/battery/battery-70.png").as_slice(), + 71..=80 => include_bytes!("../../../icons/battery/battery-80.png").as_slice(), + 81..=90 => include_bytes!("../../../icons/battery/battery-90.png").as_slice(), + 91..=100 => include_bytes!("../../../icons/battery/battery-100.png").as_slice(), + _ => unreachable!(), + }; + + let tray_handle = app.tray_handle(); + tray_handle.set_icon(tauri::Icon::Raw(battery_icon.to_vec()))?; + tray_handle.set_tooltip(&format!("{device_name} {battery_level}%")) +} diff --git a/gui/backend/src/main.rs b/gui/backend/src/main.rs new file mode 100644 index 0000000..1c2ce5e --- /dev/null +++ b/gui/backend/src/main.rs @@ -0,0 +1,37 @@ +// Prevents additional console window on Windows in release, DO NOT REMOVE!! +#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] +mod cmd; +mod setup; + +pub(crate) use setup::LOG_INSTANCE; + +use anyhow::Context as _; +use cmd::CommandsRegister; +use setup::SetupsRegister as _; + +fn main() -> std::io::Result<()> { + tauri::Builder::default() + .impl_setup() + .impl_commands() + .plugin(tauri_plugin_autostart::init( + tauri_plugin_autostart::MacosLauncher::LaunchAgent, + None, + )) + .run(tauri::generate_context!()) + .context("Failed to execute tauri") + .map_err(|err| { + tracing::error!("Error: {err}"); + std::process::exit(1); + }) +} + +/// Result -> Log & toString +#[macro_export] +macro_rules! err_log { + ($exp:expr) => { + $exp.map_err(|err| { + tracing::error!("{err}"); + err.to_string() + }) + }; +} diff --git a/gui/backend/src/setup/battery_reporter.rs b/gui/backend/src/setup/battery_reporter.rs new file mode 100644 index 0000000..7cc55a8 --- /dev/null +++ b/gui/backend/src/setup/battery_reporter.rs @@ -0,0 +1,10 @@ +use crate::cmd::battery_reporter::restart_interval; + +/// # Note +/// Interval callback fn cannot return Result. So relies on internal error log. +pub fn start_interval(app: &tauri::AppHandle) { + let app = app.clone(); + tauri::async_runtime::spawn(async move { + let _ = restart_interval(app).await; + }); +} diff --git a/gui/backend/src/setup/logger.rs b/gui/backend/src/setup/logger.rs new file mode 100644 index 0000000..918ee08 --- /dev/null +++ b/gui/backend/src/setup/logger.rs @@ -0,0 +1,147 @@ +use anyhow::{Context as _, Result}; +use chrono::Local; +use once_cell::sync::OnceCell; +use std::fs::{self, File}; +use std::path::Path; +use tracing_subscriber::{ + filter::{self, LevelFilter}, + fmt, + prelude::*, + reload::{self, Handle}, + Registry, +}; + +pub static LOG_INSTANCE: OnceCell> = OnceCell::new(); + +/// Initializes logger. +/// +/// # Errors +/// Double init +pub(super) fn init_logger(app: &tauri::App) -> Result<()> { + let resolver = app.path_resolver(); + let log_dir = &resolver.app_log_dir().context("Not found log dir")?; + let log_name = format!("{}.log", app.package_info().name); + + // Not available yet because ansi(false) is not applied in tracing::instrument under the combination of pretty() and with_ansi(false). + // - See https://github.com/tokio-rs/tracing/issues/1310 + let fmt_layer = fmt::layer() + .compact() + .with_ansi(false) + .with_file(true) + .with_line_number(true) + .with_target(false) + .with_writer(create_rotate_log(log_dir, &log_name, 4)?); + + let (filter, reload_handle) = reload::Layer::new(filter::LevelFilter::ERROR); + tracing_subscriber::registry() + .with(filter) + .with(fmt_layer) + .init(); + tracing::debug!("logger file path: {log_name:?}"); + if LOG_INSTANCE.set(reload_handle).is_err() { + Err(anyhow::anyhow!("Couldn't init logger"))? + }; + Ok(()) +} + +/// Rotation Logger File Creator. +/// - When the maximum count is reached, delete the descending ones first and create a new log file. +/// +/// # Why did you make this? +/// Because `tracing_appender` must be executed in the **root function** to work. +/// In this case where the log location is obtained with tauri, the logger cannot be initialized with the root function. +fn create_rotate_log(log_dir: impl AsRef, log_name: &str, max_files: usize) -> Result { + fs::create_dir_all(&log_dir)?; + + let mut log_files = fs::read_dir(&log_dir)? + .filter_map(|entry| entry.ok()) + .filter(|entry| { + entry + .file_name() + .to_str() + .map(|name| name.starts_with(log_name)) + .unwrap_or(false) + }) + .collect::>(); + + let mut log_count = log_files.len(); + tracing::debug!("-- Start log count: {log_count} --"); + let log_file = log_dir.as_ref().join(log_name); + if log_files.len() >= max_files { + log_files.sort_by(|a, b| { + // NOTE: Error in OS that can't be modified, but not considered here. + a.metadata() + .unwrap() + .modified() + .unwrap() + .cmp(&b.metadata().unwrap().modified().unwrap()) + }); + if let Some(oldest_file) = log_files.first() { + tracing::info!("Remove old log {oldest_file:?}"); + log_count -= 1; + fs::remove_file(oldest_file.path())?; + } + }; + + let old_file = log_dir.as_ref().join(format!( + "{log_name}_{}.log", + Local::now().format("%F_%H-%M-%S") + )); + + if log_file.exists() { + tracing::info!( + "Rename: {:?} => {:?}", + &log_file.file_name(), + &old_file.file_name() + ); + fs::rename(&log_file, old_file)?; + }; + + let f = File::create(log_file)?; + tracing::debug!("-- End log count: {} --", log_count + 1); + Ok(f) +} + +#[cfg(test)] +mod tests { + use super::*; + use pretty_assertions::assert_eq; + + /// tracing initializer + macro_rules! logger_init { + ($level:ident) => { + let (non_blocking, _guard) = tracing_appender::non_blocking(std::io::stdout()); + tracing_subscriber::fmt() + .with_writer(non_blocking) + .with_ansi(false) + .with_max_level(tracing::Level::$level) + .init(); + }; + } + + #[test] + fn should_rotate_log() -> Result<()> { + logger_init!(ERROR); + + let log_dir = temp_dir::TempDir::new()?; + let log_dir = log_dir.path(); + for _ in 0..5 { + create_rotate_log(log_dir, "app.log", 3)?; + std::thread::sleep(std::time::Duration::from_secs(1)); + } + + fn get_files_in_dir(dir_path: impl AsRef) -> Result> { + let dir = fs::read_dir(dir_path)?; + let files = dir + .filter_map(|entry| entry.ok()) + .filter(|entry| entry.file_type().map(|ft| ft.is_file()).unwrap_or(false)) + .collect::>(); + Ok(files) + } + + let files = get_files_in_dir(log_dir)?; + tracing::debug!("{:?}", &files); + assert_eq!(files.len(), 3); + Ok(()) + } +} diff --git a/gui/backend/src/setup/mod.rs b/gui/backend/src/setup/mod.rs new file mode 100644 index 0000000..3c1d5a0 --- /dev/null +++ b/gui/backend/src/setup/mod.rs @@ -0,0 +1,28 @@ +mod battery_reporter; +pub mod logger; +mod system_tray; +mod window_event; + +pub use logger::LOG_INSTANCE; // Need cmd + +use battery_reporter::start_interval; +use system_tray::{create_system_tray, tray_event}; +use tauri::{Builder, Wry}; + +pub(crate) trait SetupsRegister { + /// Implements custom setup. + fn impl_setup(self) -> Self; +} + +impl SetupsRegister for Builder { + fn impl_setup(self) -> Self { + self.setup(|app| { + logger::init_logger(app)?; + start_interval(&app.handle()); + Ok(()) + }) + .system_tray(create_system_tray()) + .on_system_tray_event(tray_event) + .on_window_event(window_event::window_event) + } +} diff --git a/gui/backend/src/setup/system_tray.rs b/gui/backend/src/setup/system_tray.rs new file mode 100644 index 0000000..cc078e7 --- /dev/null +++ b/gui/backend/src/setup/system_tray.rs @@ -0,0 +1,82 @@ +use super::battery_reporter::start_interval; +use tauri::{AppHandle, Manager as _, SystemTray, SystemTrayEvent}; + +const RELOAD_ID: &str = "reload_info"; +const TOGGLE_WINDOW_ID: &str = "toggle_window"; +const EXIT_ID: &str = "quit"; + +/// # Note +/// This function is called only at setup time. +pub fn create_system_tray() -> SystemTray { + use tauri::{CustomMenuItem, SystemTrayMenu, SystemTrayMenuItem}; + + let reload_info = CustomMenuItem::new(RELOAD_ID, "Reload"); + let toggle_window = CustomMenuItem::new(TOGGLE_WINDOW_ID, "Show"); + let quit = CustomMenuItem::new(EXIT_ID, "Exit"); + + let tray_menu = SystemTrayMenu::new() + .add_item(reload_info) + .add_native_item(SystemTrayMenuItem::Separator) + .add_item(toggle_window) + .add_item(quit); + SystemTray::new() + .with_menu(tray_menu) + .with_tooltip("Getting bluetooth battery...") +} + +/// # Note +/// This function is called only at setup time. +pub fn tray_event(app: &AppHandle, event: SystemTrayEvent) { + match event { + SystemTrayEvent::LeftClick { .. } => { + let item_handle = app.tray_handle().get_item("toggle_window"); + let window = app.get_window("main").unwrap(); + + match window.is_visible() { + Ok(visible) => { + if let Err(e) = if visible { + window.hide().expect("Couldn't hide window"); + item_handle.set_title("Show") + } else { + window.show().expect("Couldn't show window"); + item_handle.set_title("Hide") + } { + tracing::error!("{e}"); + }; + } + Err(e) => { + tracing::error!("{e}"); + } + } + } + SystemTrayEvent::MenuItemClick { id, .. } => match id.as_str() { + RELOAD_ID => start_interval(app), + TOGGLE_WINDOW_ID => { + let item_handle = app.tray_handle().get_item(&id); + let window = app.get_window("main").unwrap(); + + match window.is_visible() { + Ok(visible) => { + if let Err(e) = if visible { + window.hide().expect("Couldn't hide window"); + item_handle.set_title("Show") + } else { + window.show().expect("Couldn't show window"); + item_handle.set_title("Hide") + } { + tracing::error!("{e}"); + }; + } + Err(e) => { + tracing::error!("{e}"); + } + } + } + EXIT_ID => { + std::process::exit(0); + } + _ => tracing::error!("Unknown event id: {id}"), + }, + _ => (), + } +} diff --git a/gui/backend/src/setup/window_event.rs b/gui/backend/src/setup/window_event.rs new file mode 100644 index 0000000..c0a9b95 --- /dev/null +++ b/gui/backend/src/setup/window_event.rs @@ -0,0 +1,22 @@ +use crate::err_log; + +/// To prevent exit application by X button. +// +// # Note +// This signature is defined by a function that takes a function pointer as an argument and cannot return an error. +// Therefore, it should be logged by the logger. +pub fn window_event(event: tauri::GlobalWindowEvent) { + use tauri::Manager as _; + + if let tauri::WindowEvent::CloseRequested { api, .. } = event.event() { + let _ = err_log!(event.window().hide()); + let tray_toggle_window = event + .window() + .app_handle() + .tray_handle() + .get_item("toggle_window"); + let _ = err_log!(tray_toggle_window.set_title("show")); + + api.prevent_close(); + } +} diff --git a/src-tauri/tauri.conf.json b/gui/backend/tauri.conf.json similarity index 51% rename from src-tauri/tauri.conf.json rename to gui/backend/tauri.conf.json index cfbf414..91da95d 100644 --- a/src-tauri/tauri.conf.json +++ b/gui/backend/tauri.conf.json @@ -1,34 +1,49 @@ { + "$schema": "../../node_modules/@tauri-apps/cli/schema.json", "build": { - "beforeBuildCommand": "deno run -A ./bundle.ts --release", - "beforeDevCommand": "deno run -A ./bundle.ts --dev", + "beforeBuildCommand": "npm run build:front", + "beforeDevCommand": "npm run dev:front", "devPath": "http://localhost:3000", - "distDir": "../www" + "distDir": "../frontend/out" }, "package": { - "productName": "Bluetooth Battery Monitor", - "version": "0.3.0" + "productName": "bluetooth_battery_monitor", + "version": "../../package.json" }, "tauri": { "allowlist": { - "all": true + "all": false, + "dialog": { + "all": false, + "ask": false, + "confirm": false, + "message": false, + "open": true, + "save": true + }, + "fs": { + "all": true + }, + "path": { + "all": true + }, + "shell": { + "all": true + }, + "notification": { + "all": true + } }, "bundle": { "active": true, "category": "DeveloperTool", - "copyright": "", + "copyright": "SARDONYX-sard", "deb": { "depends": [] }, "externalBin": [], - "icon": [ - "icons/32x32.png", - "icons/128x128.png", - "icons/128x128@2x.png", - "icons/icon.icns", - "icons/icon.ico" - ], - "identifier": "com.tauri.deno.com", + "icon": ["icons/32x32.png", "icons/128x128.png", "icons/128x128@2x.png", "icons/icon.icns", "icons/icon.ico"], + "identifier": "SARDONYX.bluetooth-battery-monitor", "longDescription": "", "macOS": { "entitlements": null, @@ -58,12 +73,11 @@ }, "windows": [ { - "fullscreen": false, - "height": 600, + "height": 920, "resizable": true, - "title": "bluetooth battery monitor", - "width": 800, "theme": "Dark", + "title": "Bluetooth Battery Monitor", + "width": 860, "visible": false } ] diff --git a/gui/frontend/.eslintrc.cjs b/gui/frontend/.eslintrc.cjs new file mode 100644 index 0000000..2d4d1e6 --- /dev/null +++ b/gui/frontend/.eslintrc.cjs @@ -0,0 +1,47 @@ +// For compatibility with Biome (fast linter&fmt made by Rust), the following settings are made +// to compensate for missing functions of Biome with eslint. + +// @ts-check + +/** @typedef {import('eslint').ESLint.ConfigData} ConfigData */ + +/** @type {ConfigData} */ +module.exports = { + extends: ['next/core-web-vitals'], + settings: { + // NOTE: eslint cannot resolve aliases by `@` without the following two settings + // See:https://github.com/import-js/eslint-plugin-import/issues/2765#issuecomment-1701641064 + next: { + rootDir: __dirname, + }, + 'import/resolver': { + typescript: { + project: __dirname, + }, + }, + }, + + // `next/core-web-vitals` of `eslint-config-next` has sort import and `sort-props` functions, so use them. + rules: { + 'import/order': [ + 'warn', + { + alphabetize: { + caseInsensitive: true, + order: 'asc', + }, + groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'object', 'type'], + 'newlines-between': 'always', + pathGroupsExcludedImportTypes: ['builtin'], + pathGroups: [ + { pattern: '@/**', group: 'internal', position: 'before' }, + // styles + // treat group as index because we want it to be last + { pattern: '@/**.css', group: 'index', position: 'before' }, + { pattern: '@/**.json', group: 'index', position: 'before' }, + ], + }, + ], + 'react/jsx-sort-props': 'warn', + }, +}; diff --git a/gui/frontend/.gitignore b/gui/frontend/.gitignore new file mode 100644 index 0000000..bd98898 --- /dev/null +++ b/gui/frontend/.gitignore @@ -0,0 +1,35 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel +# typescript +*.tsbuildinfo +next-env.d.ts + +test/ diff --git a/gui/frontend/global.d.ts b/gui/frontend/global.d.ts new file mode 100644 index 0000000..74e3187 --- /dev/null +++ b/gui/frontend/global.d.ts @@ -0,0 +1,9 @@ +// Copyright (c) 2023 Luma +// SPDX-License-Identifier: MIT or Apache-2.0 +declare module 'monaco-vim' { + class VimMode { + dispose(): void; + initVimMode(editor: editor.IStandaloneCodeEditor, statusbarNode?: Element | null): VimMode; + } + export function initVimMode(editor: editor.IStandaloneCodeEditor, statusbarNode?: HTMLElement): VimMode; +} diff --git a/gui/frontend/next.config.js b/gui/frontend/next.config.js new file mode 100644 index 0000000..1f7bd4d --- /dev/null +++ b/gui/frontend/next.config.js @@ -0,0 +1,9 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + distDir: './out', + output: 'export', + reactStrictMode: true, + swcMinify: true, +}; + +export default nextConfig; diff --git a/gui/frontend/readme.md b/gui/frontend/readme.md new file mode 100644 index 0000000..b57eb12 --- /dev/null +++ b/gui/frontend/readme.md @@ -0,0 +1 @@ +# GUI Frontend diff --git a/gui/frontend/src/app/client_layout.tsx b/gui/frontend/src/app/client_layout.tsx new file mode 100644 index 0000000..13847b8 --- /dev/null +++ b/gui/frontend/src/app/client_layout.tsx @@ -0,0 +1,45 @@ +// Copyright (c) 2023 Luma +// SPDX-License-Identifier: MIT or Apache-2.0 +'use client'; +import { CssBaseline, ThemeProvider, createTheme } from '@mui/material'; +import NextLink from 'next/link'; + +import Menu from '@/components/navigation'; +import SnackBarProvider from '@/components/providers/snackbar'; + +import type { ComponentProps, ReactNode } from 'react'; + +const darkTheme = createTheme({ + palette: { + mode: 'dark', + }, + components: { + // biome-ignore lint/style/useNamingConvention: + MuiLink: { + defaultProps: { + component: (props: ComponentProps) => , + }, + }, + // biome-ignore lint/style/useNamingConvention: + MuiButtonBase: { + defaultProps: { + // biome-ignore lint/style/useNamingConvention: + LinkComponent: (props: ComponentProps) => , + }, + }, + }, +}); + +interface ClientLayoutProps { + children: ReactNode; +} +export default function ClientLayout({ children }: Readonly) { + return ( + + + + {children} + + + ); +} diff --git a/gui/frontend/src/app/favicon.ico b/gui/frontend/src/app/favicon.ico new file mode 100644 index 0000000..718d6fe Binary files /dev/null and b/gui/frontend/src/app/favicon.ico differ diff --git a/gui/frontend/src/app/globals.css b/gui/frontend/src/app/globals.css new file mode 100644 index 0000000..18e5b31 --- /dev/null +++ b/gui/frontend/src/app/globals.css @@ -0,0 +1,41 @@ +:root { + --font-mono: ui-monospace, Menlo, Monaco, 'Cascadia Mono', 'Segoe UI Mono', 'Roboto Mono', 'Oxygen Mono', + 'Ubuntu Monospace', 'Source Code Pro', 'Fira Mono', 'Droid Sans Mono', 'Courier New', monospace; + + --foreground-rgb: 0, 0, 0; +} + +@media (prefers-color-scheme: dark) { + :root { + --foreground-rgb: 255, 255, 255; + } +} + +* { + box-sizing: border-box; + padding: 0; + margin: 0; +} + +html, +body { + max-width: 100vw; + min-height: 100vh; + overflow-x: hidden; +} + +body { + color: rgb(var(--foreground-rgb)); + background-color: #000; +} + +a { + color: inherit; + text-decoration: none; +} + +@media (prefers-color-scheme: dark) { + html { + color-scheme: dark; + } +} diff --git a/gui/frontend/src/app/layout.tsx b/gui/frontend/src/app/layout.tsx new file mode 100644 index 0000000..fb2fe8c --- /dev/null +++ b/gui/frontend/src/app/layout.tsx @@ -0,0 +1,41 @@ +import dynamic from 'next/dynamic'; +import { Inter } from 'next/font/google'; + +import Loading from '@/components/pages/loading'; +import '@/utils/translation'; + +import json from '../../../backend/tauri.conf.json'; + +import type { Metadata } from 'next'; +import type { ReactNode } from 'react'; + +import '@/app/globals.css'; + +export const metadata = { + title: json.tauri.windows[0].title, + description: json.tauri.windows[0].title, +} as const satisfies Metadata; + +const ClientLayout = dynamic(() => import('@/app/client_layout'), { + loading: () => , + ssr: false, +}); +const inter = Inter({ subsets: ['latin'] }); + +type Props = Readonly<{ + children: ReactNode; +}>; + +export default function RootLayout({ children }: Props) { + return ( + + + + {children} + {/* To prevents the conversion button from being hidden because the menu is fixed. */} +
+ + + + ); +} diff --git a/gui/frontend/src/app/page.tsx b/gui/frontend/src/app/page.tsx new file mode 100644 index 0000000..c5e91d2 --- /dev/null +++ b/gui/frontend/src/app/page.tsx @@ -0,0 +1,8 @@ +import Home from '@/components/pages/home'; + +/** + * # Root page (URL: /). + */ +export default function Index() { + return ; +} diff --git a/gui/frontend/src/app/settings/page.tsx b/gui/frontend/src/app/settings/page.tsx new file mode 100644 index 0000000..35cf90e --- /dev/null +++ b/gui/frontend/src/app/settings/page.tsx @@ -0,0 +1,5 @@ +import Settings from '@/components/pages/settings'; + +export default function Settings_() { + return ; +} diff --git a/gui/frontend/src/backend_api/backend_config.ts b/gui/frontend/src/backend_api/backend_config.ts new file mode 100644 index 0000000..8bc2e69 --- /dev/null +++ b/gui/frontend/src/backend_api/backend_config.ts @@ -0,0 +1,40 @@ +import { invoke } from '@tauri-apps/api'; + +export type Config = { + /** e.g. `BTHENUM\\{0000111E-0000-1000-8000-00805F9B34FB}_LOCALMFG&005D...` */ + // biome-ignore lint/style/useNamingConvention: + instance_id: string; + + /** e.g. `60`(minutes) == 1hour */ + // biome-ignore lint/style/useNamingConvention: + battery_query_duration_minutes: number; + + /** e.g. `20`(%) */ + // biome-ignore lint/style/useNamingConvention: + notify_battery_level: number; +}; + +export const config = { + default: { + // biome-ignore lint/style/useNamingConvention: + instance_id: '', + // biome-ignore lint/style/useNamingConvention: + battery_query_duration_minutes: 60, + // biome-ignore lint/style/useNamingConvention: + notify_battery_level: 20, + }, + + /** + * Read bluetooth finder configuration + */ + async read() { + return await invoke('read_config'); + }, + + /** + * Read bluetooth finder configuration + */ + async write(config: Config) { + await invoke('write_config', { config }); + }, +}; diff --git a/gui/frontend/src/backend_api/backup.ts b/gui/frontend/src/backend_api/backup.ts new file mode 100644 index 0000000..adace9e --- /dev/null +++ b/gui/frontend/src/backend_api/backup.ts @@ -0,0 +1,55 @@ +import { save } from '@tauri-apps/api/dialog'; + +import { readFile, writeFile } from '@/backend_api'; +import { type LocalCache, cacheKeys, localStorageManager } from '@/utils/local_storage_manager'; + +import tauriJson from '../../../backend/tauri.conf.json'; + +const frontConfigPath = `${tauriJson.package.productName}_front_config` as const; + +export const backup = { + /** @throws Error */ + async import() { + const pathKey = 'import-backup-path'; + const settings = await readFile(pathKey, frontConfigPath); + if (settings) { + const obj = JSON.parse(settings); + + // Validate + for (const key of Object.keys(obj)) { + // The import path does not need to be overwritten. + if (key === pathKey) { + return; + } + // Remove invalid settings values + // biome-ignore lint/suspicious/noExplicitAny: + if (!cacheKeys.includes(key as any)) { + delete obj[key]; + } + } + + return obj as LocalCache; + } + }, + + /** @throws Error */ + async export(settings: LocalCache) { + const pathKey = 'export-settings-path'; + const cachedPath = localStorageManager.get(pathKey); + const path = await save({ + defaultPath: cachedPath ?? undefined, + filters: [ + { + name: frontConfigPath, + extensions: ['json'], + }, + ], + }); + + if (typeof path === 'string') { + await writeFile(path, `${JSON.stringify(settings, null, 2)}\n`); + return path; + } + return null; + }, +}; diff --git a/gui/frontend/src/backend_api/bluetooth_finder.ts b/gui/frontend/src/backend_api/bluetooth_finder.ts new file mode 100644 index 0000000..4b07b0a --- /dev/null +++ b/gui/frontend/src/backend_api/bluetooth_finder.ts @@ -0,0 +1,64 @@ +import { invoke } from '@tauri-apps/api'; + +export type BluetoothDeviceInfo = { + /** e.g. `E500Pro Hands-Free AG` */ + // biome-ignore lint/style/useNamingConvention: + friendly_name: string; + + /** e.g. `BTHENUM\\{0000111E-0000-1000-8000-00805F9B34FB}_LOCALMFG&005D...` */ + // biome-ignore lint/style/useNamingConvention: + instance_id: string; + + address: number; + + /** e.g. 80(%) */ + // biome-ignore lint/style/useNamingConvention: + battery_level: number; + + category: string; + + // biome-ignore lint/style/useNamingConvention: + is_connected: boolean; + + /** + * Native time + * e.g. `2024/4/19 22:42:16` + */ + // biome-ignore lint/style/useNamingConvention: + last_used: string; +}; + +/** + * Find bluetooth devices information. + * @throws `Error` + */ +export async function FindBluetoothDevices() { + return await invoke('find_bluetooth_devices'); +} + +/** + * Restart interval to get bluetooth device information. + * @throws `Error` + */ +export async function restartBtGetter() { + return await invoke('restart_interval'); +} + +export const btCache = { + /** + * Get bluetooth device information from cache. + * @throws `Error` + */ + async read() { + return await invoke('read_bt_cache'); + }, + + /** + * Write bluetooth device information to cache. + * @throws `Error` + */ + async write(devices: BluetoothDeviceInfo[]) { + // biome-ignore lint/style/useNamingConvention: + await invoke('write_bt_cache', { devices_json: JSON.stringify(devices) }); + }, +}; diff --git a/gui/frontend/src/backend_api/default_api_wrapper.ts b/gui/frontend/src/backend_api/default_api_wrapper.ts new file mode 100644 index 0000000..4b8f764 --- /dev/null +++ b/gui/frontend/src/backend_api/default_api_wrapper.ts @@ -0,0 +1,93 @@ +import { invoke } from '@tauri-apps/api'; +import { type OpenDialogOptions, open } from '@tauri-apps/api/dialog'; +import { readTextFile } from '@tauri-apps/api/fs'; +import { open as openShell } from '@tauri-apps/api/shell'; + +import { notify } from '@/components/notifications'; +import { type CacheKey, localStorageManager } from '@/utils/local_storage_manager'; + +/** + * Read the entire contents of a file into a string. + * @param pathKey - target path cache key + * @return contents + * @throws `Error` + */ +export async function readFile(pathKey: CacheKey, filterName: string) { + let path = localStorageManager.get(pathKey) ?? ''; + + const setPath = (newPath: string) => { + path = newPath; + localStorageManager.set(pathKey, path); + }; + + if ( + await openPath(path, { + setPath, + filters: [ + { + name: filterName, + extensions: ['json'], + }, + ], + }) + ) { + return await readTextFile(path); + } + return null; +} + +/** + *Alternative file writing API to avoid tauri API bug. + * # NOTE + * We couldn't use `writeTextFile`! + * - The `writeTextFile` of tauri's api has a bug that the data order of some contents is unintentionally swapped. + * @param path - path to write + * @param content - string content + * @throws Error + */ +export async function writeFile(path: string, content: string) { + await invoke('write_file', { path, content }); +} + +type OpenOptions = { + /** + * path setter. + * - If we don't get the result within this function, somehow the previous value comes in.(React component) + * @param path + * @returns + */ + setPath?: (path: string) => void; +} & OpenDialogOptions; + +/** + * Open a file or Dir + * @returns selected path or cancelled null + * @throws + */ +export async function openPath(path: string, options: OpenOptions) { + const res = await open({ + defaultPath: path, + ...options, + }); + + if (typeof res === 'string' && options.setPath) { + options.setPath(res); + } + return res; +} + +/** + * Wrapper tauri's `open` with `notify.error` + * @export + * @param {string} path + * @param {string} [openWith] + */ +export async function start(path: string, openWith?: string) { + try { + await openShell(path, openWith); + } catch (error) { + if (error instanceof Error) { + notify.error(error.message); + } + } +} diff --git a/gui/frontend/src/backend_api/index.ts b/gui/frontend/src/backend_api/index.ts new file mode 100644 index 0000000..e234f72 --- /dev/null +++ b/gui/frontend/src/backend_api/index.ts @@ -0,0 +1,9 @@ +// @index('./*', f => `export * from '${f.path}'`) +export * from './backup'; +export * from './backend_config'; +export * from './bluetooth_finder'; +export * from './default_api_wrapper'; +export * from './lang'; +export * from './log'; +export * from './progress_listener'; +export * from './sys_tray'; diff --git a/gui/frontend/src/backend_api/lang.ts b/gui/frontend/src/backend_api/lang.ts new file mode 100644 index 0000000..64a31eb --- /dev/null +++ b/gui/frontend/src/backend_api/lang.ts @@ -0,0 +1,11 @@ +import { readFile } from '.'; + +/** + * Read the entire contents of a file into a string. + * @param {string} path - target path + * @return [isCancelled, contents] + * @throws + */ +export async function importLang() { + return await readFile('lang-file-path', 'Custom Language'); +} diff --git a/gui/frontend/src/backend_api/log.ts b/gui/frontend/src/backend_api/log.ts new file mode 100644 index 0000000..0d3fe7c --- /dev/null +++ b/gui/frontend/src/backend_api/log.ts @@ -0,0 +1,32 @@ +import { invoke } from '@tauri-apps/api'; +import { appLogDir } from '@tauri-apps/api/path'; +import { open as openShell } from '@tauri-apps/api/shell'; + +import tauriJson from '../../../backend/tauri.conf.json'; + +export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error'; +/** + * Invokes the `change_log_level` command with the specified log level. + * @param {LogLevel} [logLevel] - The log level to set. If not provided, the default log level will be used. + * @returns {Promise} A promise that resolves when the log level is changed. + */ +export async function changeLogLevel(logLevel?: LogLevel): Promise { + await invoke('change_log_level', { logLevel }); +} + +/** + * Opens the log file. + * @throws - if not found path + */ +export async function openLogFile() { + const logFile = `${await appLogDir()}/${tauriJson.package.productName}.log`; + await openShell(logFile); +} + +/** + * Opens the log directory. + * @throws - if not found path + */ +export async function openLogDir() { + await openShell(await appLogDir()); +} diff --git a/gui/frontend/src/backend_api/progress_listener.ts b/gui/frontend/src/backend_api/progress_listener.ts new file mode 100644 index 0000000..094e9fb --- /dev/null +++ b/gui/frontend/src/backend_api/progress_listener.ts @@ -0,0 +1,90 @@ +import { listen } from '@tauri-apps/api/event'; + +import { notify } from '@/components/notifications'; + +import type { EventCallback, EventName } from '@tauri-apps/api/event'; +import type { JSX } from 'react/jsx-runtime'; + +type ListenerProps = { + setLoading: (loading: boolean) => void; + setProgress: (percentage: number) => void; + success: string | JSX.Element; + /** @default Error */ + error?: string | JSX.Element; +}; +/** + * - Specification decided by backend + * - At 1st => length + * - After that => index + */ +type Payload = { index: number }; + +/** + * Tauri Progress Event Listener. + * # No exception + * + * # Example + * ```typescript + * const promiseFn = async() => { await invoke('remove_oar_dir', { path: "/"})}; + * const setLoading = (bool:boolean) => {}; + * const setProgress = (per:number) => {}; + * + * await progressListener('show-progress', promiseFn, { + * setLoading, + * setProgress, + * success: 'conversion-complete', + * }); + * ``` + * + * - backend(focus window.emit) + * + * ```rust + * #[tauri::command] + * pub(crate) async fn remove_oar_dir(window: Window, path: &str) -> Result<(), ()> { + * #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] + * struct Payload { index: usize } + * let sender = |index:usize| window.emit("show-progress", Payload { index }); + * sender(1); + * Ok(()) + * } + * ``` + */ +export async function progressListener( + eventName: EventName, + promiseFn: () => Promise, + { setLoading, setProgress, success, error }: ListenerProps, +) { + setLoading(true); + setProgress(0); + + /** All File & dir counts */ + let maxNum = 0; + let unlisten: (() => void) | null = null; + const eventHandler: EventCallback = (event) => { + const toPercentage = (num: number) => (num * 100) / maxNum; + + if (maxNum === 0) { + maxNum = event.payload.index; + } else { + setProgress(toPercentage(event.payload.index)); + } + }; + + try { + // Setup before run Promise(For event hook) + unlisten = await listen(eventName, eventHandler); + + await promiseFn(); + + notify.success(success); + setProgress(100); + } catch (err) { + setProgress(0); // To avoid display `NaN` + notify.error(error ?? `${err}`); + } finally { + if (unlisten) { + unlisten(); + } + setLoading(false); + } +} diff --git a/gui/frontend/src/backend_api/sys_tray.ts b/gui/frontend/src/backend_api/sys_tray.ts new file mode 100644 index 0000000..d96c74f --- /dev/null +++ b/gui/frontend/src/backend_api/sys_tray.ts @@ -0,0 +1,5 @@ +import { invoke } from '@tauri-apps/api'; + +export async function updateTrayIcon(deviceName: string, batteryLevel: number) { + await invoke('update_tray_icon', { deviceName, batteryLevel }); +} diff --git a/gui/frontend/src/components/bt_devices/device.tsx b/gui/frontend/src/components/bt_devices/device.tsx new file mode 100644 index 0000000..0784486 --- /dev/null +++ b/gui/frontend/src/components/bt_devices/device.tsx @@ -0,0 +1,60 @@ +import { Headset } from '@mui/icons-material'; +import HeadsetOffIcon from '@mui/icons-material/HeadsetOff'; +import { Button, Card, CardActions, CardContent, CardHeader, IconButton, Tooltip, Typography } from '@mui/material'; +import { useCallback } from 'react'; + +import { type BluetoothDeviceInfo, config, updateTrayIcon } from '@/backend_api'; +import { CircularProgressWithLabel, notify } from '@/components/notifications'; +import { useTranslation } from '@/hooks'; + +type Props = Readonly<{ + device: BluetoothDeviceInfo; +}>; + +export const DeviceCard = ({ device }: Props) => { + const { friendly_name, battery_level, category, is_connected, last_used, instance_id } = device; + const { t } = useTranslation(); + const powerOffColor = '#69696978'; + + const cardClickHandler = useCallback(async () => { + try { + await updateTrayIcon(friendly_name, battery_level); + await config.write({ + ...(await config.read()), + instance_id, + }); + } catch (err) { + notify.error(`${err}`); + } + }, [battery_level, friendly_name, instance_id]); + + return ( + + + + {friendly_name} + + + + } + avatar={ + + {is_connected ? : } + + } + subheader={last_used} + title={category} + /> + + + + + + + + ); +}; diff --git a/gui/frontend/src/components/bt_devices/devices.tsx b/gui/frontend/src/components/bt_devices/devices.tsx new file mode 100644 index 0000000..ed071fd --- /dev/null +++ b/gui/frontend/src/components/bt_devices/devices.tsx @@ -0,0 +1,71 @@ +'use client'; + +import { Box, Grid, List } from '@mui/material'; +import { useCallback, useEffect, useState } from 'react'; + +import { type BluetoothDeviceInfo, FindBluetoothDevices, btCache, changeLogLevel } from '@/backend_api'; +import { DeviceCard } from '@/components/bt_devices/device'; +import { LogDirButton, LogFileButton, UpdateButton } from '@/components/buttons'; +import { notify } from '@/components/notifications'; +import { selectLogLevel } from '@/utils/selector'; + +import { ConfigFields } from './update_interval'; + +export const DeviceCards = () => { + const [dev, setDev] = useState(null); + + useEffect(() => { + (async () => { + await changeLogLevel(selectLogLevel(localStorage.getItem('log_level'))); + try { + setDev(await btCache.read()); + } catch (err) { + notify.error(`${err}`); + } + })(); + }, []); + + const updateHandler = useCallback(async () => { + try { + const devices = await FindBluetoothDevices(); + setDev(devices); + await btCache.write(devices); + } catch (err) { + notify.error(`${err}`); + } + }, []); + + return ( + + + + + + + + + + + + + + + + + + + {dev?.map((dev) => { + return ; + })} + + + ); +}; diff --git a/gui/frontend/src/components/bt_devices/index.tsx b/gui/frontend/src/components/bt_devices/index.tsx new file mode 100644 index 0000000..b1f8a7a --- /dev/null +++ b/gui/frontend/src/components/bt_devices/index.tsx @@ -0,0 +1 @@ +export * from './devices'; diff --git a/gui/frontend/src/components/bt_devices/update_interval.tsx b/gui/frontend/src/components/bt_devices/update_interval.tsx new file mode 100644 index 0000000..2707665 --- /dev/null +++ b/gui/frontend/src/components/bt_devices/update_interval.tsx @@ -0,0 +1,121 @@ +import { Checkbox, FormControlLabel, Skeleton, TextField, Tooltip } from '@mui/material'; +import { type ChangeEventHandler, useCallback, useEffect, useState } from 'react'; +import { useDebounce } from 'react-use'; +import { disable, enable, isEnabled } from 'tauri-plugin-autostart-api'; + +import { type Config, config } from '@/backend_api'; +import { notify } from '@/components/notifications'; +import { useTranslation } from '@/hooks'; + +export const ConfigFields = () => { + const { t } = useTranslation(); + const [isAutoStart, setIsAutoStart] = useState(null); + const [conf, setConf] = useState(null); + const interval = conf?.battery_query_duration_minutes; + const warnTime = conf?.notify_battery_level; + + useEffect(() => { + (async () => { + setIsAutoStart(await isEnabled()); + setConf(await config.read()); + })(); + }, []); + + useDebounce( + async () => { + try { + if (conf) { + await config.write(conf); + } + } catch (err) { + notify.error(`${err}`); + } + }, + 2000, + [conf], + ); + + const handleAutoStart = useCallback(async () => { + setIsAutoStart(!isAutoStart); + if (isAutoStart) { + await enable(); + } else { + await disable(); + } + }, [isAutoStart]); + + const handleInterval: ChangeEventHandler = (e) => { + const newValue = Number(e.target.value); + const newTime = Number.isNaN(newValue) ? 30 : newValue; + + if (conf) { + setConf({ + ...conf, + // biome-ignore lint/style/useNamingConvention: + battery_query_duration_minutes: newTime, + }); + } + }; + + const handleWarnPerLevel: ChangeEventHandler = (e) => { + const newValue = Number(e.target.value); + const newPer = Number.isNaN(newValue) ? 20 : newValue; + if (conf) { + setConf({ + ...conf, + // biome-ignore lint/style/useNamingConvention: + notify_battery_level: newPer, + }); + } + }; + + return ( + <> + {isAutoStart !== null ? ( + + } + label={t('autostart-label')} + sx={{ m: 1, minWidth: 105 }} + /> + + ) : ( + + )} + + {interval !== undefined ? ( + + ) : ( + + )} + + {warnTime !== undefined ? ( + = 100} + helperText={warnTime < 0 || warnTime >= 100 ? '0 <= N <= 100' : ''} + id='outlined-number' + label={t('warn-limit-battery')} + onChange={handleWarnPerLevel} + sx={{ m: 1, minWidth: 105, width: 105 }} + type='number' + value={warnTime} + /> + ) : ( + + )} + + ); +}; diff --git a/gui/frontend/src/components/buttons/backup_btn.tsx b/gui/frontend/src/components/buttons/backup_btn.tsx new file mode 100644 index 0000000..46e03d4 --- /dev/null +++ b/gui/frontend/src/components/buttons/backup_btn.tsx @@ -0,0 +1,122 @@ +import FileDownloadIcon from '@mui/icons-material/FileDownload'; +import FileOpen from '@mui/icons-material/FileOpen'; +import { Button, Tooltip } from '@mui/material'; +import { type ReactNode, useState } from 'react'; + +import { backup } from '@/backend_api'; +import { + type DialogClickHandler, + LocalStorageDialog, + type LocalStorageDialogProps, + notify, +} from '@/components/notifications'; +import { useTranslation } from '@/hooks'; +import { type LocalCache, localStorageManager } from '@/utils/local_storage_manager'; + +type Props = { + buttonName: string; + /** Trigger to open dialog */ + onClick?: () => void; + startIcon: ReactNode; + tooltipTitle: ReactNode; +} & LocalStorageDialogProps; + +export const BackupButton = ({ buttonName, startIcon, tooltipTitle, onClick, ...props }: Readonly) => { + return ( + <> + + + + + + ); +}; + +export const ImportBackupButton = () => { + const { t } = useTranslation(); + const [settings, setSettings] = useState({}); + const [open, setOpen] = useState(false); + + const handleClick = async () => { + const newSettings = await backup.import(); + try { + if (newSettings) { + setSettings(newSettings); + setOpen(true); + } + } catch (e) { + notify.error(`${e}`); + } + }; + + const handleDialogClick: DialogClickHandler = (checkedKeys) => { + for (const key of checkedKeys) { + const value = settings[key]; + if (value) { + localStorage.setItem(key, value); + } + } + + window.location.reload(); // To enable + }; + + return ( + } + title={t('backup-import-dialog-title')} + tooltipTitle={t('backup-import-tooltip')} + /> + ); +}; + +export const ExportBackupButton = () => { + const { t } = useTranslation(); + const [open, setOpen] = useState(false); + + const handleClick: DialogClickHandler = async (checkedKeys) => { + try { + const exportTarget = localStorageManager.getFromKeys(checkedKeys); + if (await backup.export(exportTarget)) { + notify.success(t('backup-export-success')); + setOpen(false); + } + } catch (e) { + notify.error(`${e}`); + } + }; + + return ( + setOpen(true)} + open={open} + setOpen={setOpen} + startIcon={} + title={t('backup-export-dialog-title')} + tooltipTitle={t('backup-export-tooltip')} + /> + ); +}; diff --git a/gui/frontend/src/components/buttons/exec_js_btn.tsx b/gui/frontend/src/components/buttons/exec_js_btn.tsx new file mode 100644 index 0000000..f73215e --- /dev/null +++ b/gui/frontend/src/components/buttons/exec_js_btn.tsx @@ -0,0 +1,40 @@ +'use client'; +import { Checkbox, FormControlLabel, Tooltip } from '@mui/material'; + +import { useStorageState, useTranslation } from '@/hooks'; + +import type { FormControlLabelProps } from '@mui/material'; + +export const ExecJsBtn = ({ ...props }: Omit) => { + const { t } = useTranslation(); + const [runScript, setRunScript] = useStorageState('runScript', 'false'); + + return ( + + {t('custom-js-auto-run-tooltip')} +
+ {t('custom-js-auto-run-tooltip2')} + + } + > + { + const newValue = runScript === 'true' ? 'false' : 'true'; + if (newValue === 'false') { + window.location.reload(); + } + setRunScript(newValue); + }} + /> + } + label={t('custom-js-auto-run-label')} + /> +
+ ); +}; diff --git a/gui/frontend/src/components/buttons/import_lang_btn.tsx b/gui/frontend/src/components/buttons/import_lang_btn.tsx new file mode 100644 index 0000000..5836859 --- /dev/null +++ b/gui/frontend/src/components/buttons/import_lang_btn.tsx @@ -0,0 +1,51 @@ +import { FileOpen } from '@mui/icons-material'; +import { Button, Tooltip } from '@mui/material'; +import { useCallback } from 'react'; + +import { importLang } from '@/backend_api'; +import { notify } from '@/components/notifications'; +import { useTranslation } from '@/hooks'; + +export const ImportLangButton = () => { + const { t } = useTranslation(); + + const handleClick = useCallback(async () => { + try { + const contents = await importLang(); + if (contents) { + JSON.parse(contents); // Parse test + localStorage.setItem('custom-translation-dict', contents); + localStorage.setItem('locale', 'custom'); + window.location.reload(); // To enable + } + } catch (e) { + notify.error(`${e}`); + } + }, []); + + return ( + +

{t('import-lang-tooltip')}

+

{t('import-lang-tooltip2')}

+ + } + > + +
+ ); +}; diff --git a/gui/frontend/src/components/buttons/index.ts b/gui/frontend/src/components/buttons/index.ts new file mode 100644 index 0000000..a75a785 --- /dev/null +++ b/gui/frontend/src/components/buttons/index.ts @@ -0,0 +1,7 @@ +// @index('./*', f => `export * from '${f.path}'`) +export * from './backup_btn'; +export * from './update_btn'; +export * from './exec_js_btn'; +export * from './import_lang_btn'; +export * from './log_btn'; +export * from './path_selector'; diff --git a/gui/frontend/src/components/buttons/log_btn.tsx b/gui/frontend/src/components/buttons/log_btn.tsx new file mode 100644 index 0000000..ae7277f --- /dev/null +++ b/gui/frontend/src/components/buttons/log_btn.tsx @@ -0,0 +1,70 @@ +import { FileOpen } from '@mui/icons-material'; +import FolderOpenIcon from '@mui/icons-material/FolderOpen'; +import { Button, type ButtonProps, Tooltip } from '@mui/material'; + +import { openLogDir, openLogFile } from '@/backend_api'; +import { notify } from '@/components/notifications'; +import { useTranslation } from '@/hooks'; + +import type { ReactNode } from 'react'; + +type Props = { + buttonName: ReactNode; + tooltipTitle: ReactNode; +} & ButtonProps; + +export const LogButton = ({ buttonName, tooltipTitle, ...props }: Props) => ( + + + +); + +export const LogFileButton = () => { + const { t } = useTranslation(); + + const handleClick = async () => { + try { + await openLogFile(); + } catch (error) { + if (error instanceof Error) { + notify.error(error.message); + } + } + }; + + return ; +}; + +export const LogDirButton = () => { + const { t } = useTranslation(); + + const handleClick = async () => { + try { + await openLogDir(); + } catch (error) { + if (error instanceof Error) { + notify.error(error.message); + } + } + }; + + return ( + } + tooltipTitle={t('open-log-dir-tooltip')} + /> + ); +}; diff --git a/gui/frontend/src/components/buttons/path_selector.tsx b/gui/frontend/src/components/buttons/path_selector.tsx new file mode 100644 index 0000000..9c6978b --- /dev/null +++ b/gui/frontend/src/components/buttons/path_selector.tsx @@ -0,0 +1,35 @@ +import FolderOpenIcon from '@mui/icons-material/FolderOpen'; +import { Button } from '@mui/material'; + +import { openPath } from '@/backend_api'; +import { notify } from '@/components/notifications'; +import { useTranslation } from '@/hooks'; + +type Props = Readonly<{ + path: string; + setPath: (value: string) => void; + isDir?: boolean; +}>; + +export function SelectPathButton({ path, isDir = false, setPath }: Props) { + const { t } = useTranslation(); + const handleClick = async () => { + openPath(path, { setPath, directory: isDir }).catch((e) => notify.error(`${e}`)); + }; + + return ( + + ); +} diff --git a/gui/frontend/src/components/buttons/update_btn.tsx b/gui/frontend/src/components/buttons/update_btn.tsx new file mode 100644 index 0000000..93f4f4c --- /dev/null +++ b/gui/frontend/src/components/buttons/update_btn.tsx @@ -0,0 +1,44 @@ +import SyncIcon from '@mui/icons-material/Sync'; +import LoadingButton from '@mui/lab/LoadingButton'; +import { Tooltip } from '@mui/material'; +import { useState } from 'react'; + +import { useTranslation } from '@/hooks'; + +type Props = Readonly<{ + eventFn: () => Promise; +}>; + +/** + * Update bluetooth information + * + * Icon ref + * - https://mui.com/material-ui/material-icons/ + */ +export function UpdateButton({ eventFn }: Props) { + const { t } = useTranslation(); + const [loading, setLoading] = useState(false); + + return ( + + } + loading={loading} + loadingPosition='end' + onChange={async () => { + setLoading(true); + await eventFn(); + setLoading(false); + }} + sx={{ + width: '100%', + minHeight: '40px', + }} + type='submit' + variant='contained' + > + {loading ? t('updating-btn') : t('update-btn')} + + + ); +} diff --git a/gui/frontend/src/components/editor/atom_onedark_pro.ts b/gui/frontend/src/components/editor/atom_onedark_pro.ts new file mode 100644 index 0000000..4a19c9f --- /dev/null +++ b/gui/frontend/src/components/editor/atom_onedark_pro.ts @@ -0,0 +1,2000 @@ +// Copyright (c) 2019 Cosmo Myzrail Gorynych +// SPDX-License-Identifier: MIT +// +// https://github.com/ct-js/ct-js/blob/ec638ccdc01e990ed56445873e2a9c768740ecea/src/node_requires/monaco-themes/OneDarkPro.json +import type monaco from 'monaco-editor/esm/vs/editor/editor.api'; + +export const atomOneDarkPro: monaco.editor.IStandaloneThemeData = { + inherit: true, + base: 'vs-dark', + colors: { + 'activityBar.background': '#282c34', + 'activityBar.foreground': '#d7dae0', + 'activityBarBadge.background': '#4d78cc', + 'activityBarBadge.foreground': '#f8fafd', + 'badge.background': '#282c34', + 'button.background': '#404754', + 'button.secondaryBackground': '#30333d', + 'button.secondaryForeground': '#c0bdbd', + 'checkbox.border': '#404754', + 'debugToolBar.background': '#21252b', + descriptionForeground: '#abb2bf', + 'diffEditor.insertedTextBackground': '#00809b33', + 'dropdown.background': '#21252b', + 'dropdown.border': '#21252b', + 'editor.background': '#282c34', + 'editor.findMatchBackground': '#42557b', + 'editor.findMatchBorder': '#457dff', + 'editor.findMatchHighlightBackground': '#6199ff2f', + 'editor.foreground': '#abb2bf', + 'editorBracketHighlight.foreground1': '#d19a66', + 'editorBracketHighlight.foreground2': '#c678dd', + 'editorBracketHighlight.foreground3': '#56b6c2', + 'editorHoverWidget.highlightForeground': '#61afef', + 'editorInlayHint.foreground': '#abb2bf', + 'editorInlayHint.background': '#2c313c', + 'editor.lineHighlightBackground': '#2c313c', + 'editorLineNumber.activeForeground': '#abb2bf', + 'editorGutter.addedBackground': '#109868', + 'editorGutter.deletedBackground': '#9A353D', + 'editorGutter.modifiedBackground': '#948B60', + 'editorOverviewRuler.addedBackground': '#109868', + 'editorOverviewRuler.deletedBackground': '#9A353D', + 'editorOverviewRuler.modifiedBackground': '#948B60', + 'editor.selectionBackground': '#67769660', + 'editor.selectionHighlightBackground': '#ffffff10', + 'editor.selectionHighlightBorder': '#dddddd', + 'editor.wordHighlightBackground': '#d2e0ff2f', + 'editor.wordHighlightBorder': '#7f848e', + 'editor.wordHighlightStrongBackground': '#abb2bf26', + 'editor.wordHighlightStrongBorder': '#7f848e', + 'editorBracketMatch.background': '#515a6b', + 'editorBracketMatch.border': '#515a6b', + 'editorCursor.background': '#ffffffc9', + 'editorCursor.foreground': '#528bff', + 'editorError.foreground': '#c24038', + 'editorGroup.background': '#181a1f', + 'editorGroup.border': '#181a1f', + 'editorGroupHeader.tabsBackground': '#21252b', + 'editorHoverWidget.background': '#21252b', + 'editorHoverWidget.border': '#181a1f', + 'editorIndentGuide.activeBackground': '#c8c8c859', + 'editorIndentGuide.background': '#3b4048', + 'editorLineNumber.foreground': '#495162', + 'editorMarkerNavigation.background': '#21252b', + 'editorRuler.foreground': '#abb2bf26', + 'editorSuggestWidget.background': '#21252b', + 'editorSuggestWidget.border': '#181a1f', + 'editorSuggestWidget.selectedBackground': '#2c313a', + 'editorWarning.foreground': '#d19a66', + 'editorWhitespace.foreground': '#ffffff1d', + 'editorWidget.background': '#21252b', + focusBorder: '#3e4452', + 'gitDecoration.ignoredResourceForeground': '#636b78', + 'input.background': '#1d1f23', + 'input.foreground': '#abb2bf', + 'list.activeSelectionBackground': '#2c313a', + 'list.activeSelectionForeground': '#d7dae0', + 'list.focusBackground': '#323842', + 'list.focusForeground': '#f0f0f0', + 'list.highlightForeground': '#ecebeb', + 'list.hoverBackground': '#2c313a', + 'list.hoverForeground': '#abb2bf', + 'list.inactiveSelectionBackground': '#323842', + 'list.inactiveSelectionForeground': '#d7dae0', + 'list.warningForeground': '#d19a66', + 'menu.foreground': '#abb2bf', + 'menu.separatorBackground': '#343a45', + 'minimapGutter.addedBackground': '#109868', + 'minimapGutter.deletedBackground': '#9A353D', + 'minimapGutter.modifiedBackground': '#948B60', + 'panel.border': '#3e4452', + 'panelSectionHeader.background': '#21252b', + 'peekViewEditor.background': '#1b1d23', + 'peekViewEditor.matchHighlightBackground': '#29244b', + 'peekViewResult.background': '#22262b', + 'scrollbar.shadow': '#23252c', + 'scrollbarSlider.activeBackground': '#747d9180', + 'scrollbarSlider.background': '#4e566660', + 'scrollbarSlider.hoverBackground': '#5a637580', + 'settings.focusedRowBackground': '#282c34', + 'settings.headerForeground': '#fff', + 'sideBar.background': '#21252b', + 'sideBar.foreground': '#abb2bf', + 'sideBarSectionHeader.background': '#282c34', + 'sideBarSectionHeader.foreground': '#abb2bf', + 'statusBar.background': '#21252b', + 'statusBar.debuggingBackground': '#cc6633', + 'statusBar.debuggingBorder': '#ff000000', + 'statusBar.debuggingForeground': '#ffffff', + 'statusBar.foreground': '#9da5b4', + 'statusBar.noFolderBackground': '#21252b', + 'statusBarItem.remoteBackground': '#4d78cc', + 'statusBarItem.remoteForeground': '#f8fafd', + 'tab.activeBackground': '#282c34', + 'tab.activeBorder': '#b4b4b4', + 'tab.activeForeground': '#dcdcdc', + 'tab.border': '#181a1f', + 'tab.hoverBackground': '#323842', + 'tab.inactiveBackground': '#21252b', + 'tab.unfocusedHoverBackground': '#323842', + 'terminal.ansiBlack': '#3f4451', + 'terminal.ansiBlue': '#4aa5f0', + 'terminal.ansiBrightBlack': '#4f5666', + 'terminal.ansiBrightBlue': '#4dc4ff', + 'terminal.ansiBrightCyan': '#4cd1e0', + 'terminal.ansiBrightGreen': '#a5e075', + 'terminal.ansiBrightMagenta': '#de73ff', + 'terminal.ansiBrightRed': '#ff616e', + 'terminal.ansiBrightWhite': '#e6e6e6', + 'terminal.ansiBrightYellow': '#f0a45d', + 'terminal.ansiCyan': '#42b3c2', + 'terminal.ansiGreen': '#8cc265', + 'terminal.ansiMagenta': '#c162de', + 'terminal.ansiRed': '#e05561', + 'terminal.ansiWhite': '#d7dae0', + 'terminal.ansiYellow': '#d18f52', + 'terminal.background': '#282c34', + 'terminal.border': '#3e4452', + 'terminal.foreground': '#abb2bf', + 'terminal.selectionBackground': '#abb2bf30', + 'textBlockQuote.background': '#2e3440', + 'textBlockQuote.border': '#4b5362', + 'textLink.foreground': '#61afef', + 'textPreformat.foreground': '#d19a66', + 'titleBar.activeBackground': '#282c34', + 'titleBar.activeForeground': '#9da5b4', + 'titleBar.inactiveBackground': '#282c34', + 'titleBar.inactiveForeground': '#6b717d', + 'tree.indentGuidesStroke': '#ffffff1d', + 'walkThrough.embeddedEditorBackground': '#2e3440', + 'welcomePage.buttonHoverBackground': '#404754', + }, + rules: [ + { + foreground: '#abb2bf', + token: 'meta.embedded', + }, + { + foreground: '#61AFEF', + token: 'identifier', + }, + { + foreground: '#E06C75', + token: 'type.identifier', + }, + { + foreground: '#D19A66', + token: 'number', + }, + { + foreground: '#e06c75', + token: 'punctuation.definition.delayed.unison', + }, + { + foreground: '#e06c75', + token: 'punctuation.definition.list.begin.unison', + }, + { + foreground: '#e06c75', + token: 'punctuation.definition.list.end.unison', + }, + { + foreground: '#e06c75', + token: 'punctuation.definition.ability.begin.unison', + }, + { + foreground: '#e06c75', + token: 'punctuation.definition.ability.end.unison', + }, + { + foreground: '#e06c75', + token: 'punctuation.operator.assignment.as.unison', + }, + { + foreground: '#e06c75', + token: 'punctuation.separator.pipe.unison', + }, + { + foreground: '#e06c75', + token: 'punctuation.separator.delimiter.unison', + }, + { + foreground: '#e06c75', + token: 'punctuation.definition.hash.unison', + }, + { + foreground: '#c678dd', + token: 'variable.other.generic-type.haskell', + }, + { + foreground: '#d19a66', + token: 'storage.type.haskell', + }, + { + foreground: '#e06c75', + token: 'support.variable.magic.python', + }, + { + foreground: '#abb2bf', + token: 'punctuation.separator.period.python', + }, + { + foreground: '#abb2bf', + token: 'punctuation.separator.element.python', + }, + { + foreground: '#abb2bf', + token: 'punctuation.parenthesis.begin.python', + }, + { + foreground: '#abb2bf', + token: 'punctuation.parenthesis.end.python', + }, + { + foreground: '#e5c07b', + token: 'variable.parameter.function.language.special.self.python', + }, + { + foreground: '#e5c07b', + token: 'variable.parameter.function.language.special.cls.python', + }, + { + foreground: '#abb2bf', + token: 'storage.modifier.lifetime.rust', + }, + { + foreground: '#61afef', + token: 'support.function.std.rust', + }, + { + foreground: '#e5c07b', + token: 'entity.name.lifetime.rust', + }, + { + foreground: '#e06c75', + token: 'variable.language.rust', + }, + { + foreground: '#c678dd', + token: 'support.constant.edge', + }, + { + foreground: '#e06c75', + token: 'constant.other.character-class.regexp', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.word', + }, + { + foreground: '#d19a66', + token: 'keyword.operator.quantifier.regexp', + }, + { + foreground: '#abb2bf', + token: 'variable.parameter.function', + }, + { + foreground: '#5c6370', + token: 'comment markup.link', + }, + { + foreground: '#e5c07b', + token: 'markup.changed.diff', + }, + { + foreground: '#61afef', + token: 'meta.diff.header.from-file', + }, + { + foreground: '#61afef', + token: 'meta.diff.header.to-file', + }, + { + foreground: '#61afef', + token: 'punctuation.definition.from-file.diff', + }, + { + foreground: '#61afef', + token: 'punctuation.definition.to-file.diff', + }, + { + foreground: '#98c379', + token: 'markup.inserted.diff', + }, + { + foreground: '#e06c75', + token: 'markup.deleted.diff', + }, + { + foreground: '#e06c75', + token: 'meta.function.c', + }, + { + foreground: '#e06c75', + token: 'meta.function.cpp', + }, + { + foreground: '#abb2bf', + token: 'punctuation.section.block.begin.bracket.curly.cpp', + }, + { + foreground: '#abb2bf', + token: 'punctuation.section.block.end.bracket.curly.cpp', + }, + { + foreground: '#abb2bf', + token: 'punctuation.terminator.statement.c', + }, + { + foreground: '#abb2bf', + token: 'punctuation.section.block.begin.bracket.curly.c', + }, + { + foreground: '#abb2bf', + token: 'punctuation.section.block.end.bracket.curly.c', + }, + { + foreground: '#abb2bf', + token: 'punctuation.section.parens.begin.bracket.round.c', + }, + { + foreground: '#abb2bf', + token: 'punctuation.section.parens.end.bracket.round.c', + }, + { + foreground: '#abb2bf', + token: 'punctuation.section.parameters.begin.bracket.round.c', + }, + { + foreground: '#abb2bf', + token: 'punctuation.section.parameters.end.bracket.round.c', + }, + { + foreground: '#abb2bf', + token: 'punctuation.separator.key-value', + }, + { + foreground: '#61afef', + token: 'keyword.operator.expression.import', + }, + { + foreground: '#e5c07b', + token: 'support.constant.math', + }, + { + foreground: '#d19a66', + token: 'support.constant.property.math', + }, + { + foreground: '#e5c07b', + token: 'variable.other.constant', + }, + { + foreground: '#e5c07b', + token: 'storage.type.annotation.java', + }, + { + foreground: '#e5c07b', + token: 'storage.type.object.array.java', + }, + { + foreground: '#e06c75', + token: 'source.java', + }, + { + foreground: '#abb2bf', + token: 'punctuation.section.block.begin.java', + }, + { + foreground: '#abb2bf', + token: 'punctuation.section.block.end.java', + }, + { + foreground: '#abb2bf', + token: 'punctuation.definition.method-parameters.begin.java', + }, + { + foreground: '#abb2bf', + token: 'punctuation.definition.method-parameters.end.java', + }, + { + foreground: '#abb2bf', + token: 'meta.method.identifier.java', + }, + { + foreground: '#abb2bf', + token: 'punctuation.section.method.begin.java', + }, + { + foreground: '#abb2bf', + token: 'punctuation.section.method.end.java', + }, + { + foreground: '#abb2bf', + token: 'punctuation.terminator.java', + }, + { + foreground: '#abb2bf', + token: 'punctuation.section.class.begin.java', + }, + { + foreground: '#abb2bf', + token: 'punctuation.section.class.end.java', + }, + { + foreground: '#abb2bf', + token: 'punctuation.section.inner-class.begin.java', + }, + { + foreground: '#abb2bf', + token: 'punctuation.section.inner-class.end.java', + }, + { + foreground: '#abb2bf', + token: 'meta.method-call.java', + }, + { + foreground: '#abb2bf', + token: 'punctuation.section.class.begin.bracket.curly.java', + }, + { + foreground: '#abb2bf', + token: 'punctuation.section.class.end.bracket.curly.java', + }, + { + foreground: '#abb2bf', + token: 'punctuation.section.method.begin.bracket.curly.java', + }, + { + foreground: '#abb2bf', + token: 'punctuation.section.method.end.bracket.curly.java', + }, + { + foreground: '#abb2bf', + token: 'punctuation.separator.period.java', + }, + { + foreground: '#abb2bf', + token: 'punctuation.bracket.angle.java', + }, + { + foreground: '#abb2bf', + token: 'punctuation.definition.annotation.java', + }, + { + foreground: '#abb2bf', + token: 'meta.method.body.java', + }, + { + foreground: '#61afef', + token: 'meta.method.java', + }, + { + foreground: '#e5c07b', + token: 'storage.modifier.import.java', + }, + { + foreground: '#e5c07b', + token: 'storage.type.java', + }, + { + foreground: '#e5c07b', + token: 'storage.type.generic.java', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.instanceof.java', + }, + { + foreground: '#e06c75', + token: 'meta.definition.variable.name.java', + }, + { + foreground: '#56b6c2', + token: 'keyword.operator.logical', + }, + { + foreground: '#56b6c2', + token: 'keyword.operator.bitwise', + }, + { + foreground: '#56b6c2', + token: 'keyword.operator.channel', + }, + { + foreground: '#d19a66', + token: 'support.constant.property-value.scss', + }, + { + foreground: '#d19a66', + token: 'support.constant.property-value.css', + }, + { + foreground: '#56b6c2', + token: 'keyword.operator.css', + }, + { + foreground: '#56b6c2', + token: 'keyword.operator.scss', + }, + { + foreground: '#56b6c2', + token: 'keyword.operator.less', + }, + { + foreground: '#d19a66', + token: 'support.constant.color.w3c-standard-color-name.css', + }, + { + foreground: '#d19a66', + token: 'support.constant.color.w3c-standard-color-name.scss', + }, + { + foreground: '#abb2bf', + token: 'punctuation.separator.list.comma.css', + }, + { + foreground: '#d19a66', + token: 'support.constant.color.w3c-standard-color-name.css', + }, + { + foreground: '#56b6c2', + token: 'support.type.vendored.property-name.css', + }, + { + foreground: '#e5c07b', + token: 'support.module.node', + }, + { + foreground: '#e5c07b', + token: 'support.type.object.module', + }, + { + foreground: '#e5c07b', + token: 'support.module.node', + }, + { + foreground: '#e5c07b', + token: 'entity.name.type.module', + }, + { + foreground: '#e06c75', + token: 'variable.other.readwrite', + }, + { + foreground: '#e06c75', + token: 'meta.object-literal.key', + }, + { + foreground: '#e06c75', + token: 'support.variable.property', + }, + { + foreground: '#e06c75', + token: 'support.variable.object.process', + }, + { + foreground: '#e06c75', + token: 'support.variable.object.node', + }, + { + foreground: '#d19a66', + token: 'support.constant.json', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.expression.instanceof', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.new', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.ternary', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.optional', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.expression.keyof', + }, + { + foreground: '#e06c75', + token: 'support.type.object.console', + }, + { + foreground: '#d19a66', + token: 'support.variable.property.process', + }, + { + foreground: '#61afef', + token: 'entity.name.function', + }, + { + foreground: '#61afef', + token: 'support.function.console', + }, + { + foreground: '#abb2bf', + token: 'keyword.operator.misc.rust', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.sigil.rust', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.delete', + }, + { + foreground: '#56b6c2', + token: 'support.type.object.dom', + }, + { + foreground: '#e06c75', + token: 'support.variable.dom', + }, + { + foreground: '#e06c75', + token: 'support.variable.property.dom', + }, + { + foreground: '#56b6c2', + token: 'keyword.operator.arithmetic', + }, + { + foreground: '#56b6c2', + token: 'keyword.operator.comparison', + }, + { + foreground: '#56b6c2', + token: 'keyword.operator.decrement', + }, + { + foreground: '#56b6c2', + token: 'keyword.operator.increment', + }, + { + foreground: '#56b6c2', + token: 'keyword.operator.relational', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.assignment.c', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.comparison.c', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.c', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.increment.c', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.decrement.c', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.bitwise.shift.c', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.assignment.cpp', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.comparison.cpp', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.cpp', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.increment.cpp', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.decrement.cpp', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.bitwise.shift.cpp', + }, + { + foreground: '#abb2bf', + token: 'punctuation.separator.delimiter', + }, + { + foreground: '#c678dd', + token: 'punctuation.separator.c', + }, + { + foreground: '#c678dd', + token: 'punctuation.separator.cpp', + }, + { + foreground: '#56b6c2', + token: 'support.type.posix-reserved.c', + }, + { + foreground: '#56b6c2', + token: 'support.type.posix-reserved.cpp', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.sizeof.c', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.sizeof.cpp', + }, + { + foreground: '#d19a66', + token: 'variable.parameter.function.language.python', + }, + { + foreground: '#56b6c2', + token: 'support.type.python', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.logical.python', + }, + { + foreground: '#d19a66', + token: 'variable.parameter.function.python', + }, + { + foreground: '#abb2bf', + token: 'punctuation.definition.arguments.begin.python', + }, + { + foreground: '#abb2bf', + token: 'punctuation.definition.arguments.end.python', + }, + { + foreground: '#abb2bf', + token: 'punctuation.separator.arguments.python', + }, + { + foreground: '#abb2bf', + token: 'punctuation.definition.list.begin.python', + }, + { + foreground: '#abb2bf', + token: 'punctuation.definition.list.end.python', + }, + { + foreground: '#61afef', + token: 'meta.function-call.generic.python', + }, + { + foreground: '#d19a66', + token: 'constant.character.format.placeholder.other.python', + }, + { + foreground: '#abb2bf', + token: 'keyword.operator', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.assignment.compound', + }, + { + foreground: '#56b6c2', + token: 'keyword.operator.assignment.compound.js', + }, + { + foreground: '#56b6c2', + token: 'keyword.operator.assignment.compound.ts', + }, + { + foreground: '#c678dd', + token: 'keyword', + }, + { + foreground: '#e5c07b', + token: 'entity.name.namespace', + }, + { + foreground: '#e06c75', + token: 'variable', + }, + { + foreground: '#abb2bf', + token: 'variable.c', + }, + { + foreground: '#e5c07b', + token: 'variable.language', + }, + { + foreground: '#abb2bf', + token: 'token.variable.parameter.java', + }, + { + foreground: '#e5c07b', + token: 'import.storage.java', + }, + { + foreground: '#c678dd', + token: 'token.package.keyword', + }, + { + foreground: '#abb2bf', + token: 'token.package', + }, + { + foreground: '#61afef', + token: 'entity.name.function', + }, + { + foreground: '#61afef', + token: 'meta.require', + }, + { + foreground: '#61afef', + token: 'support.function.any-method', + }, + { + foreground: '#61afef', + token: 'variable.function', + }, + { + foreground: '#e5c07b', + token: 'entity.name.type.namespace', + }, + { + foreground: '#e5c07b', + token: 'support.class', + }, + { + foreground: '#e5c07b', + token: ' entity.name.type.class', + }, + { + foreground: '#e5c07b', + token: 'entity.name.class.identifier.namespace.type', + }, + { + foreground: '#e5c07b', + token: 'entity.name.class', + }, + { + foreground: '#e5c07b', + token: 'variable.other.class.js', + }, + { + foreground: '#e5c07b', + token: 'variable.other.class.ts', + }, + { + foreground: '#e06c75', + token: 'variable.other.class.php', + }, + { + foreground: '#e5c07b', + token: 'entity.name.type', + }, + { + foreground: '#c678dd', + token: 'keyword.control', + }, + { + foreground: '#d19a66', + token: 'control.elements', + }, + { + foreground: '#d19a66', + token: ' keyword.operator.less', + }, + { + foreground: '#61afef', + token: 'keyword.other.special-method', + }, + { + foreground: '#c678dd', + token: 'storage', + }, + { + foreground: '#c678dd', + token: 'token.storage', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.expression.delete', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.expression.in', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.expression.of', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.expression.instanceof', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.new', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.expression.typeof', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.expression.void', + }, + { + foreground: '#e5c07b', + token: 'token.storage.type.java', + }, + { + foreground: '#56b6c2', + token: 'support.function', + }, + { + foreground: '#abb2bf', + token: 'support.type.property-name', + }, + { + foreground: '#e06c75', + token: 'support.type.property-name.toml', + }, + { + foreground: '#e06c75', + token: ' support.type.property-name.table.toml', + }, + { + foreground: '#e06c75', + token: ' support.type.property-name.array.toml', + }, + { + foreground: '#abb2bf', + token: 'support.constant.property-value', + }, + { + foreground: '#d19a66', + token: 'support.constant.font-name', + }, + { + foreground: '#abb2bf', + token: 'meta.tag', + }, + { + foreground: '#98c379', + token: 'string', + }, + { + foreground: '#56b6c2', + token: 'constant.other.symbol', + }, + { + foreground: '#d19a66', + token: 'constant.numeric', + }, + { + foreground: '#d19a66', + token: 'constant', + }, + { + foreground: '#d19a66', + token: 'punctuation.definition.constant', + }, + { + foreground: '#e06c75', + token: 'entity.name.tag', + }, + { + foreground: '#d19a66', + token: 'entity.other.attribute-name', + }, + { + foreground: '#61afef', + token: 'entity.other.attribute-name.id', + }, + { + foreground: '#d19a66', + token: 'entity.other.attribute-name.class.css', + }, + { + foreground: '#c678dd', + token: 'meta.selector', + }, + { + foreground: '#e06c75', + token: 'markup.heading', + }, + { + foreground: '#61afef', + token: 'markup.heading punctuation.definition.heading', + }, + { + foreground: '#61afef', + token: ' entity.name.section', + }, + { + foreground: '#e06c75', + token: 'keyword.other.unit', + }, + { + foreground: '#d19a66', + token: 'markup.bold', + }, + { + foreground: '#d19a66', + token: 'todo.bold', + }, + { + foreground: '#e5c07b', + token: 'punctuation.definition.bold', + }, + { + foreground: '#c678dd', + token: 'markup.italic', + }, + { + foreground: '#c678dd', + token: ' punctuation.definition.italic', + }, + { + foreground: '#c678dd', + token: 'todo.emphasis', + }, + { + foreground: '#c678dd', + token: 'emphasis md', + }, + { + foreground: '#e06c75', + token: 'entity.name.section.markdown', + }, + { + foreground: '#e06c75', + token: 'punctuation.definition.heading.markdown', + }, + { + foreground: '#e5c07b', + token: 'punctuation.definition.list.begin.markdown', + }, + { + foreground: '#abb2bf', + token: 'markup.heading.setext', + }, + { + foreground: '#d19a66', + token: 'punctuation.definition.bold.markdown', + }, + { + foreground: '#98c379', + token: 'markup.inline.raw.markdown', + }, + { + foreground: '#98c379', + token: 'markup.inline.raw.string.markdown', + }, + { + foreground: '#e5c07b', + token: 'punctuation.definition.raw.markdown', + }, + { + foreground: '#e5c07b', + token: 'punctuation.definition.list.markdown', + }, + { + foreground: '#e06c75', + token: 'punctuation.definition.string.begin.markdown', + }, + { + foreground: '#e06c75', + token: 'punctuation.definition.string.end.markdown', + }, + { + foreground: '#e06c75', + token: 'punctuation.definition.metadata.markdown', + }, + { + foreground: '#e06c75', + token: 'beginning.punctuation.definition.list.markdown', + }, + { + foreground: '#e06c75', + token: 'punctuation.definition.metadata.markdown', + }, + { + foreground: '#c678dd', + token: 'markup.underline.link.markdown', + }, + { + foreground: '#c678dd', + token: 'markup.underline.link.image.markdown', + }, + { + foreground: '#61afef', + token: 'string.other.link.title.markdown', + }, + { + foreground: '#61afef', + token: 'string.other.link.description.markdown', + }, + { + foreground: '#98c379', + token: 'markup.raw.monospace.asciidoc', + }, + { + foreground: '#e5c07b', + token: 'punctuation.definition.asciidoc', + }, + { + foreground: '#e5c07b', + token: 'markup.list.asciidoc', + }, + { + foreground: '#c678dd', + token: 'markup.link.asciidoc', + }, + { + foreground: '#c678dd', + token: 'markup.other.url.asciidoc', + }, + { + foreground: '#61afef', + token: 'string.unquoted.asciidoc', + }, + { + foreground: '#61afef', + token: 'markup.other.url.asciidoc', + }, + { + foreground: '#56b6c2', + token: 'string.regexp', + }, + { + foreground: '#e06c75', + token: 'punctuation.section.embedded', + }, + { + foreground: '#e06c75', + token: ' variable.interpolation', + }, + { + foreground: '#c678dd', + token: 'punctuation.section.embedded.begin', + }, + { + foreground: '#c678dd', + token: 'punctuation.section.embedded.end', + }, + { + foreground: '#ffffff', + token: 'invalid.illegal', + }, + { + foreground: '#abb2bf', + token: 'invalid.illegal.bad-ampersand.html', + }, + { + foreground: '#e06c75', + token: 'invalid.illegal.unrecognized-tag.html', + }, + { + foreground: '#ffffff', + token: 'invalid.broken', + }, + { + foreground: '#ffffff', + token: 'invalid.deprecated', + }, + { + foreground: '#d19a66', + token: 'invalid.deprecated.entity.other.attribute-name.html', + }, + { + foreground: '#ffffff', + token: 'invalid.unimplemented', + }, + { + foreground: '#e06c75', + token: 'source.json meta.structure.dictionary.json > string.quoted.json', + }, + { + foreground: '#e06c75', + token: 'source.json meta.structure.dictionary.json > string.quoted.json > punctuation.string', + }, + { + foreground: '#98c379', + token: 'source.json meta.structure.dictionary.json > value.json > string.quoted.json', + }, + { + foreground: '#98c379', + token: 'source.json meta.structure.array.json > value.json > string.quoted.json', + }, + { + foreground: '#98c379', + token: 'source.json meta.structure.dictionary.json > value.json > string.quoted.json > punctuation', + }, + { + foreground: '#98c379', + token: 'source.json meta.structure.array.json > value.json > string.quoted.json > punctuation', + }, + { + foreground: '#56b6c2', + token: 'source.json meta.structure.dictionary.json > constant.language.json', + }, + { + foreground: '#56b6c2', + token: 'source.json meta.structure.array.json > constant.language.json', + }, + { + foreground: '#e06c75', + token: 'support.type.property-name.json', + }, + { + foreground: '#e06c75', + token: 'support.type.property-name.json punctuation', + }, + { + foreground: '#c678dd', + token: 'text.html.laravel-blade source.php.embedded.line.html entity.name.tag.laravel-blade', + }, + { + foreground: '#c678dd', + token: 'text.html.laravel-blade source.php.embedded.line.html support.constant.laravel-blade', + }, + { + foreground: '#e5c07b', + token: 'support.other.namespace.use.php', + }, + { + foreground: '#e5c07b', + token: 'support.other.namespace.use-as.php', + }, + { + foreground: '#e5c07b', + token: 'entity.other.alias.php', + }, + { + foreground: '#e5c07b', + token: 'meta.interface.php', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.error-control.php', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.type.php', + }, + { + foreground: '#abb2bf', + token: 'punctuation.section.array.begin.php', + }, + { + foreground: '#abb2bf', + token: 'punctuation.section.array.end.php', + }, + { + foreground: '#f44747', + token: 'invalid.illegal.non-null-typehinted.php', + }, + { + foreground: '#e5c07b', + token: 'storage.type.php', + }, + { + foreground: '#e5c07b', + token: 'meta.other.type.phpdoc.php', + }, + { + foreground: '#e5c07b', + token: 'keyword.other.type.php', + }, + { + foreground: '#e5c07b', + token: 'keyword.other.array.phpdoc.php', + }, + { + foreground: '#61afef', + token: 'meta.function-call.php', + }, + { + foreground: '#61afef', + token: 'meta.function-call.object.php', + }, + { + foreground: '#61afef', + token: 'meta.function-call.static.php', + }, + { + foreground: '#abb2bf', + token: 'punctuation.definition.parameters.begin.bracket.round.php', + }, + { + foreground: '#abb2bf', + token: 'punctuation.definition.parameters.end.bracket.round.php', + }, + { + foreground: '#abb2bf', + token: 'punctuation.separator.delimiter.php', + }, + { + foreground: '#abb2bf', + token: 'punctuation.section.scope.begin.php', + }, + { + foreground: '#abb2bf', + token: 'punctuation.section.scope.end.php', + }, + { + foreground: '#abb2bf', + token: 'punctuation.terminator.expression.php', + }, + { + foreground: '#abb2bf', + token: 'punctuation.definition.arguments.begin.bracket.round.php', + }, + { + foreground: '#abb2bf', + token: 'punctuation.definition.arguments.end.bracket.round.php', + }, + { + foreground: '#abb2bf', + token: 'punctuation.definition.storage-type.begin.bracket.round.php', + }, + { + foreground: '#abb2bf', + token: 'punctuation.definition.storage-type.end.bracket.round.php', + }, + { + foreground: '#abb2bf', + token: 'punctuation.definition.array.begin.bracket.round.php', + }, + { + foreground: '#abb2bf', + token: 'punctuation.definition.array.end.bracket.round.php', + }, + { + foreground: '#abb2bf', + token: 'punctuation.definition.begin.bracket.round.php', + }, + { + foreground: '#abb2bf', + token: 'punctuation.definition.end.bracket.round.php', + }, + { + foreground: '#abb2bf', + token: 'punctuation.definition.begin.bracket.curly.php', + }, + { + foreground: '#abb2bf', + token: 'punctuation.definition.end.bracket.curly.php', + }, + { + foreground: '#abb2bf', + token: 'punctuation.definition.section.switch-block.end.bracket.curly.php', + }, + { + foreground: '#abb2bf', + token: 'punctuation.definition.section.switch-block.start.bracket.curly.php', + }, + { + foreground: '#abb2bf', + token: 'punctuation.definition.section.switch-block.begin.bracket.curly.php', + }, + { + foreground: '#abb2bf', + token: 'punctuation.definition.section.switch-block.end.bracket.curly.php', + }, + { + foreground: '#d19a66', + token: 'support.constant.core.rust', + }, + { + foreground: '#d19a66', + token: 'support.constant.ext.php', + }, + { + foreground: '#d19a66', + token: 'support.constant.std.php', + }, + { + foreground: '#d19a66', + token: 'support.constant.core.php', + }, + { + foreground: '#d19a66', + token: 'support.constant.parser-token.php', + }, + { + foreground: '#61afef', + token: 'entity.name.goto-label.php', + }, + { + foreground: '#61afef', + token: 'support.other.php', + }, + { + foreground: '#56b6c2', + token: 'keyword.operator.logical.php', + }, + { + foreground: '#56b6c2', + token: 'keyword.operator.bitwise.php', + }, + { + foreground: '#56b6c2', + token: 'keyword.operator.arithmetic.php', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.regexp.php', + }, + { + foreground: '#56b6c2', + token: 'keyword.operator.comparison.php', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.heredoc.php', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.nowdoc.php', + }, + { + foreground: '#61afef', + token: 'meta.function.decorator.python', + }, + { + foreground: '#56b6c2', + token: 'support.token.decorator.python', + }, + { + foreground: '#56b6c2', + token: 'meta.function.decorator.identifier.python', + }, + { + foreground: '#abb2bf', + token: 'function.parameter', + }, + { + foreground: '#abb2bf', + token: 'function.brace', + }, + { + foreground: '#abb2bf', + token: 'function.parameter.ruby', + }, + { + foreground: '#abb2bf', + token: ' function.parameter.cs', + }, + { + foreground: '#56b6c2', + token: 'constant.language.symbol.ruby', + }, + { + foreground: '#56b6c2', + token: 'constant.language.symbol.hashkey.ruby', + }, + { + foreground: '#56b6c2', + token: 'rgb-value', + }, + { + foreground: '#d19a66', + token: 'inline-color-decoration rgb-value', + }, + { + foreground: '#d19a66', + token: 'less rgb-value', + }, + { + foreground: '#e06c75', + token: 'selector.sass', + }, + { + foreground: '#e5c07b', + token: 'support.type.primitive.ts', + }, + { + foreground: '#e5c07b', + token: 'support.type.builtin.ts', + }, + { + foreground: '#e5c07b', + token: 'support.type.primitive.tsx', + }, + { + foreground: '#e5c07b', + token: 'support.type.builtin.tsx', + }, + { + foreground: '#abb2bf', + token: 'block.scope.end', + }, + { + foreground: '#abb2bf', + token: 'block.scope.begin', + }, + { + foreground: '#e5c07b', + token: 'storage.type.cs', + }, + { + foreground: '#e06c75', + token: 'entity.name.variable.local.cs', + }, + { + foreground: '#61afef', + token: 'token.info-token', + }, + { + foreground: '#d19a66', + token: 'token.warn-token', + }, + { + foreground: '#f44747', + token: 'token.error-token', + }, + { + foreground: '#c678dd', + token: 'token.debug-token', + }, + { + foreground: '#c678dd', + token: 'punctuation.definition.template-expression.begin', + }, + { + foreground: '#c678dd', + token: 'punctuation.definition.template-expression.end', + }, + { + foreground: '#c678dd', + token: 'punctuation.section.embedded', + }, + { + foreground: '#abb2bf', + token: 'meta.template.expression', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.module', + }, + { + foreground: '#61afef', + token: 'support.type.type.flowtype', + }, + { + foreground: '#e5c07b', + token: 'support.type.primitive', + }, + { + foreground: '#e06c75', + token: 'meta.property.object', + }, + { + foreground: '#e06c75', + token: 'variable.parameter.function.js', + }, + { + foreground: '#98c379', + token: 'keyword.other.template.begin', + }, + { + foreground: '#98c379', + token: 'keyword.other.template.end', + }, + { + foreground: '#98c379', + token: 'keyword.other.substitution.begin', + }, + { + foreground: '#98c379', + token: 'keyword.other.substitution.end', + }, + { + foreground: '#56b6c2', + token: 'keyword.operator.assignment', + }, + { + foreground: '#e5c07b', + token: 'keyword.operator.assignment.go', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.arithmetic.go', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.address.go', + }, + { + foreground: '#e5c07b', + token: 'entity.name.package.go', + }, + { + foreground: '#56b6c2', + token: 'support.type.prelude.elm', + }, + { + foreground: '#d19a66', + token: 'support.constant.elm', + }, + { + foreground: '#c678dd', + token: 'punctuation.quasi.element', + }, + { + foreground: '#e06c75', + token: 'constant.character.entity', + }, + { + foreground: '#56b6c2', + token: 'entity.other.attribute-name.pseudo-element', + }, + { + foreground: '#56b6c2', + token: 'entity.other.attribute-name.pseudo-class', + }, + { + foreground: '#e5c07b', + token: 'entity.global.clojure', + }, + { + foreground: '#e06c75', + token: 'meta.symbol.clojure', + }, + { + foreground: '#56b6c2', + token: 'constant.keyword.clojure', + }, + { + foreground: '#e06c75', + token: 'meta.arguments.coffee', + }, + { + foreground: '#e06c75', + token: 'variable.parameter.function.coffee', + }, + { + foreground: '#98c379', + token: 'source.ini', + }, + { + foreground: '#e06c75', + token: 'meta.scope.prerequisites.makefile', + }, + { + foreground: '#e5c07b', + token: 'source.makefile', + }, + { + foreground: '#e5c07b', + token: 'storage.modifier.import.groovy', + }, + { + foreground: '#61afef', + token: 'meta.method.groovy', + }, + { + foreground: '#e06c75', + token: 'meta.definition.variable.name.groovy', + }, + { + foreground: '#98c379', + token: 'meta.definition.class.inherited.classes.groovy', + }, + { + foreground: '#e5c07b', + token: 'support.variable.semantic.hlsl', + }, + { + foreground: '#c678dd', + token: 'support.type.texture.hlsl', + }, + { + foreground: '#c678dd', + token: 'support.type.sampler.hlsl', + }, + { + foreground: '#c678dd', + token: 'support.type.object.hlsl', + }, + { + foreground: '#c678dd', + token: 'support.type.object.rw.hlsl', + }, + { + foreground: '#c678dd', + token: 'support.type.fx.hlsl', + }, + { + foreground: '#c678dd', + token: 'support.type.object.hlsl', + }, + { + foreground: '#e06c75', + token: 'text.variable', + }, + { + foreground: '#e06c75', + token: 'text.bracketed', + }, + { + foreground: '#e5c07b', + token: 'support.type.swift', + }, + { + foreground: '#e5c07b', + token: 'support.type.vb.asp', + }, + { + foreground: '#e5c07b', + token: 'entity.name.function.xi', + }, + { + foreground: '#56b6c2', + token: 'entity.name.class.xi', + }, + { + foreground: '#e06c75', + token: 'constant.character.character-class.regexp.xi', + }, + { + foreground: '#c678dd', + token: 'constant.regexp.xi', + }, + { + foreground: '#56b6c2', + token: 'keyword.control.xi', + }, + { + foreground: '#abb2bf', + token: 'invalid.xi', + }, + { + foreground: '#98c379', + token: 'beginning.punctuation.definition.quote.markdown.xi', + }, + { + foreground: '#7f848e', + token: 'beginning.punctuation.definition.list.markdown.xi', + }, + { + foreground: '#61afef', + token: 'constant.character.xi', + }, + { + foreground: '#61afef', + token: 'accent.xi', + }, + { + foreground: '#d19a66', + token: 'wikiword.xi', + }, + { + foreground: '#ffffff', + token: 'constant.other.color.rgb-value.xi', + }, + { + foreground: '#5c6370', + token: 'punctuation.definition.tag.xi', + }, + { + foreground: '#e5c07b', + token: 'entity.name.label.cs', + }, + { + foreground: '#e5c07b', + token: 'entity.name.scope-resolution.function.call', + }, + { + foreground: '#e5c07b', + token: 'entity.name.scope-resolution.function.definition', + }, + { + foreground: '#e06c75', + token: 'entity.name.label.cs', + }, + { + foreground: '#e06c75', + token: 'markup.heading.setext.1.markdown', + }, + { + foreground: '#e06c75', + token: 'markup.heading.setext.2.markdown', + }, + { + foreground: '#abb2bf', + token: ' meta.brace.square', + }, + { + foreground: '#7f848e', + fontStyle: 'italic', + token: 'comment', + }, + { + foreground: '#7f848e', + fontStyle: 'italic', + token: ' punctuation.definition.comment', + }, + { + foreground: '#5c6370', + token: 'markup.quote.markdown', + }, + { + foreground: '#abb2bf', + token: 'punctuation.definition.block.sequence.item.yaml', + }, + { + foreground: '#56b6c2', + token: 'constant.language.symbol.elixir', + }, + { + foreground: '#56b6c2', + token: 'constant.language.symbol.double-quoted.elixir', + }, + { + foreground: '#e5c07b', + token: 'entity.name.variable.parameter.cs', + }, + { + foreground: '#e06c75', + token: 'entity.name.variable.field.cs', + }, + { + foreground: '#e06c75', + token: 'markup.deleted', + }, + { + foreground: '#98c379', + token: 'markup.inserted', + }, + { + fontStyle: 'underline', + token: 'markup.underline', + }, + { + foreground: '#BE5046', + token: 'punctuation.section.embedded.begin.php', + }, + { + foreground: '#BE5046', + token: 'punctuation.section.embedded.end.php', + }, + { + foreground: '#abb2bf', + token: 'support.other.namespace.php', + }, + { + foreground: '#e06c75', + token: 'variable.parameter.function.latex', + }, + { + foreground: '#e5c07b', + token: 'variable.other.object', + }, + { + foreground: '#e06c75', + token: 'variable.other.constant.property', + }, + { + foreground: '#e5c07b', + token: 'entity.other.inherited-class', + }, + { + foreground: '#e06c75', + token: 'variable.other.readwrite.c', + }, + { + foreground: '#abb2bf', + token: 'entity.name.variable.parameter.php', + }, + { + foreground: '#abb2bf', + token: 'punctuation.separator.colon.php', + }, + { + foreground: '#abb2bf', + token: 'constant.other.php', + }, + { + foreground: '#c678dd', + token: 'constant.numeric.decimal.asm.x86_64', + }, + { + foreground: '#d19a66', + token: 'support.other.parenthesis.regexp', + }, + { + foreground: '#56b6c2', + token: 'constant.character.escape', + }, + { + foreground: '#e06c75', + token: 'string.regexp', + }, + { + foreground: '#98c379', + token: 'log.info', + }, + { + foreground: '#e5c07b', + token: 'log.warning', + }, + { + foreground: '#e06c75', + token: 'log.error', + }, + { + foreground: '#c678dd', + token: 'keyword.operator.expression.is', + }, + { + foreground: '#e06c75', + token: 'entity.name.label', + }, + { + fontStyle: 'italic', + token: 'entity.other.attribute-name.js', + }, + { + fontStyle: 'italic', + token: 'entity.other.attribute-name.ts', + }, + { + fontStyle: 'italic', + token: 'entity.other.attribute-name.jsx', + }, + { + fontStyle: 'italic', + token: 'entity.other.attribute-name.tsx', + }, + { + fontStyle: 'italic', + token: 'variable.parameter', + }, + { + fontStyle: 'italic', + token: 'variable.language.super', + }, + { + fontStyle: 'italic', + foreground: '#E5C07B', + token: 'pointsOfInterest.ts', + }, + { + fontStyle: 'italic', + foreground: '#E5C07B', + token: 'pointsOfInterest.coffee', + }, + { + fontStyle: 'italic', + token: 'comment.line.double-slash', + }, + { + fontStyle: 'italic', + token: 'comment.block.documentation', + }, + { + fontStyle: 'italic', + token: 'markup.italic.markdown', + }, + ], + encodedTokensColors: [], +}; diff --git a/gui/frontend/src/components/editor/code_editor.tsx b/gui/frontend/src/components/editor/code_editor.tsx new file mode 100644 index 0000000..0a3b64c --- /dev/null +++ b/gui/frontend/src/components/editor/code_editor.tsx @@ -0,0 +1,80 @@ +// Copyright (c) 2023 Luma +// SPDX-License-Identifier: MIT or Apache-2.0 +// +// issue: https://github.com/suren-atoyan/monaco-react/issues/136#issuecomment-731420078 +'use client'; +import Editor, { type OnMount } from '@monaco-editor/react'; +import { type ComponentProps, memo, useCallback, useRef } from 'react'; + +import { atomOneDarkPro } from './atom_onedark_pro'; + +import type monaco from 'monaco-editor/esm/vs/editor/editor.api'; +import type { VimMode } from 'monaco-vim'; + +const loadVimKeyBindings: OnMount = (editor, monaco) => { + // setup key bindings before monaco-vim setup + + // setup key bindings + editor.addAction({ + // an unique identifier of the contributed action + id: 'some-unique-id', + // a label of the action that will be presented to the user + label: 'Some label!', + keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS], + + // the method that will be executed when the action is triggered. + run: (editor) => { + alert(`we wanna save something => ${editor.getValue()}`); + }, + }); + + // setup monaco-vim + // @ts-ignore + window.require.config({ + paths: { + 'monaco-vim': 'https://unpkg.com/monaco-vim/dist/monaco-vim', + }, + }); + + // @ts-ignore + window.require(['monaco-vim'], (monacoVim: VimMode) => { + const statusNode = document.querySelector('#status-node'); + monacoVim.initVimMode(editor, statusNode); + }); +}; + +export type CodeEditorProps = ComponentProps & { + readonly vimMode?: boolean; +}; +function CodeEditorInternal({ vimMode = false, onMount, ...params }: CodeEditorProps) { + const editorRef = useRef(null); + + const handleDidMount: OnMount = useCallback( + (editor, monaco) => { + editorRef.current = editor; + if (vimMode) { + loadVimKeyBindings(editor, monaco); + } + + editor.updateOptions({ + theme: 'onedark', + }); + onMount?.(editor, monaco); + }, + [onMount, vimMode], + ); + + return ( + { + monaco.editor.defineTheme('onedark', atomOneDarkPro); + }} + onMount={handleDidMount} + /> + ); +} + +export const CodeEditor = memo(CodeEditorInternal); diff --git a/gui/frontend/src/components/editor/editor.tsx b/gui/frontend/src/components/editor/editor.tsx new file mode 100644 index 0000000..c8616df --- /dev/null +++ b/gui/frontend/src/components/editor/editor.tsx @@ -0,0 +1,118 @@ +import { TabContext, TabList } from '@mui/lab'; +import { Box, InputLabel, Tab } from '@mui/material'; + +import { CodeEditor } from '@/components/editor/code_editor'; +import { useInjectScript, useStorageState, useTranslation } from '@/hooks'; +import { selectEditorMode } from '@/utils/selector'; +import type { EditorMode } from '@/utils/selector'; + +import type { SyntheticEvent } from 'react'; + +export type EditorProps = { + editorMode: string; + setPreset: (script: string) => void; + setStyle: (style: string) => void; + style: string; +}; + +export const Editor = ({ editorMode, setPreset, setStyle, style }: EditorProps) => { + const [script, handleScriptChange] = useInjectScript(); + const { t } = useTranslation(); + + const [value, setValue] = useStorageState('editor-tab-select', 'javascript'); + const handleTabChange = (_event: SyntheticEvent, newValue: string) => { + setValue(newValue); + }; + + const editorValues: EditorValues = { + css: { + label: t('custom-css-label'), + defaultValue: style, + language: 'css', + onChange: (newValue) => { + const value = newValue ?? ''; + setStyle(value); + localStorage.setItem('customCSS', value); + setPreset('0'); + }, + }, + + javascript: { + label: t('custom-js-label'), + defaultValue: script, + language: 'javascript', + onChange: handleScriptChange, + }, + }; + + const editorValue = (() => { + if (value === 'javascript') { + return editorValues.javascript; + } + return editorValues.css; + })(); + + return ( + + + + + + + + + + + ); +}; + +type EditorInnerProps = { + label: string; + defaultValue: string; + language: string; + onChange: (newValue: string | undefined) => void; + editorMode: EditorMode; +}; +type InitEditor = Omit; + +type EditorValues = { + css: InitEditor; + javascript: InitEditor; +}; + +const EditorInner = ({ label, defaultValue, language, onChange, editorMode }: EditorInnerProps) => { + return ( + <> + + {label} + + + + + ); +}; diff --git a/gui/frontend/src/components/editor/index.ts b/gui/frontend/src/components/editor/index.ts new file mode 100644 index 0000000..cad1444 --- /dev/null +++ b/gui/frontend/src/components/editor/index.ts @@ -0,0 +1,2 @@ +// @index('./*', f => `export * from '${f.path}'`) +export * from './editor'; diff --git a/gui/frontend/src/components/lists/editor_list.tsx b/gui/frontend/src/components/lists/editor_list.tsx new file mode 100644 index 0000000..446a146 --- /dev/null +++ b/gui/frontend/src/components/lists/editor_list.tsx @@ -0,0 +1,43 @@ +import { FormControl, InputLabel } from '@mui/material'; +import MenuItem from '@mui/material/MenuItem'; +import Select, { type SelectChangeEvent } from '@mui/material/Select'; +import { useCallback } from 'react'; + +import { useTranslation } from '@/hooks'; +import { selectEditorMode } from '@/utils/selector'; +import type { EditorMode } from '@/utils/selector'; + +export type SelectEditorProps = { + setEditorMode: (value: EditorMode) => void; + editorMode: EditorMode; +}; + +export const SelectEditorMode = ({ editorMode, setEditorMode }: SelectEditorProps) => { + const { t } = useTranslation(); + + const handleChange = useCallback( + (e: SelectChangeEvent) => { + const presetEditor = selectEditorMode(e.target.value); + setEditorMode(presetEditor); + window.location.reload(); + }, + [setEditorMode], + ); + + return ( + + {t('editor-mode-list-label')} + + + ); +}; diff --git a/gui/frontend/src/components/lists/index.ts b/gui/frontend/src/components/lists/index.ts new file mode 100644 index 0000000..17f269d --- /dev/null +++ b/gui/frontend/src/components/lists/index.ts @@ -0,0 +1,6 @@ +// @index('./*', f => `export * from '${f.path}'`) +export * from './editor_list'; +export * from './notice_position_list'; +export * from './log_level_list'; +export * from './style_list'; +export * from './translation_list'; diff --git a/gui/frontend/src/components/lists/log_level_list.tsx b/gui/frontend/src/components/lists/log_level_list.tsx new file mode 100644 index 0000000..27621e6 --- /dev/null +++ b/gui/frontend/src/components/lists/log_level_list.tsx @@ -0,0 +1,55 @@ +import { FormControl, InputLabel, MenuItem, Select, type SelectChangeEvent, Tooltip } from '@mui/material'; +import { useCallback, useState } from 'react'; + +import { type LogLevel, changeLogLevel } from '@/backend_api'; +import { notify } from '@/components/notifications'; +import { useTranslation } from '@/hooks'; +import { selectLogLevel } from '@/utils/selector'; + +export const LogLevelList = () => { + const { t } = useTranslation(); + const [logLevel, setLogLevel] = useState(selectLogLevel(localStorage.getItem('log_level'))); + + const handleChange = useCallback(async (event: SelectChangeEvent) => { + localStorage.setItem('log_level', event.target.value); + try { + const newLogLevel = selectLogLevel(event.target.value); + await changeLogLevel(newLogLevel); + setLogLevel(newLogLevel); + } catch (err) { + notify.error(`${err}`); + } + }, []); + + return ( + +

{t('log-level-list-tooltip')}

+

{t('log-level-list-tooltip2')}

+

{t('log-level-list-tooltip3')}

+

{t('log-level-list-tooltip4')}

+ + } + > + + {t('log-level-list-label')} + + +
+ ); +}; diff --git a/gui/frontend/src/components/lists/notice_position_list.tsx b/gui/frontend/src/components/lists/notice_position_list.tsx new file mode 100644 index 0000000..fb67a0f --- /dev/null +++ b/gui/frontend/src/components/lists/notice_position_list.tsx @@ -0,0 +1,85 @@ +import { FormControl, InputLabel, TextField } from '@mui/material'; +import MenuItem from '@mui/material/MenuItem'; +import Select, { type SelectChangeEvent } from '@mui/material/Select'; +import { type ChangeEventHandler, useCallback, useState } from 'react'; + +import { getSnackbarSettings } from '@/components/notifications'; +import { useTranslation } from '@/hooks'; +import { localStorageManager } from '@/utils/local_storage_manager'; + +import { LogLevelList } from './log_level_list'; + +import type { SnackbarOrigin } from 'notistack'; + +export const NoticeSettingsList = () => { + const { t } = useTranslation(); + // NOTE: Get settings here at once to avoid cache access. + const { position, maxSnack: initMaxSnack } = getSnackbarSettings(); + const [pos, setPos] = useState(position); + const [maxSnack, setMaxSnack] = useState(initMaxSnack); + + const handlePosChange = useCallback((e: SelectChangeEvent) => { + const [vertical, horizontal] = e.target.value.split('_'); + + const newPosition: SnackbarOrigin = { + vertical: vertical === 'bottom' || vertical === 'top' ? vertical : 'bottom', + horizontal: horizontal === 'center' || horizontal === 'right' || horizontal === 'left' ? horizontal : 'right', + }; + + localStorageManager.set( + 'snackbar-position', + JSON.stringify({ + vertical: vertical, + horizontal: horizontal, + }), + ); + setPos(newPosition); + }, []); + + const handleMaxSnackChange: ChangeEventHandler = (e) => { + const newValue = Number(e.target.value); + const newMaxSnack = Number.isNaN(newValue) ? 3 : newValue; + if (Number.isNaN(newValue)) { + localStorageManager.set('snackbar-limit', '1'); + } else { + localStorageManager.set('snackbar-limit', `${newMaxSnack}`); + } + setMaxSnack(newMaxSnack); + }; + + return ( + <> + + {t('notice-position-list-label')} + + + + + + ); +}; diff --git a/gui/frontend/src/components/lists/style_list.tsx b/gui/frontend/src/components/lists/style_list.tsx new file mode 100644 index 0000000..d8aff60 --- /dev/null +++ b/gui/frontend/src/components/lists/style_list.tsx @@ -0,0 +1,56 @@ +import { FormControl, InputLabel, Tooltip } from '@mui/material'; +import MenuItem from '@mui/material/MenuItem'; +import Select, { type SelectChangeEvent } from '@mui/material/Select'; + +import { useTranslation } from '@/hooks'; +import { presetStyles, selectPreset } from '@/utils/styles'; + +export type StyleListProps = { + setStyle: (value: string) => void; + setPreset: (value: string) => void; + preset: string; +}; + +export const StyleList = ({ preset, setPreset, setStyle }: StyleListProps) => { + const { t } = useTranslation(); + + const handleChange = (e: SelectChangeEvent) => { + const presetNumber = selectPreset(e.target.value); + setPreset(presetNumber); + if (presetNumber === '0') { + setStyle(localStorage.getItem('customCSS') ?? ''); + return; + } + setStyle(presetStyles[presetNumber]); + }; + + return ( + +

{t('css-preset-list-tooltip')}

+

{t('css-preset-list-tooltip2')}

+ + } + > + + {t('css-preset-list-label')} + + +
+ ); +}; diff --git a/gui/frontend/src/components/lists/translation_list.tsx b/gui/frontend/src/components/lists/translation_list.tsx new file mode 100644 index 0000000..3057f7e --- /dev/null +++ b/gui/frontend/src/components/lists/translation_list.tsx @@ -0,0 +1,37 @@ +import { FormControl, InputLabel } from '@mui/material'; +import MenuItem from '@mui/material/MenuItem'; +import Select, { type SelectChangeEvent } from '@mui/material/Select'; +import { changeLanguage } from 'i18next'; + +import { useStorageState, useTranslation } from '@/hooks'; + +export const TranslationList = () => { + const [lang, setLang] = useStorageState('locale', 'auto'); + const { t } = useTranslation(); + + const handleChange = (e: SelectChangeEvent) => { + const newLocale = e.target.value; + setLang(newLocale); + changeLanguage(newLocale === 'auto' ? window.navigator.language : newLocale); + }; + + const locale = 'Locale'; + return ( + + {t('lang-preset-label')} + + + ); +}; diff --git a/gui/frontend/src/components/navigation.tsx b/gui/frontend/src/components/navigation.tsx new file mode 100644 index 0000000..b8bc235 --- /dev/null +++ b/gui/frontend/src/components/navigation.tsx @@ -0,0 +1,48 @@ +'use client'; + +import SettingsIcon from '@mui/icons-material/Settings'; +import TransformIcon from '@mui/icons-material/Transform'; +import BottomNavigation from '@mui/material/BottomNavigation'; +import BottomNavigationAction from '@mui/material/BottomNavigationAction'; +import { styled } from '@mui/material/styles'; +import { usePathname, useRouter } from 'next/navigation'; +import { useEffect, useState } from 'react'; + +const Nav = styled(BottomNavigation)(() => { + return { + position: 'fixed', + bottom: 0, + width: '100%', + zIndex: '100', // Because Ace-editor uses z-index and without it, it would be covered. + '.Mui-selected': { + color: '#99e4ee', + }, + }; +}); + +export default function MenuNavigation() { + const router = useRouter(); + const pathname = usePathname(); + const [value, setValue] = useState(0); + + useEffect(() => { + if (pathname === '/') { + setValue(0); + } else if (pathname === '/settings') { + setValue(1); + } + }, [pathname]); + + return ( + + ); +} diff --git a/gui/frontend/src/components/notifications/circular_with_label.tsx b/gui/frontend/src/components/notifications/circular_with_label.tsx new file mode 100644 index 0000000..fe0efc2 --- /dev/null +++ b/gui/frontend/src/components/notifications/circular_with_label.tsx @@ -0,0 +1,32 @@ +import Box from '@mui/material/Box'; +import CircularProgress, { type CircularProgressProps } from '@mui/material/CircularProgress'; +import Typography from '@mui/material/Typography'; + +/** + * https://mui.com/material-ui/react-progress/#circular-with-label + */ +export function CircularProgressWithLabel(props: CircularProgressProps & { progColor?: string; value: number }) { + const style = { color: props.progColor }; + + return ( + + + + {`${Math.round( + props.value, + )}%`} + + + ); +} diff --git a/gui/frontend/src/components/notifications/dialog.tsx b/gui/frontend/src/components/notifications/dialog.tsx new file mode 100644 index 0000000..9820bcb --- /dev/null +++ b/gui/frontend/src/components/notifications/dialog.tsx @@ -0,0 +1,147 @@ +import CloseIcon from '@mui/icons-material/Close'; +import { Button, Checkbox, Dialog, Divider, FormControlLabel } from '@mui/material'; +import DialogActions from '@mui/material/DialogActions'; +import DialogContent from '@mui/material/DialogContent'; +import DialogTitle from '@mui/material/DialogTitle'; +import IconButton from '@mui/material/IconButton'; +import List from '@mui/material/List'; +import ListItem from '@mui/material/ListItem'; +import ListItemButton from '@mui/material/ListItemButton'; +import ListItemIcon from '@mui/material/ListItemIcon'; +import ListItemText from '@mui/material/ListItemText'; +import { type Dispatch, type ReactNode, type SetStateAction, useState } from 'react'; + +import { useTranslation } from '@/hooks'; +import { type CacheKey, type LocalCache, pubCacheKeys } from '@/utils/local_storage_manager'; + +export type DialogClickHandler = (checkedKeys: CacheKey[]) => void; +export type LocalStorageDialogProps = { + buttonName: string; + cacheItems: LocalCache; + /** Event when a button in the dialog is clicked */ + inDialogClick: DialogClickHandler; + open: boolean; + setOpen: Dispatch>; + title: ReactNode; +}; + +export const LocalStorageDialog = ({ + buttonName, + cacheItems, + inDialogClick, + open, + setOpen, + title, +}: Readonly) => { + const handleClose = () => setOpen(false); + + const { t } = useTranslation(); + const [isAllChecked, setIsAllChecked] = useState(false); + const [isPubAllChecked, setIsPubAllChecked] = useState(false); + const [checked, setChecked] = useState([]); + + const handleToggle = (selectedKey: CacheKey) => () => { + setChecked((prev) => { + // Remove + if (prev.includes(selectedKey)) { + return prev.filter((key) => key !== selectedKey); + } + // Add + return [...prev, selectedKey]; + }); + setIsAllChecked(false); + setIsPubAllChecked(false); + }; + + const handleAllCheck = () => { + setIsPubAllChecked(false); + setIsAllChecked((prev) => { + const newIsAll = !prev; + if (newIsAll) { + setChecked(Object.keys(cacheItems) as CacheKey[]); + } else { + setChecked([]); + } + return newIsAll; + }); + }; + + const handlePubAllCheck = () => { + setIsAllChecked(false); + setIsPubAllChecked((prev) => { + const newIsPub = !prev; + if (newIsPub) { + // Safety: `setState` copies arguments without changing them on its own + setChecked(pubCacheKeys as unknown as CacheKey[]); + } else { + setChecked([]); + } + return newIsPub; + }); + }; + + return ( + + {title} + theme.palette.grey[500], + }} + > + + + + + } + label={t('backup-dialog-all-checked-label')} + /> + } + label={t('backup-dialog-pub-checked-label')} + /> + + + + + {Object.keys(cacheItems).map((key_) => { + const key = key_ as CacheKey; + const value = cacheItems[key]; + const labelId = `checkbox-list-label-${key}`; + const oneObject: LocalCache = {}; + oneObject[key] = value; + + return ( + + + + + + + + + + ); + })} + + + + + + + + ); +}; diff --git a/gui/frontend/src/components/notifications/index.ts b/gui/frontend/src/components/notifications/index.ts new file mode 100644 index 0000000..009ab20 --- /dev/null +++ b/gui/frontend/src/components/notifications/index.ts @@ -0,0 +1,5 @@ +// @index('./*', f => `export * from '${f.path}'`) +export * from './circular_with_label'; +export * from './dialog'; +export * from './progress_bar'; +export * from './notify'; diff --git a/gui/frontend/src/components/notifications/notify.tsx b/gui/frontend/src/components/notifications/notify.tsx new file mode 100644 index 0000000..35e329e --- /dev/null +++ b/gui/frontend/src/components/notifications/notify.tsx @@ -0,0 +1,57 @@ +import { enqueueSnackbar } from 'notistack'; + +import { localStorageManager } from '@/utils/local_storage_manager'; + +import type { OptionsObject, SnackbarMessage, SnackbarOrigin } from 'notistack'; + +// Notify design is defined in provider +/** + * Wrapper to simplify refactoring of libraries such as snackbar and toast + */ +export const notify = { + info(message: SnackbarMessage, options?: OptionsObject<'info'>) { + enqueueSnackbar(message, { variant: 'info', ...options }); + }, + success(message: SnackbarMessage, options?: OptionsObject<'success'>) { + enqueueSnackbar(message, { variant: 'success', ...options }); + }, + warn(message: SnackbarMessage, options?: OptionsObject<'warning'>) { + enqueueSnackbar(message, { variant: 'warning', ...options }); + }, + error(message: SnackbarMessage, options?: OptionsObject<'error'>) { + enqueueSnackbar(message, { variant: 'error', ...options }); + }, +}; + +type SnackbarSettings = { + position: SnackbarOrigin; + maxSnack: number; +}; + +export const defaultSnackbarSettings: SnackbarSettings = { + position: { + horizontal: 'right', + vertical: 'bottom', + }, + maxSnack: 3, +} as const; + +export const getSnackbarSettings = (): SnackbarSettings => { + let position: Partial = {}; + try { + position = JSON.parse(localStorageManager.get('snackbar-position') ?? '{}'); + } catch (error) { + console.error(error); + } + + const maxSnack = Number(localStorageManager.get('snackbar-limit')); + const { position: defaultPos, maxSnack: defaultMaxSnack } = defaultSnackbarSettings; + + return { + position: { + horizontal: position?.horizontal ?? defaultPos.horizontal, + vertical: position?.vertical ?? defaultPos.vertical, + }, + maxSnack: Number.isNaN(maxSnack) ? defaultMaxSnack : maxSnack, + }; +}; diff --git a/gui/frontend/src/components/notifications/progress_bar.tsx b/gui/frontend/src/components/notifications/progress_bar.tsx new file mode 100644 index 0000000..48642c0 --- /dev/null +++ b/gui/frontend/src/components/notifications/progress_bar.tsx @@ -0,0 +1,28 @@ +import Box from '@mui/material/Box'; +import LinearProgress, { type LinearProgressProps } from '@mui/material/LinearProgress'; +import Typography from '@mui/material/Typography'; + +function LinearProgressWithLabel(props: LinearProgressProps & { value: number }) { + return ( + + + + + + {`${Math.round(props.value)}%`} + + + ); +} + +type Props = { + progress: number; +}; + +export function LinearWithValueLabel({ progress }: Readonly) { + return ( + + + + ); +} diff --git a/gui/frontend/src/components/pages/home.tsx b/gui/frontend/src/components/pages/home.tsx new file mode 100644 index 0000000..d3e5528 --- /dev/null +++ b/gui/frontend/src/components/pages/home.tsx @@ -0,0 +1,30 @@ +'use client'; + +import { Box, Skeleton } from '@mui/material'; +import { Suspense } from 'react'; + +import { DeviceCards } from '@/components/bt_devices'; +import { useDynStyle, useInjectScript, useLocale } from '@/hooks'; + +export default function Home() { + useDynStyle(); + useInjectScript(); + useLocale(); + + return ( + + }> + + + + ); +} diff --git a/gui/frontend/src/components/pages/loading.tsx b/gui/frontend/src/components/pages/loading.tsx new file mode 100644 index 0000000..fa28f32 --- /dev/null +++ b/gui/frontend/src/components/pages/loading.tsx @@ -0,0 +1,20 @@ +import { Box, CircularProgress } from '@mui/material'; + +/** This is executed on the server side, so the client's API cannot be used + * (because it is an alternative page for preparing the Client). + */ +export default function Loading() { + return ( + +

Loading...

+ +
+ ); +} diff --git a/gui/frontend/src/components/pages/settings.tsx b/gui/frontend/src/components/pages/settings.tsx new file mode 100644 index 0000000..e6fc9e1 --- /dev/null +++ b/gui/frontend/src/components/pages/settings.tsx @@ -0,0 +1,129 @@ +'use client'; +import TabContext from '@mui/lab/TabContext'; +import TabList from '@mui/lab/TabList'; +import TabPanel from '@mui/lab/TabPanel'; +import { Box, Button, Grid } from '@mui/material'; +import Tab from '@mui/material/Tab'; + +import { start } from '@/backend_api'; +import { ExecJsBtn, ExportBackupButton, ImportBackupButton, ImportLangButton } from '@/components/buttons'; +import { Editor, type EditorProps } from '@/components/editor'; +import { NoticeSettingsList, SelectEditorMode, StyleList, TranslationList } from '@/components/lists'; +import type { SelectEditorProps, StyleListProps } from '@/components/lists'; +import { useDynStyle, useLocale, useStorageState, useTranslation } from '@/hooks'; +import { selectEditorMode } from '@/utils/selector'; +import type { EditorMode } from '@/utils/selector'; + +import packageJson from '@/../../package.json'; + +import type { SyntheticEvent } from 'react'; + +export default function Settings() { + useLocale(); + const [editorMode, setEditorMode] = useStorageState('editorMode', 'default'); + const [preset, setPreset] = useStorageState('presetNumber', '0'); + const [style, setStyle] = useDynStyle(); + const validEditorMode = selectEditorMode(editorMode); + + const setEditorKeyMode = (editorMode: EditorMode) => setEditorMode(editorMode); + return ( + + + + + + + + + + + + + ); +} + +type TabsProps = StyleListProps & SelectEditorProps & EditorProps; +const Tabs = ({ editorMode, setEditorMode, preset, setPreset, setStyle }: TabsProps) => { + const [value, setValue] = useStorageState('settings-tab-select', 'editor'); + const { t } = useTranslation(); + + const handleChange = (_event: SyntheticEvent, newValue: string) => { + setValue(newValue); + }; + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +const Help = () => { + const handleClick = () => start(packageJson.homepage); + return ( + +
Version: {packageJson.version}
+
+ Source:{' '} + +
+
+ ); +}; diff --git a/gui/frontend/src/components/providers/snackbar.tsx b/gui/frontend/src/components/providers/snackbar.tsx new file mode 100644 index 0000000..7b58073 --- /dev/null +++ b/gui/frontend/src/components/providers/snackbar.tsx @@ -0,0 +1,86 @@ +'use client'; + +import CloseIcon from '@mui/icons-material/Close'; +import { Alert, AlertTitle, IconButton } from '@mui/material'; +import { + type CustomContentProps, + type SnackbarKey, + SnackbarProvider as SnackbarProviderInner, + closeSnackbar, +} from 'notistack'; +import { forwardRef, memo } from 'react'; + +import { getSnackbarSettings } from '@/components/notifications'; + +/** + * ref + * - https://github.com/iamhosseindhv/notistack/issues/477#issuecomment-1885706867 + * @export + */ +export default function SnackBarProvider() { + const settings = getSnackbarSettings(); + + return ( + + ); +} + +/** It exists to realize the deletion of the history of the passage at any timing by Click. */ +const action = (id: SnackbarKey) => ( + closeSnackbar(id)} size='small'> + + +); + +const ThemeResponsiveSnackbarComp = forwardRef((props, forwardedRef) => { + const { + id, + message, + action: componentOrFnAction, + variant: notistackVariant, + hideIconVariant, + style, + className, + } = props; + + const severity = notistackVariant === 'default' ? 'info' : notistackVariant; + const action = typeof componentOrFnAction === 'function' ? componentOrFnAction(id) : componentOrFnAction; + + return ( + ({ + alignItems: 'center', + backgroundColor: '#1a1919e1', + borderRadius: '8px', + boxShadow: theme.shadows[8], + display: 'flex', + maxWidth: '35vw', + willChange: 'transform', + })} + variant='outlined' + > + {severity.toUpperCase()} + {message} + + ); +}); +ThemeResponsiveSnackbarComp.displayName = 'ThemeResponsiveSnackbarCompRef'; +const ThemeResponsiveSnackbar = memo(ThemeResponsiveSnackbarComp); diff --git a/gui/frontend/src/hooks/dyn_style.ts b/gui/frontend/src/hooks/dyn_style.ts new file mode 100644 index 0000000..064222a --- /dev/null +++ b/gui/frontend/src/hooks/dyn_style.ts @@ -0,0 +1,77 @@ +import { useCallback, useEffect, useInsertionEffect, useState } from 'react'; + +import { notify } from '@/components/notifications'; +import { localStorageManager } from '@/utils/local_storage_manager'; +import { presetStyles, selectPreset } from '@/utils/styles'; + +const getStyle = () => { + const presetNumber = selectPreset(localStorageManager.get('presetNumber')); + if (presetNumber === '0') { + return localStorageManager.get('customCSS') ?? ''; + } + return presetStyles[presetNumber]; +}; + +/** + * Inject CSS dynamically on the client side. + * # NOTE + * Frequent style recalculation is inevitable, + * but this hook can solve the delay problem caused by style injection lifecycle discrepancies. + * - See: [useInsertionEffect](https://react.dev/reference/react/useInsertionEffect) + */ +export function useDynStyle(initialState = getStyle()) { + const [style, setStyle] = useState(initialState); + + useInsertionEffect(() => { + const styleElement = document.createElement('style'); + styleElement.innerHTML = style; + document.head.appendChild(styleElement); + return () => { + document.head.removeChild(styleElement); + }; + }, [style]); + + return [style, setStyle] as const; +} + +const initScript = () => { + return localStorageManager.get('customJS') ?? ''; +}; +/** + * Inject JavaScript + */ +export function useInjectScript(initialState = initScript()) { + const [script, setScript] = useState(initialState); + const [pathname, setPathname] = useState(null); + + const handleScriptChange = useCallback((newValue: string | undefined) => { + setScript(newValue ?? ''); + localStorage.setItem('customJS', newValue ?? ''); + }, []); + + useEffect(() => { + const scriptElement = document.createElement('script'); + if (localStorage.getItem('runScript') === 'true') { + scriptElement.innerHTML = script; + } + scriptElement.id = 'custom-script'; + + if (pathname !== window.location.pathname) { + try { + if (!document.getElementById('custom-script')) { + document.body.appendChild(scriptElement); + } + } catch (e) { + notify.error(`${e}`); + } + setPathname(window.location.pathname); + } + return () => { + if (document.getElementById('custom-script')) { + document.body.removeChild(scriptElement); + } + }; + }, [script, pathname]); + + return [script, handleScriptChange] as const; +} diff --git a/gui/frontend/src/hooks/index.test.ts b/gui/frontend/src/hooks/index.test.ts new file mode 100644 index 0000000..e70074f --- /dev/null +++ b/gui/frontend/src/hooks/index.test.ts @@ -0,0 +1,22 @@ +import { act, cleanup, renderHook } from '@testing-library/react'; + +import { useStorageState } from '@/hooks'; +import type { CacheKey } from '@/utils/local_storage_manager'; + +afterEach(() => { + cleanup(); +}); + +describe('useStorageState hook', () => { + it('should set and get value from state', () => { + const storageKey: CacheKey = 'cached-dst'; + const initialValue = 'initialValue'; + + const { result } = renderHook(() => useStorageState(storageKey, initialValue)); + expect(result.current[0]).toBe(initialValue); + + const newValue = 'newValue'; + act(() => result.current[1](newValue)); + expect(result.current[0]).toBe(newValue); + }); +}); diff --git a/gui/frontend/src/hooks/index.ts b/gui/frontend/src/hooks/index.ts new file mode 100644 index 0000000..d263672 --- /dev/null +++ b/gui/frontend/src/hooks/index.ts @@ -0,0 +1,5 @@ +// @index('./*', f => `export * from '${f.path}'`) +'use client'; +export * from './dyn_style'; +export * from './storage_state'; +export * from './useLocale'; diff --git a/gui/frontend/src/hooks/storage_state.ts b/gui/frontend/src/hooks/storage_state.ts new file mode 100644 index 0000000..3afa6c5 --- /dev/null +++ b/gui/frontend/src/hooks/storage_state.ts @@ -0,0 +1,27 @@ +import { useCallback, useState } from 'react'; + +import type { CacheKey } from '@/utils/local_storage_manager'; + +type CacheKeyAll = CacheKey | 'runScript'; +const getCacheStr = (cacheKey: CacheKeyAll, initialState: string) => localStorage.getItem(cacheKey) ?? initialState; + +/** + * useState with localStorage + * @param keyName + * @param fallbackState - if localStorage.getItem is returned null, then use. + */ +export function useStorageState(keyName: CacheKeyAll, fallbackState = '') { + const [value, setValue] = useState(getCacheStr(keyName, fallbackState)); + + const setState = useCallback( + (newValue: string) => { + setValue(newValue); + if (value !== newValue) { + localStorage.setItem(keyName, newValue); + } + }, + [keyName, value], + ); + + return [value, setState] as const; +} diff --git a/gui/frontend/src/hooks/useLocale.ts b/gui/frontend/src/hooks/useLocale.ts new file mode 100644 index 0000000..f49460f --- /dev/null +++ b/gui/frontend/src/hooks/useLocale.ts @@ -0,0 +1,34 @@ +import { type FlatNamespace, type KeyPrefix, changeLanguage } from 'i18next'; +import { useEffect } from 'react'; +import { type FallbackNs, type UseTranslationOptions, useTranslation as useTrans } from 'react-i18next'; + +import { localStorageManager } from '@/utils/local_storage_manager'; +import type { I18nKeys } from '@/utils/translation'; + +/** + * Change language + */ +export function useLocale() { + useEffect(() => { + const locale = localStorageManager.get('locale') ?? window.navigator.language; + changeLanguage(locale === 'auto' ? window.navigator.language : locale); + }, []); +} + +type $Tuple = readonly [T?, ...T[]]; +type UseTranslation = < + Ns extends FlatNamespace | $Tuple | undefined = undefined, + // biome-ignore lint/style/useNamingConvention: + KPrefix extends KeyPrefix> = undefined, +>( + ns?: Ns, + options?: UseTranslationOptions, +) => { t: (key: I18nKeys) => string }; + +/** + * useTranslation(react-i18next) Wrapper for type completion of translation keys. + */ +export const useTranslation: UseTranslation = (ns, options) => { + const trans = useTrans(ns, options).t; + return { t: (key) => trans(key as unknown as string) }; +}; diff --git a/gui/frontend/src/utils/local_storage_manager.ts b/gui/frontend/src/utils/local_storage_manager.ts new file mode 100644 index 0000000..dfbb61c --- /dev/null +++ b/gui/frontend/src/utils/local_storage_manager.ts @@ -0,0 +1,74 @@ +const formPubCacheKeys = ['logLevel'] as const; +const formPrivateCacheKeys = [] as const; + +export const pubCacheKeys = [ + ...formPubCacheKeys, + 'custom-translation-dict', + 'customCSS', + 'customJS', + 'editor-tab-select', + 'editorMode', + 'locale', + 'presetNumber', + 'settings-tab-select', + 'snackbar-limit', + 'snackbar-position', +] as const; +export const privateCacheKeys = [ + ...formPrivateCacheKeys, + 'import-backup-path', + 'import-settings-path', + 'export-settings-path', + 'lang-file-path', +] as const; +export const cacheKeys = [...pubCacheKeys, ...privateCacheKeys]; + +export type CacheKey = (typeof cacheKeys)[number]; +export type LocalCache = Partial<{ [Key in CacheKey]: string }>; + +/** Wrapper for type completion of keys to be cached */ +export const localStorageManager = { + /** + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Storage/getItem) + * @returns + * - Value associated with the given key + * - `null` if the given key does not exist. + */ + get(key: CacheKey) { + return localStorage.getItem(key); + }, + getFromKeys(keys: CacheKey[]) { + const res: LocalCache = {}; + + for (const key of keys) { + const value = localStorageManager.get(key); + if (value) { + res[key] = value; + } + } + + return res; + }, + /** Get all cache */ + getAll() { + const res: LocalCache = {}; + + for (const key of cacheKeys) { + const val = localStorageManager.get(key); + if (val) { + res[key] = val; + } + } + + return res; + }, + /** Set cache */ + set(key: CacheKey, value: string) { + return localStorage.setItem(key, value); + }, + removeFromKeys(keys: CacheKey[]) { + for (const key of keys) { + localStorage.removeItem(key); + } + }, +}; diff --git a/gui/frontend/src/utils/path.test.ts b/gui/frontend/src/utils/path.test.ts new file mode 100644 index 0000000..4c4eda0 --- /dev/null +++ b/gui/frontend/src/utils/path.test.ts @@ -0,0 +1,25 @@ +import { getParent } from '@/utils/path'; + +describe('get_parent function', () => { + test('returns the same path if it ends with /', () => { + const path = '/example/path/'; + expect(getParent(path)).toBe(path); + }); + + test('returns the same path if it ends with \\', () => { + const path = '\\example\\path\\'; + expect(getParent(path)).toBe(path); + }); + + test('deletes tailing part until / if path does not end with /', () => { + const path = '/example/path/file.txt'; + const expected = '/example/path'; + expect(getParent(path)).toBe(expected); + }); + + test('deletes tailing part until \\ if path does not end with \\', () => { + const path = '\\example\\path\\file.txt'; + const expected = '\\example\\path'; + expect(getParent(path)).toBe(expected); + }); +}); diff --git a/gui/frontend/src/utils/path.ts b/gui/frontend/src/utils/path.ts new file mode 100644 index 0000000..7c58524 --- /dev/null +++ b/gui/frontend/src/utils/path.ts @@ -0,0 +1,12 @@ +/** + * Return parent path from argument path. + * @param path + * @returns + */ +export function getParent(path: string): string { + if (path.endsWith('/') || path.endsWith('\\')) { + return path; + } + // Deletes tailing part until / if path does not end with / or \ + return path.replace(/[/\\][^/\\]*$/, ''); +} diff --git a/gui/frontend/src/utils/selector.ts b/gui/frontend/src/utils/selector.ts new file mode 100644 index 0000000..9efbe79 --- /dev/null +++ b/gui/frontend/src/utils/selector.ts @@ -0,0 +1,24 @@ +import type { LogLevel } from '@/backend_api'; + +export type EditorMode = 'default' | 'vim'; +/** 'default' if null or undefined */ +export function selectEditorMode(select?: string | null): EditorMode { + if (select === 'vim') { + return select; + } + return 'default'; +} + +/** 'error' if null or undefined */ +export function selectLogLevel(logLevel?: string | null): LogLevel { + switch (logLevel) { + case 'trace': + case 'debug': + case 'info': + case 'warn': + case 'error': + return logLevel; + default: + return 'error'; + } +} diff --git a/gui/frontend/src/utils/styles.ts b/gui/frontend/src/utils/styles.ts new file mode 100644 index 0000000..15a68bc --- /dev/null +++ b/gui/frontend/src/utils/styles.ts @@ -0,0 +1,155 @@ +/** + * Creates a CSS preset. + * + * @template T - The type of the CSS string. + * @param {T} css - The CSS string. + * @returns {`${T} as const`} - The CSS preset as a readonly string literal type. + */ +function createPreset(css: T) { + return /* css */ `:root { + ${css} +} + +body { + background-attachment: fixed; + background-color: #000; + background-image: var(--image-url); + background-position-x: var(--image-position-x); + background-position-y: var(--image-position-y); + background-repeat: no-repeat; + background-size: var(--image-size); +} + +.MuiCard-root, +main { + background-color: var(--main-bg-color); +} + +:-webkit-autofill { + box-shadow: var(--autofill-color) 0px 0px 0px 100px inset !important; +} + +.monaco-editor, +.monaco-editor-background { + background-color: #2121213b !important; + --vscode-editorGutter-background: #283d671a !important; +} + +.decorationsOverviewRuler, +.monaco-editor .minimap canvas { + opacity: 0.6; +} + +.MuiOutlinedInput-root { + background-color: #2424248c !important; +} + +p.Mui-error { + background-color: #2f2e2eba; + color: var(--error-color); +} + +a, +span.Mui-checked>svg, +.MuiInputBase-root.MuiOutlinedInput-root.MuiInputBase-colorPrimary.Mui-focused>fieldset, +/* Bottom Navigation */ +.Mui-selected, +.MuiButton-outlined { + color: var(--theme-color) !important; + border-color: var(--theme-color); +} + +label.Mui-focused, +.MuiButton-root.MuiButton-text { + color: var(--theme-color) !important; +} + +.MuiButton-outlined { + background-color: #2424248c; +} + +.MuiButton-outlined:hover { + color: #fff !important; + background-color: var(--hover-btn-color); +} + +.MuiLoadingButton-root { + color: #fff; + background-color: var(--convert-btn-color); +} + +.MuiLoadingButton-root:hover { + background-color: var(--hover-convert-btn-color); +} + +.MuiLinearProgress-bar, +.MuiTabs-indicator { + background-color: var(--theme-color); +} +` as const; +} + +const preset1 = createPreset( + `--autofill-color: #691c3747; + --convert-btn-color: #ab2b7e6e; + --error-color: #ff1655; + --hover-btn-color: #ff89898b; + --hover-convert-btn-color: #fd3b3b6e; + --image-size: cover; + --image-url: url("https://i.redd.it/red-forest-1920-1080-v0-s9u8ki2rr70a1.jpg?s=139edf608c428656505a143635a0687dec086229"); + --main-bg-color: #2223; + --theme-color: #ff8e16;`, +); + +const preset2 = createPreset( + `--autofill-color: #5eb1ef24; + --convert-btn-color: #3369ad7d; + --hover-btn-color: #1d5aa58b; + --hover-convert-btn-color: #2665b5d1; + --image-size: cover; + --image-url: url("https://images.pexels.com/photos/2817421/pexels-photo-2817421.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750& dpr=1"); + --main-bg-color: #2223; + --theme-color: #5a9ab9;`, +); + +const preset3 = createPreset( + `--autofill-color: #eb37ff1c; + --convert-btn-color: #ab2b7e6e; + --hover-btn-color: #8b51fb8b; + --hover-convert-btn-color: #7d00c9a3; + --image-size: cover; + --image-url: url("https://images.pexels.com/photos/6162265/pexels-photo-6162265.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"); + --main-bg-color: #2223; + --theme-color: #9644f1;`, +); + +const preset4 = createPreset( + `--autofill-color: #a19c0038; + --convert-btn-color: #94ce7c6e; + --hover-btn-color: #cefb518b; + --hover-convert-btn-color: #81c462a3; + --image-position-x: center; + --image-position-y: center; + --image-url: url('https://images.pexels.com/photos/973324/pexels-photo-973324.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1'); + --main-bg-color: #222a; + --theme-color: rgb(185, 185, 90);`, +); + +export const presetStyles = { + '1': preset1, + '2': preset2, + '3': preset3, + '4': preset4, +} as const; + +export function selectPreset(select: string | null) { + switch (select) { + case '1': + case '2': + case '3': + case '4': + return select; + default: + return '0'; + } +} diff --git a/gui/frontend/src/utils/translation.ts b/gui/frontend/src/utils/translation.ts new file mode 100644 index 0000000..921b24c --- /dev/null +++ b/gui/frontend/src/utils/translation.ts @@ -0,0 +1,47 @@ +'use client'; +import { type Resource, use } from 'i18next'; +import { initReactI18next } from 'react-i18next'; + +import { notify } from '@/components/notifications'; +import { localStorageManager } from '@/utils/local_storage_manager'; + +import dictEnUs from '@/../../locales/en-US.json'; +import dictJaJp from '@/../../locales/ja-JP.json'; + +function getCustomTranslationDict() { + try { + return JSON.parse(localStorageManager.get('custom-translation-dict') ?? '{}'); + } catch (error) { + notify.error(`${error}`); + } +} + +// The keys in RESOURCE are language tags according to the BCP-47 standard. +// See: https://partnerhub.warnermediagroup.com/metadata/languages +const resources = { + 'en-US': { + translation: dictEnUs, + }, + 'ja-JP': { + translation: dictJaJp, + }, + ja: { + translation: dictJaJp, + }, + custom: { translation: getCustomTranslationDict() }, +} as const satisfies Resource; + +export type I18nKeys = keyof (typeof resources)['en-US']['translation']; + +use(initReactI18next) // passes i18n down to react-i18next + .init({ + resources, + // NOTE: + // Since it seems that `window.navigator.language` cannot automatically detect the language, + // I have created a hook called useLocale as a substitute. + lng: localStorageManager.get('locale') ?? window.navigator.language, + fallbackLng: 'en-US', + interpolation: { + escapeValue: false, // react already safes from xss + }, + }); diff --git a/gui/frontend/tsconfig.json b/gui/frontend/tsconfig.json new file mode 100644 index 0000000..5a5dd67 --- /dev/null +++ b/gui/frontend/tsconfig.json @@ -0,0 +1,40 @@ +{ + "compilerOptions": { + "target": "ESNext", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "noUnusedLocals": true, + "noUnusedParameters": true, + "removeComments": false, + "preserveConstEnums": true, + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./src/*"] + }, + "forceConsistentCasingInFileNames": true + }, + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + "../out/types/**/*.ts", + ".next/types/**/*.ts", + "./out/types/**/*.ts", + "../../vitest.config.ts" + ], + "exclude": ["node_modules"] +} diff --git a/gui/frontend/vitest.setup.mts b/gui/frontend/vitest.setup.mts new file mode 100644 index 0000000..19c44e8 --- /dev/null +++ b/gui/frontend/vitest.setup.mts @@ -0,0 +1,9 @@ +import '@testing-library/jest-dom/vitest'; +import { loadEnvConfig } from '@next/env'; +import { configure } from '@testing-library/react'; + +loadEnvConfig(process.cwd()); + +configure({ + testIdAttribute: 'data-test', +}); diff --git a/import_map.json b/import_map.json deleted file mode 100644 index 51dfb19..0000000 --- a/import_map.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "imports": { - "twind": "https://cdn.skypack.dev/twind@0.16.19", - "@tabler/icons-react": "https://esm.sh/v113/*@tabler/icons-react@2.16.0", - "@tauri-apps/api": "https://esm.sh/v113/@tauri-apps/api@1.2.0", - "@tauri-apps/api/": "https://esm.sh/v113/@tauri-apps/api@1.2.0/", - "clsx": "https://esm.sh/v113/clsx@1.2.1", - "react-dom": "https://esm.sh/v113/*react-dom@18.2.0", - "react-dom/": "https://esm.sh/v113/*react-dom@18.2.0/", - "react-number-format": "https://esm.sh/v113/*react-number-format@5.1.4", - "react": "https://esm.sh/v113/react@18.2.0", - "react/": "https://esm.sh/v113/react@18.2.0/", - "reactive-button": "https://esm.sh/v113/*reactive-button@1.3.13" - }, - "scopes": { - "https://esm.sh/v113/": { - "@babel/runtime": "https://esm.sh/v113/@babel/runtime@7.21.0", - "@tabler/icons": "https://esm.sh/v113/@tabler/icons@2.16.0", - "@twind/core": "https://esm.sh/v113/@twind/core@1.1.3", - "hoist-non-react-statics": "https://esm.sh/v113/hoist-non-react-statics@3.3.2", - "loose-envify": "https://esm.sh/v113/loose-envify@1.4.0", - "prop-types": "https://esm.sh/v113/prop-types@15.8.1", - "reselect": "https://esm.sh/v113/reselect@4.1.7", - "scheduler": "https://esm.sh/v113/scheduler@0.23.0" - } - } -} \ No newline at end of file diff --git a/locales/en-US.json b/locales/en-US.json new file mode 100644 index 0000000..dff8704 --- /dev/null +++ b/locales/en-US.json @@ -0,0 +1,63 @@ +{ + "autostart-label": "Auto start", + "autostart-tooltip": "Starts automatically at PC startup.", + "backup-dialog-all-checked-label": "Check all", + "backup-dialog-pub-checked-label": "Check all public", + "backup-export-btn-name": "Export", + "backup-export-dialog-title": "Export Settings", + "backup-export-success": "Settings exported.", + "backup-export-tooltip": "Export current settings.(Please be careful to handle personal information when transferring to others.)", + "backup-import-btn-name": "Import", + "backup-import-dialog-title": "Import Settings", + "backup-import-tooltip": "Import settings from Json file.(JavaScript is also executed at the moment of import! If it is someone else's file, please be careful that the JavaScript is not malicious.)", + "cancel-btn": "Cancel", + "css-preset-list-item0": "Custom", + "css-preset-list-item1": "Preset1", + "css-preset-list-item2": "Preset2", + "css-preset-list-item3": "Preset3", + "css-preset-list-item4": "Preset4", + "css-preset-list-label": "CSS Preset", + "css-preset-list-tooltip": "You can choose a CSS preset.", + "css-preset-list-tooltip2": "Note: Editing \"Preset\" will overwrite \"Custom\".", + "custom-css-label": "Currently applied CSS", + "custom-js-auto-run-label": "JS Auto run", + "custom-js-auto-run-tooltip": "Automatically run JavaScript on every page transition.(If disabled, it will automatically reload to apply the settings.)", + "custom-js-auto-run-tooltip2": "This configuration item will not be activated unless manually selected by the user.", + "custom-js-label": "Custom JavaScript(Please do not execute untrusted scripts)", + "editor-mode-list-label": "Editor Mode", + "import-lang-btn": "Import Language", + "import-lang-tooltip": "Import any language from a Json file. (automatically reloads for validation).", + "import-lang-tooltip2": "Note: For invalid Json, fall back to English. (See Wiki for how to write Json)", + "lang-preset-auto": "Auto", + "lang-preset-custom": "Custom", + "lang-preset-label": "Language", + "log-level-list-label": "Log Level", + "log-level-list-tooltip": "Minor log level encompasses the more critical log levels. (i.e. Error ⊂ Info)", + "log-level-list-tooltip2": "Debug: Logs data on the way of the converted condition.", + "log-level-list-tooltip3": " Info: Log the conversion time.", + "log-level-list-tooltip4": "Error: Logs nothing but errors.", + "notice-limit": "Limit", + "notice-position-bottom-center": "Bottom Center", + "notice-position-bottom-left": "Bottom Left", + "notice-position-bottom-right": "Bottom Right", + "notice-position-list-label": "Notice Position", + "notice-position-top-center": "Top Center", + "notice-position-top-left": "Top Left", + "notice-position-top-right": "Top Right", + "open-log-btn": "Open log", + "open-log-dir-btn": "Log(dir)", + "open-log-dir-tooltip": "Open the log storage location.", + "open-log-tooltip": "Open current log file.(Rotate to a new log file each time the application is launched.)", + "select-btn": "Select", + "tab-label-backup": "Backup", + "tab-label-editor": "Editor / Preset", + "tab-label-lang": "Language", + "tab-label-notice": "Notice", + "target-bt-id": "Display in tray", + "target-bt-id-tooltip": "Display the battery information for this device in the taskbar's tray.", + "update-btn": "Update", + "update-interval": "Update interval(mins)", + "update-tooltip": "Update Bluetooth information", + "updating-btn": "Updating...", + "warn-limit-battery": "Warn battery(%)" +} diff --git a/locales/en.json b/locales/en.json new file mode 120000 index 0000000..45934c2 --- /dev/null +++ b/locales/en.json @@ -0,0 +1 @@ +./en-US.json \ No newline at end of file diff --git a/locales/ja-JP.json b/locales/ja-JP.json new file mode 100644 index 0000000..1840bc3 --- /dev/null +++ b/locales/ja-JP.json @@ -0,0 +1,67 @@ +{ + "autostart-label": "自動起動", + "autostart-tooltip": "PC起動時に自動で起動します。", + "backup-dialog-all-checked-label": "全て選択", + "backup-dialog-pub-checked-label": "個人情報以外選択", + "backup-export-btn-name": "エクスポート", + "backup-export-dialog-title": "設定のエクスポート", + "backup-export-success": "設定をエクスポートしました", + "backup-export-tooltip": "現在の設定をエクスポートします(他人に譲渡するときは個人情報の取り扱いに注意してください)", + "backup-import-btn-name": "インポート", + "backup-import-dialog-title": "設定のインポート", + "backup-import-tooltip": "Jsonファイルから設定をインポートします(他人のファイルの場合はJavaScriptに悪意がないか注意してください。)", + "cancel-btn": "キャンセル", + "css-preset-list-item0": "カスタム", + "css-preset-list-item1": "プリセット1", + "css-preset-list-item2": "プリセット2", + "css-preset-list-item3": "プリセット3", + "css-preset-list-item4": "プリセット4", + "css-preset-list-label": "CSSプリセット", + "css-preset-list-tooltip": "CSS presetを選択", + "css-preset-list-tooltip2": "注意: 「プリセット」を編集すると「カスタム」が上書きされます", + "custom-css-label": "現在適用されているCSS", + "custom-js-auto-run-label": "JS自動実行", + "custom-js-auto-run-tooltip": "ページを遷移するたびにJavaScriptを自動実行します。(無効化した場合、設定を適用するために自動で再読み込みします)", + "custom-js-auto-run-tooltip2": "この設定項目はユーザーが手動で選択しない限り有効化されることはありません", + "custom-js-label": "カスタムJavaScript(信用できないスクリプトは実行しないでください)", + "editor-mode-list-label": "エディタモード", + "import-lang-btn": "言語インポート", + "import-lang-tooltip": "Jsonファイルから任意の言語をインポートします。(有効化のため自動で再読み込みします)", + "import-lang-tooltip2": "注: 無効なJsonの場合、英語にフォールバックします。(Jsonの書き方はWikiを参照してください)", + "lang-preset-auto": "自動", + "lang-preset-custom": "カスタム", + "lang-preset-label": "言語", + "log-level-list-label": "ログレベル", + "log-level-list-tooltip": "軽度なログレベルはより重大なログレベルを包含します。(Error ⊂ Info)", + "log-level-list-tooltip2": "Debug: 変換されたconditionの途中データを記録します", + "log-level-list-tooltip3": " Info: 変換時間を記録します", + "log-level-list-tooltip4": "Error: 重大なエラー以外記録しません", + "notice-limit": "通知上限", + "notice-position-bottom-center": "下・中央", + "notice-position-bottom-left": "下・左", + "notice-position-bottom-right": "下・右", + "notice-position-list-label": "通知位置", + "notice-position-top-center": "上・中央", + "notice-position-top-left": "上・左", + "notice-position-top-right": "上・右", + "open-log-btn": "ログを閲覧", + "open-log-dir-btn": "ログ(dir)", + "open-log-dir-tooltip": "ログの格納場所を開きます。", + "open-log-tooltip": "現在のログファイルを開きます。(アプリを起動するたびに新しいログファイルにローテーションします)", + "progress-btn": "進捗バー", + "progress-btn-tooltip": "詳細な進捗状況を表示します", + "progress-btn-tooltip2": "", + "remove-oar-btn": "OARを削除", + "select-btn": "選択", + "tab-label-backup": "バックアップ", + "tab-label-editor": "エディタ・プリセット", + "tab-label-lang": "言語", + "tab-label-notice": "通知", + "target-bt-id": "トレイに表示", + "target-bt-id-tooltip": "このデバイスのバッテリー情報をタスクバーのトレイに表示させます。", + "update-btn": "情報の更新", + "update-interval": "更新間隔(分)", + "update-tooltip": "Bluetoothの情報を更新します。", + "updating-btn": "更新中...", + "warn-limit-battery": "警告容量(%)" +} diff --git a/locales/readme.md b/locales/readme.md new file mode 100644 index 0000000..631c99a --- /dev/null +++ b/locales/readme.md @@ -0,0 +1,14 @@ +# Localization + +This files in are language tags according to the BCP-47 standard. + +- See: + [Content Partner Hub | BCP-47 Language Tags](https://partnerhub.warnermediagroup.com/metadata/languages) + +## Note + +This file information is currently only used on the front end of the GUI. +It is placed in the root directory for clarity and for future reference. + +The file `en.json` is not used in the `en-US.json` symbolic link. +It exists to prevent erroneous error reporting of i18n's VS Code extension. diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..1d80085 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,11953 @@ +{ + "name": "bluetooth-battery-monitor", + "version": "0.3.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "bluetooth-battery-monitor", + "version": "0.3.0", + "license": "MIT", + "dependencies": { + "@monaco-editor/react": "^4.6.0", + "@mui/icons-material": "^5.16.4", + "@mui/lab": "5.0.0-alpha.170", + "@mui/material": "^5.16.4", + "@tauri-apps/api": "^1.6.0", + "i18next": "^23.12.2", + "next": "14.2.5", + "notistack": "^3.0.1", + "react": "18.3.1", + "react-dom": "18.3.1", + "react-hook-form": "^7.52.1", + "react-i18next": "^15.0.0", + "react-use": "^17.5.1", + "tauri-plugin-autostart-api": "github:tauri-apps/tauri-plugin-autostart#v1" + }, + "devDependencies": { + "@biomejs/biome": "1.8.3", + "@tauri-apps/cli": "^1.6.0", + "@testing-library/jest-dom": "^6.4.7", + "@testing-library/react": "^16.0.0", + "@types/node": "20.14.11", + "@types/react": "18.3.3", + "@types/react-dom": "18.3.0", + "@vitejs/plugin-react-swc": "^3.7.0", + "eslint": "^8.57.0", + "eslint-config-next": "14.2.5", + "jsdom": "^24.1.1", + "prettier": "^3.3.3", + "rimraf": "^6.0.1", + "typescript": "5.5.4", + "vite-tsconfig-paths": "^4.3.2", + "vitest": "2.0.4" + } + }, + "node_modules/@adobe/css-tools": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.0.tgz", + "integrity": "sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "devOptional": true, + "peer": true, + "dependencies": { + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "devOptional": true, + "peer": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "devOptional": true, + "peer": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "devOptional": true, + "peer": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "devOptional": true, + "peer": true + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "devOptional": true, + "peer": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "devOptional": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "devOptional": true, + "peer": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.3.tgz", + "integrity": "sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz", + "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.3", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.2", + "@babel/parser": "^7.23.3", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.3", + "@babel/types": "^7.23.3", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@babel/core/node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.3.tgz", + "integrity": "sha512-keeZWAV4LU3tW0qRi19HRpabC/ilM0HRBBzf9/k8FFiG4KVpiv0FIy4hHfLfFQZNhziCTPTmd59zoyv6DNISzg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/types": "^7.23.3", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", + "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.15", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "optional": true, + "peer": true, + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "optional": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "devOptional": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", + "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.2.tgz", + "integrity": "sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.2", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", + "devOptional": true, + "peer": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "devOptional": true, + "peer": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "devOptional": true, + "peer": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "devOptional": true, + "peer": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "devOptional": true, + "peer": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "devOptional": true, + "peer": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "devOptional": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "devOptional": true, + "peer": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.3.tgz", + "integrity": "sha512-uVsWNvlVsIninV2prNz/3lHCb+5CJ+e+IUBfbjToAHODtfGYLfCFuY4AU7TskI+dAKk+njsPiBjq1gKTvZOBaw==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", + "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", + "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz", + "integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.3.tgz", + "integrity": "sha512-+K0yF1/9yR0oHdE0StHuEj3uTPzwwbrLGfNOndVJVV2TqA5+j3oljJUb4nmB954FLGjNem976+B+eDuLIjesiQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.3", + "@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.22.6", + "@babel/parser": "^7.23.3", + "@babel/types": "^7.23.3", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.3.tgz", + "integrity": "sha512-OZnvoH2l8PK5eUvEcUyCt/sXgr/h+UWpVuBbOljwcrAgUl6lpchoQ++PHGyQy1AtYnVA6CEq3y5xeEI10brpXw==", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@biomejs/biome": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.8.3.tgz", + "integrity": "sha512-/uUV3MV+vyAczO+vKrPdOW0Iaet7UnJMU4bNMinggGJTAnBPjCoLEYcyYtYHNnUNYlv4xZMH6hVIQCAozq8d5w==", + "dev": true, + "hasInstallScript": true, + "license": "MIT OR Apache-2.0", + "bin": { + "biome": "bin/biome" + }, + "engines": { + "node": ">=14.21.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/biome" + }, + "optionalDependencies": { + "@biomejs/cli-darwin-arm64": "1.8.3", + "@biomejs/cli-darwin-x64": "1.8.3", + "@biomejs/cli-linux-arm64": "1.8.3", + "@biomejs/cli-linux-arm64-musl": "1.8.3", + "@biomejs/cli-linux-x64": "1.8.3", + "@biomejs/cli-linux-x64-musl": "1.8.3", + "@biomejs/cli-win32-arm64": "1.8.3", + "@biomejs/cli-win32-x64": "1.8.3" + } + }, + "node_modules/@biomejs/cli-darwin-arm64": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.8.3.tgz", + "integrity": "sha512-9DYOjclFpKrH/m1Oz75SSExR8VKvNSSsLnVIqdnKexj6NwmiMlKk94Wa1kZEdv6MCOHGHgyyoV57Cw8WzL5n3A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-darwin-x64": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.8.3.tgz", + "integrity": "sha512-UeW44L/AtbmOF7KXLCoM+9PSgPo0IDcyEUfIoOXYeANaNXXf9mLUwV1GeF2OWjyic5zj6CnAJ9uzk2LT3v/wAw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.8.3.tgz", + "integrity": "sha512-fed2ji8s+I/m8upWpTJGanqiJ0rnlHOK3DdxsyVLZQ8ClY6qLuPc9uehCREBifRJLl/iJyQpHIRufLDeotsPtw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64-musl": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.8.3.tgz", + "integrity": "sha512-9yjUfOFN7wrYsXt/T/gEWfvVxKlnh3yBpnScw98IF+oOeCYb5/b/+K7YNqKROV2i1DlMjg9g/EcN9wvj+NkMuQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.8.3.tgz", + "integrity": "sha512-I8G2QmuE1teISyT8ie1HXsjFRz9L1m5n83U1O6m30Kw+kPMPSKjag6QGUn+sXT8V+XWIZxFFBoTDEDZW2KPDDw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64-musl": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.8.3.tgz", + "integrity": "sha512-UHrGJX7PrKMKzPGoEsooKC9jXJMa28TUSMjcIlbDnIO4EAavCoVmNQaIuUSH0Ls2mpGMwUIf+aZJv657zfWWjA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-arm64": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.8.3.tgz", + "integrity": "sha512-J+Hu9WvrBevfy06eU1Na0lpc7uR9tibm9maHynLIoAjLZpQU3IW+OKHUtyL8p6/3pT2Ju5t5emReeIS2SAxhkQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-x64": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.8.3.tgz", + "integrity": "sha512-/PJ59vA1pnQeKahemaQf4Nyj7IKUvGQSc3Ze1uIGi+Wvr1xF7rGobSrAAG01T/gUDG21vkDsZYM03NAmPiVkqg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@emotion/babel-plugin": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/cache": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "dependencies": { + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==", + "optional": true, + "peer": true + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", + "optional": true, + "peer": true, + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "node_modules/@emotion/react": { + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz", + "integrity": "sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==", + "optional": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz", + "integrity": "sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==", + "optional": true, + "peer": true, + "dependencies": { + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + }, + "node_modules/@emotion/styled": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz", + "integrity": "sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==", + "optional": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==", + "optional": true, + "peer": true + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "optional": true, + "peer": true, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", + "dependencies": { + "@floating-ui/utils": "^0.2.1" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.1.tgz", + "integrity": "sha512-iA8qE43/H5iGozC3W0YSnVSW42Vh522yyM1gj+BqRwVsTNOyr231PsXDaV04yT39PsO0QL2QpbI/M0ZaLUQgRQ==", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.1" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz", + "integrity": "sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==", + "dependencies": { + "@floating-ui/dom": "^1.6.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", + "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "dev": true + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@jest/transform/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@jest/transform/node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@monaco-editor/loader": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.4.0.tgz", + "integrity": "sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==", + "dependencies": { + "state-local": "^1.0.6" + }, + "peerDependencies": { + "monaco-editor": ">= 0.21.0 < 1" + } + }, + "node_modules/@monaco-editor/react": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.6.0.tgz", + "integrity": "sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==", + "dependencies": { + "@monaco-editor/loader": "^1.4.0" + }, + "peerDependencies": { + "monaco-editor": ">= 0.25.0 < 1", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@mui/base": { + "version": "5.0.0-beta.40", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz", + "integrity": "sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@floating-ui/react-dom": "^2.0.8", + "@mui/types": "^7.2.14", + "@mui/utils": "^5.15.14", + "@popperjs/core": "^2.11.8", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.4.tgz", + "integrity": "sha512-rNdHXhclwjEZnK+//3SR43YRx0VtjdHnUFhMSGYmAMJve+KiwEja/41EYh8V3pZKqF2geKyfcFUenTfDTYUR4w==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/icons-material": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.4.tgz", + "integrity": "sha512-j9/CWctv6TH6Dou2uR2EH7UOgu79CW/YcozxCYVLJ7l03pCsiOlJ5sBArnWJxJ+nGkFwyL/1d1k8JEPMDR125A==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^5.0.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/lab": { + "version": "5.0.0-alpha.170", + "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.170.tgz", + "integrity": "sha512-0bDVECGmrNjd3+bLdcLiwYZ0O4HP5j5WSQm5DV6iA/Z9kr8O6AnvZ1bv9ImQbbX7Gj3pX4o43EKwCutj3EQxQg==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/base": "5.0.0-beta.40", + "@mui/system": "^5.15.15", + "@mui/types": "^7.2.14", + "@mui/utils": "^5.15.14", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@mui/material": ">=5.15.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.4.tgz", + "integrity": "sha512-dBnh3/zRYgEVIS3OE4oTbujse3gifA0qLMmuUk13ywsDCbngJsdgwW5LuYeiT5pfA8PGPGSqM7mxNytYXgiMCw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/core-downloads-tracker": "^5.16.4", + "@mui/system": "^5.16.4", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.4", + "@popperjs/core": "^2.11.8", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^18.3.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, + "node_modules/@mui/private-theming": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.16.4.tgz", + "integrity": "sha512-ZsAm8cq31SJ37SVWLRlu02v9SRthxnfQofaiv14L5Bht51B0dz6yQEoVU/V8UduZDCCIrWkBHuReVfKhE/UuXA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/utils": "^5.16.4", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.16.4.tgz", + "integrity": "sha512-0+mnkf+UiAmTVB8PZFqOhqf729Yh0Cxq29/5cA3VAyDVTRIUUQ8FXQhiAhUIbijFmM72rY80ahFPXIm4WDbzcA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.4.tgz", + "integrity": "sha512-ET1Ujl2/8hbsD611/mqUuNArMCGv/fIWO/f8B3ZqF5iyPHM2aS74vhTNyjytncc4i6dYwGxNk+tLa7GwjNS0/w==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/private-theming": "^5.16.4", + "@mui/styled-engine": "^5.16.4", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.4", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.2.15", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.15.tgz", + "integrity": "sha512-nbo7yPhtKJkdf9kcVOF8JZHPZTmqXjJ/tI0bdWgHg5tp9AnIN4Y7f7wm9T+0SyGYJk76+GYZ8Q5XaTYAsUHN0Q==", + "license": "MIT", + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.4.tgz", + "integrity": "sha512-nlppYwq10TBIFqp7qxY0SvbACOXeOjeVL3pOcDsK0FT8XjrEXh9/+lkg8AEIzD16z7YfiJDQjaJG2OLkE7BxNg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@types/prop-types": "^15.7.12", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-is": "^18.3.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, + "node_modules/@next/env": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.5.tgz", + "integrity": "sha512-/zZGkrTOsraVfYjGP8uM0p6r0BDT6xWpkjdVbcz66PJVSpwXX3yNiRycxAuDfBKGWBrZBXRuK/YVlkNgxHGwmA==", + "license": "MIT" + }, + "node_modules/@next/eslint-plugin-next": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.2.5.tgz", + "integrity": "sha512-LY3btOpPh+OTIpviNojDpUdIbHW9j0JBYBjsIp8IxtDFfYFyORvw3yNq6N231FVqQA7n7lwaf7xHbVJlA1ED7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "10.3.10" + } + }, + "node_modules/@next/eslint-plugin-next/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@next/eslint-plugin-next/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@next/eslint-plugin-next/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.5.tgz", + "integrity": "sha512-/9zVxJ+K9lrzSGli1///ujyRfon/ZneeZ+v4ptpiPoOU+GKZnm8Wj8ELWU1Pm7GHltYRBklmXMTUqM/DqQ99FQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.5.tgz", + "integrity": "sha512-vXHOPCwfDe9qLDuq7U1OYM2wUY+KQ4Ex6ozwsKxp26BlJ6XXbHleOUldenM67JRyBfVjv371oneEvYd3H2gNSA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.5.tgz", + "integrity": "sha512-vlhB8wI+lj8q1ExFW8lbWutA4M2ZazQNvMWuEDqZcuJJc78iUnLdPPunBPX8rC4IgT6lIx/adB+Cwrl99MzNaA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.5.tgz", + "integrity": "sha512-NpDB9NUR2t0hXzJJwQSGu1IAOYybsfeB+LxpGsXrRIb7QOrYmidJz3shzY8cM6+rO4Aojuef0N/PEaX18pi9OA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.5.tgz", + "integrity": "sha512-8XFikMSxWleYNryWIjiCX+gU201YS+erTUidKdyOVYi5qUQo/gRxv/3N1oZFCgqpesN6FPeqGM72Zve+nReVXQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.5.tgz", + "integrity": "sha512-6QLwi7RaYiQDcRDSU/os40r5o06b5ue7Jsk5JgdRBGGp8l37RZEh9JsLSM8QF0YDsgcosSeHjglgqi25+m04IQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.5.tgz", + "integrity": "sha512-1GpG2VhbspO+aYoMOQPQiqc/tG3LzmsdBH0LhnDS3JrtDx2QmzXe0B6mSZZiN3Bq7IOMXxv1nlsjzoS1+9mzZw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.5.tgz", + "integrity": "sha512-Igh9ZlxwvCDsu6438FXlQTHlRno4gFpJzqPjSIBZooD22tKeI4fE/YMRoHVJHmrQ2P5YL1DoZ0qaOKkbeFWeMg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.5.tgz", + "integrity": "sha512-tEQ7oinq1/CjSG9uSTerca3v4AZ+dFa+4Yu6ihaG8Ud8ddqLQgFGcnwYls13H5X5CPDPZJdYxyeMui6muOLd4g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", + "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", + "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", + "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", + "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", + "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", + "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", + "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", + "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", + "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", + "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", + "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", + "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", + "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", + "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", + "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", + "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.3.tgz", + "integrity": "sha512-qC/xYId4NMebE6w/V33Fh9gWxLgURiNYgVNObbJl2LZv0GUUItCcCqC5axQSwRaAgaxl2mELq1rMzlswaQ0Zxg==", + "dev": true + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@swc/core": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.5.7.tgz", + "integrity": "sha512-U4qJRBefIJNJDRCCiVtkfa/hpiZ7w0R6kASea+/KLp+vkus3zcLSB8Ub8SvKgTIxjWpwsKcZlPf5nrv4ls46SQ==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@swc/counter": "^0.1.2", + "@swc/types": "0.1.7" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.5.7", + "@swc/core-darwin-x64": "1.5.7", + "@swc/core-linux-arm-gnueabihf": "1.5.7", + "@swc/core-linux-arm64-gnu": "1.5.7", + "@swc/core-linux-arm64-musl": "1.5.7", + "@swc/core-linux-x64-gnu": "1.5.7", + "@swc/core-linux-x64-musl": "1.5.7", + "@swc/core-win32-arm64-msvc": "1.5.7", + "@swc/core-win32-ia32-msvc": "1.5.7", + "@swc/core-win32-x64-msvc": "1.5.7" + }, + "peerDependencies": { + "@swc/helpers": "^0.5.0" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.5.7.tgz", + "integrity": "sha512-bZLVHPTpH3h6yhwVl395k0Mtx8v6CGhq5r4KQdAoPbADU974Mauz1b6ViHAJ74O0IVE5vyy7tD3OpkQxL/vMDQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.5.7.tgz", + "integrity": "sha512-RpUyu2GsviwTc2qVajPL0l8nf2vKj5wzO3WkLSHAHEJbiUZk83NJrZd1RVbEknIMO7+Uyjh54hEh8R26jSByaw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.5.7.tgz", + "integrity": "sha512-cTZWTnCXLABOuvWiv6nQQM0hP6ZWEkzdgDvztgHI/+u/MvtzJBN5lBQ2lue/9sSFYLMqzqff5EHKlFtrJCA9dQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.5.7.tgz", + "integrity": "sha512-hoeTJFBiE/IJP30Be7djWF8Q5KVgkbDtjySmvYLg9P94bHg9TJPSQoC72tXx/oXOgXvElDe/GMybru0UxhKx4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.5.7.tgz", + "integrity": "sha512-+NDhK+IFTiVK1/o7EXdCeF2hEzCiaRSrb9zD7X2Z7inwWlxAntcSuzZW7Y6BRqGQH89KA91qYgwbnjgTQ22PiQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.5.7.tgz", + "integrity": "sha512-25GXpJmeFxKB+7pbY7YQLhWWjkYlR+kHz5I3j9WRl3Lp4v4UD67OGXwPe+DIcHqcouA1fhLhsgHJWtsaNOMBNg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.5.7.tgz", + "integrity": "sha512-0VN9Y5EAPBESmSPPsCJzplZHV26akC0sIgd3Hc/7S/1GkSMoeuVL+V9vt+F/cCuzr4VidzSkqftdP3qEIsXSpg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.5.7.tgz", + "integrity": "sha512-RtoNnstBwy5VloNCvmvYNApkTmuCe4sNcoYWpmY7C1+bPR+6SOo8im1G6/FpNem8AR5fcZCmXHWQ+EUmRWJyuA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.5.7.tgz", + "integrity": "sha512-Xm0TfvcmmspvQg1s4+USL3x8D+YPAfX2JHygvxAnCJ0EHun8cm2zvfNBcsTlnwYb0ybFWXXY129aq1wgFC9TpQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.5.7.tgz", + "integrity": "sha512-tp43WfJLCsKLQKBmjmY/0vv1slVywR5Q4qKjF5OIY8QijaEW7/8VwPyUyVoJZEnDgv9jKtUTG5PzqtIYPZGnyg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==" + }, + "node_modules/@swc/helpers": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz", + "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==", + "dependencies": { + "@swc/counter": "^0.1.3", + "tslib": "^2.4.0" + } + }, + "node_modules/@swc/types": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.7.tgz", + "integrity": "sha512-scHWahbHF0eyj3JsxG9CFJgFdFNaVQCNAimBlT6PzS3n/HptxqREjsm4OH6AN3lYcffZYSPxXW8ua2BEHp0lJQ==", + "dev": true, + "dependencies": { + "@swc/counter": "^0.1.3" + } + }, + "node_modules/@tauri-apps/api": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-1.6.0.tgz", + "integrity": "sha512-rqI++FWClU5I2UBp4HXFvl+sBWkdigBkxnpJDQUWttNyG7IZP4FwQGhTNL5EOw0vI8i6eSAJ5frLqO7n7jbJdg==", + "license": "Apache-2.0 OR MIT", + "engines": { + "node": ">= 14.6.0", + "npm": ">= 6.6.0", + "yarn": ">= 1.19.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + } + }, + "node_modules/@tauri-apps/cli": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-1.6.0.tgz", + "integrity": "sha512-DBBpBl6GhTzm8ImMbKkfaZ4fDTykWrC7Q5OXP4XqD91recmDEn2LExuvuiiS3HYe7uP8Eb5B9NPHhqJb+Zo7qQ==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "bin": { + "tauri": "tauri.js" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + }, + "optionalDependencies": { + "@tauri-apps/cli-darwin-arm64": "1.6.0", + "@tauri-apps/cli-darwin-x64": "1.6.0", + "@tauri-apps/cli-linux-arm-gnueabihf": "1.6.0", + "@tauri-apps/cli-linux-arm64-gnu": "1.6.0", + "@tauri-apps/cli-linux-arm64-musl": "1.6.0", + "@tauri-apps/cli-linux-x64-gnu": "1.6.0", + "@tauri-apps/cli-linux-x64-musl": "1.6.0", + "@tauri-apps/cli-win32-arm64-msvc": "1.6.0", + "@tauri-apps/cli-win32-ia32-msvc": "1.6.0", + "@tauri-apps/cli-win32-x64-msvc": "1.6.0" + } + }, + "node_modules/@tauri-apps/cli-darwin-arm64": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-1.6.0.tgz", + "integrity": "sha512-SNRwUD9nqGxY47mbY1CGTt/jqyQOU7Ps7Mx/mpgahL0FVUDiCEY/5L9QfEPPhEgccgcelEVn7i6aQHIkHyUtCA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-darwin-x64": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-1.6.0.tgz", + "integrity": "sha512-g2/uDR/eeH2arvuawA4WwaEOqv/7jDO/ZLNI3JlBjP5Pk8GGb3Kdy0ro1xQzF94mtk2mOnOXa4dMgAet4sUJ1A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm-gnueabihf": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-1.6.0.tgz", + "integrity": "sha512-EVwf4oRkQyG8BpSrk0gqO7oA0sDM2MdNDtJpMfleYFEgCxLIOGZKNqaOW3M7U+0Y4qikmG3TtRK+ngc8Ymtrjg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm64-gnu": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-1.6.0.tgz", + "integrity": "sha512-YdpY17cAySrhK9dX4BUVEmhAxE2o+6skIEFg8iN/xrDwRxhaNPI9I80YXPatUTX54Kx55T5++25VJG9+3iw83A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm64-musl": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.6.0.tgz", + "integrity": "sha512-4U628tuf2U8pMr4tIBJhEkrFwt+46dwhXrDlpdyWSZtnop5RJAVKHODm0KbWns4xGKfTW1F3r6sSv+2ZxLcISA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-x64-gnu": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-1.6.0.tgz", + "integrity": "sha512-AKRzp76fVUaJyXj5KRJT9bJyhwZyUnRQU0RqIRqOtZCT5yr6qGP8rjtQ7YhCIzWrseBlOllc3Qvbgw3Yl0VQcA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-x64-musl": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-1.6.0.tgz", + "integrity": "sha512-0edIdq6aMBTaRMIXddHfyAFL361JqulLLd2Wi2aoOie7DkQ2MYh6gv3hA7NB9gqFwNIGE+xtJ4BkXIP2tSGPlg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-arm64-msvc": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-1.6.0.tgz", + "integrity": "sha512-QwWpWk4ubcwJ1rljsRAmINgB2AwkyzZhpYbalA+MmzyYMREcdXWGkyixWbRZgqc6fEWEBmq5UG73qz5eBJiIKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-ia32-msvc": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-1.6.0.tgz", + "integrity": "sha512-Vtw0yxO9+aEFuhuxQ57ALG43tjECopRimRuKGbtZYDCriB/ty5TrT3QWMdy0dxBkpDTu3Rqsz30sbDzw6tlP3Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-x64-msvc": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-1.6.0.tgz", + "integrity": "sha512-h54FHOvGi7+LIfRchzgZYSCHB1HDlP599vWXQQJ/XnwJY+6Rwr2E5bOe/EhqoG8rbGkfK0xX3KPAvXPbUlmggg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@testing-library/dom": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.1.0.tgz", + "integrity": "sha512-wdsYKy5zupPyLCW2Je5DLHSxSfbIp6h80WoHOQc+RPtmPGA52O9x5MJEkv92Sjonpq+poOAtUKhh1kBGAXBrNA==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.4.7", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.4.7.tgz", + "integrity": "sha512-GaKJ0nijoNf30dWSOOzQEBkWBRk4rG3C/efw8zKrimNuZpnS/6/AEwo0WvZHgJxG84cNCgxt+mtbe1fsvfLp2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "@babel/runtime": "^7.9.2", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "lodash": "^4.17.21", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + }, + "peerDependencies": { + "@jest/globals": ">= 28", + "@types/bun": "latest", + "@types/jest": ">= 28", + "jest": ">= 28", + "vitest": ">= 0.32" + }, + "peerDependenciesMeta": { + "@jest/globals": { + "optional": true + }, + "@types/bun": { + "optional": true + }, + "@types/jest": { + "optional": true + }, + "jest": { + "optional": true + }, + "vitest": { + "optional": true + } + } + }, + "node_modules/@testing-library/jest-dom/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true + }, + "node_modules/@testing-library/jest-dom/node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/react": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.0.0.tgz", + "integrity": "sha512-guuxUKRWQ+FgNX0h0NS0FIq3Q3uLtWVpBzcLOggmfMoUpgBnzBzvLLd4fbm6yS8ydJd94cIfY4yP9qUQjM2KwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@testing-library/dom": "^10.0.0", + "@types/react": "^18.0.0", + "@types/react-dom": "^18.0.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "peer": true + }, + "node_modules/@types/babel__core": { + "version": "7.20.4", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.4.tgz", + "integrity": "sha512-mLnSC22IC4vcWiuObSRjrLd9XcBTGf59vUSoq2jkQDJ/QQ8PMI9rSuzE+aEV8karUMbskw07bKYoUJCKTUaygg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.7", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.7.tgz", + "integrity": "sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.4", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz", + "integrity": "sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.11", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.11.tgz", + "integrity": "sha512-S2mHmYIVe13vrm6q4kN6fLYYAka15ALQki/vgDC3mIukEOx8WJlv0kQPM+d4w8Gp6u0uSdKND04IlTXBv0rwnQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/jest/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@types/jest/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@types/jest/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@types/js-cookie": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.7.tgz", + "integrity": "sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==", + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.14.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", + "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "optional": true, + "peer": true + }, + "node_modules/@types/prop-types": { + "version": "15.7.12", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.3", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", + "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.0", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", + "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@types/yargs": { + "version": "17.0.31", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.31.tgz", + "integrity": "sha512-bocYSx4DI8TmdlvxqGpVNXOgCNR1Jj0gNPhhAY+iz1rgKDAaYrAYdFYnhDV1IFuiuVc9HkOwyDcFxaTElF3/wg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@typescript-eslint/parser": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.2.0.tgz", + "integrity": "sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "7.2.0", + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/typescript-estree": "7.2.0", + "@typescript-eslint/visitor-keys": "7.2.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz", + "integrity": "sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/visitor-keys": "7.2.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz", + "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz", + "integrity": "sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/visitor-keys": "7.2.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz", + "integrity": "sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.2.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/@vitejs/plugin-react-swc": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.7.0.tgz", + "integrity": "sha512-yrknSb3Dci6svCd/qhHqhFPDSw0QtjumcqdKMoNNzmOl5lMXTTiqzjWtG4Qask2HdvvzaNgSunbQGet8/GrKdA==", + "dev": true, + "dependencies": { + "@swc/core": "^1.5.7" + }, + "peerDependencies": { + "vite": "^4 || ^5" + } + }, + "node_modules/@vitest/expect": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.4.tgz", + "integrity": "sha512-39jr5EguIoanChvBqe34I8m1hJFI4+jxvdOpD7gslZrVQBKhh8H9eD7J/LJX4zakrw23W+dITQTDqdt43xVcJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.0.4", + "@vitest/utils": "2.0.4", + "chai": "^5.1.1", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/pretty-format": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.0.4.tgz", + "integrity": "sha512-RYZl31STbNGqf4l2eQM1nvKPXE0NhC6Eq0suTTePc4mtMQ1Fn8qZmjV4emZdEdG2NOWGKSCrHZjmTqDCDoeFBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.0.4.tgz", + "integrity": "sha512-Gk+9Su/2H2zNfNdeJR124gZckd5st4YoSuhF1Rebi37qTXKnqYyFCd9KP4vl2cQHbtuVKjfEKrNJxHHCW8thbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "2.0.4", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.0.4.tgz", + "integrity": "sha512-or6Mzoz/pD7xTvuJMFYEtso1vJo1S5u6zBTinfl+7smGUhqybn6VjzCDMhmTyVOFWwkCMuNjmNNxnyXPgKDoPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.0.4", + "magic-string": "^0.30.10", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.4.tgz", + "integrity": "sha512-uTXU56TNoYrTohb+6CseP8IqNwlNdtPwEO0AWl+5j7NelS6x0xZZtP0bDWaLvOfUbaYwhhWp1guzXUxkC7mW7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.4.tgz", + "integrity": "sha512-Zc75QuuoJhOBnlo99ZVUkJIuq4Oj0zAkrQ2VzCqNCx6wAwViHEh5Fnp4fiJTE9rA+sAoXRf00Z9xGgfEzV6fzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.0.4", + "estree-walker": "^3.0.3", + "loupe": "^3.1.1", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@xobotyi/scrollbar-width": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz", + "integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==", + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.toreversed": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz", + "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.3.tgz", + "integrity": "sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.1.0", + "es-shim-unscopables": "^1.0.2" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axe-core": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", + "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", + "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", + "dev": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "optional": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", + "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "optional": true, + "peer": true, + "dependencies": { + "caniuse-lite": "^1.0.30001541", + "electron-to-chromium": "^1.4.535", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "devOptional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001581", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001581.tgz", + "integrity": "sha512-whlTkwhqV2tUmP3oYhtNfaWGYHDdS3JYFQBKXxcUR9qqPWsRhFHhoISO2Xnl/g0xyKzht9mI1LZpiNWfMzHixQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chai": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz", + "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "optional": true, + "peer": true + }, + "node_modules/copy-to-clipboard": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", + "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", + "license": "MIT", + "dependencies": { + "toggle-selection": "^1.0.6" + } + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "optional": true, + "peer": true, + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-in-js-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz", + "integrity": "sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==", + "license": "MIT", + "dependencies": { + "hyphenate-style-name": "^1.0.3" + } + }, + "node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/css-tree/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true + }, + "node_modules/cssstyle": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.0.1.tgz", + "integrity": "sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==", + "dev": true, + "dependencies": { + "rrweb-cssom": "^0.6.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true + }, + "node_modules/data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "dev": true, + "dependencies": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "dev": true + }, + "node_modules/dedent": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", + "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", + "dev": true, + "optional": true, + "peer": true, + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "peer": true + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.4.585", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.585.tgz", + "integrity": "sha512-B4yBlX0azdA3rVMxpYwLQfDpdwOgcnLCkpvSOd68iFmeedo+WYjaBJS3/W58LVD8CB2nf+o7C4K9xz1l09RkWg==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/enhanced-resolve": { + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.1.tgz", + "integrity": "sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "optional": true, + "peer": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/error-stack-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "license": "MIT", + "dependencies": { + "stackframe": "^1.3.4" + } + }, + "node_modules/es-abstract": { + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", + "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "devOptional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-next": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.2.5.tgz", + "integrity": "sha512-zogs9zlOiZ7ka+wgUnmcM0KBEDjo4Jis7kxN1jvC0N4wynQ2MIx/KBkg4mVF63J5EK4W0QMCn7xO3vNisjaAoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@next/eslint-plugin-next": "14.2.5", + "@rushstack/eslint-patch": "^1.3.3", + "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-import-resolver-typescript": "^3.5.2", + "eslint-plugin-import": "^2.28.1", + "eslint-plugin-jsx-a11y": "^6.7.1", + "eslint-plugin-react": "^7.33.2", + "eslint-plugin-react-hooks": "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705" + }, + "peerDependencies": { + "eslint": "^7.23.0 || ^8.0.0", + "typescript": ">=3.3.1" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", + "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "enhanced-resolve": "^5.12.0", + "eslint-module-utils": "^2.7.4", + "fast-glob": "^3.3.1", + "get-tsconfig": "^4.5.0", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz", + "integrity": "sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.23.2", + "aria-query": "^5.3.0", + "array-includes": "^3.1.7", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "=4.7.0", + "axobject-query": "^3.2.1", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "es-iterator-helpers": "^1.0.15", + "hasown": "^2.0.0", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.entries": "^1.1.7", + "object.fromentries": "^2.0.7" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.34.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.1.tgz", + "integrity": "sha512-N97CxlouPT1AHt8Jn0mhhN2RrADlUAsk1/atcT2KyA/l9Q/E6ll7OIGwNumFmWfZ9skV3XXccYS19h80rHtgkw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.7", + "array.prototype.findlast": "^1.2.4", + "array.prototype.flatmap": "^1.3.2", + "array.prototype.toreversed": "^1.1.2", + "array.prototype.tosorted": "^1.1.3", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.0.17", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.7", + "object.fromentries": "^2.0.7", + "object.hasown": "^1.1.3", + "object.values": "^1.1.7", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.10" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", + "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fast-shallow-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-shallow-equal/-/fast-shallow-equal-1.0.0.tgz", + "integrity": "sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==" + }, + "node_modules/fastest-stable-stringify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fastest-stable-stringify/-/fastest-stable-stringify-2.0.2.tgz", + "integrity": "sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==", + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "optional": true, + "peer": true + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/foreground-child": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "devOptional": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz", + "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==", + "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true + }, + "node_modules/goober": { + "version": "2.1.13", + "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.13.tgz", + "integrity": "sha512-jFj3BQeleOoy7t93E9rZ2de+ScC4lQICLwiAQmKMg9F6roKGaLSHoCDYKkWlSafg138jejvq/mTdvmnwDQgqoQ==", + "peerDependencies": { + "csstype": "^3.0.10" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "devOptional": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "optional": true, + "peer": true, + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^3.1.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/html-parse-stringify": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", + "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", + "dependencies": { + "void-elements": "3.1.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/hyphenate-style-name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz", + "integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==", + "license": "BSD-3-Clause" + }, + "node_modules/i18next": { + "version": "23.12.2", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.12.2.tgz", + "integrity": "sha512-XIeh5V+bi8SJSWGL3jqbTEBW5oD6rbP5L+E7dVQh1MNTxxYef0x15rhJVcRb7oiuq4jLtgy2SD8eFlf6P2cmqg==", + "funding": [ + { + "type": "individual", + "url": "https://locize.com" + }, + { + "type": "individual", + "url": "https://locize.com/i18next.html" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + } + ], + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.2" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "devOptional": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/inline-style-prefixer": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-7.0.1.tgz", + "integrity": "sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw==", + "license": "MIT", + "dependencies": { + "css-in-js-utils": "^3.1.0" + } + }, + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "optional": true, + "peer": true + }, + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "devOptional": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", + "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz", + "integrity": "sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/iterator.prototype": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", + "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + } + }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/jest-cli": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-config/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-diff/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/jest-docblock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-leak-detector/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-leak-detector/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-leak-detector/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime/node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/jest-watcher": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-cookie": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", + "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==", + "license": "MIT" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdom": { + "version": "24.1.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.1.tgz", + "integrity": "sha512-5O1wWV99Jhq4DV7rCLIoZ/UIhyQeDR7wHVyZAHAshbrvZsLs+Xzz7gtwnlJTJDjleiTKh54F4dXrX70vJQTyJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssstyle": "^4.0.1", + "data-urls": "^5.0.0", + "decimal.js": "^10.4.3", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.12", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.7.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.4", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "canvas": "^2.11.2" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/rrweb-cssom": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", + "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "optional": true, + "peer": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "dev": true + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "optional": true, + "peer": true + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/loupe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", + "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "peer": true, + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "license": "CC0-1.0" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/monaco-editor": { + "version": "0.49.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.49.0.tgz", + "integrity": "sha512-2I8/T3X/hLxB2oPHgqcNYUVdA/ZEFShT7IAujifIPMfKkNbLOqY8XCoyHCXrsdjb36dW9MwoTwBCFpXKMwNwaQ==", + "peer": true + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nano-css": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/nano-css/-/nano-css-5.6.2.tgz", + "integrity": "sha512-+6bHaC8dSDGALM1HJjOHVXpuastdu2xFoZlC77Jh4cg+33Zcgm+Gxd+1xsnpZK14eyHObSp82+ll5y3SX75liw==", + "license": "Unlicense", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15", + "css-tree": "^1.1.2", + "csstype": "^3.1.2", + "fastest-stable-stringify": "^2.0.2", + "inline-style-prefixer": "^7.0.1", + "rtl-css-js": "^1.16.1", + "stacktrace-js": "^2.0.2", + "stylis": "^4.3.0" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/nano-css/node_modules/stylis": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", + "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/next": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/next/-/next-14.2.5.tgz", + "integrity": "sha512-0f8aRfBVL+mpzfBjYfQuLWh2WyAwtJXCRfkPF4UJ5qd2YwrHczsrSzXU4tRMV0OAxR8ZJZWPFn6uhSC56UTsLA==", + "license": "MIT", + "dependencies": { + "@next/env": "14.2.5", + "@swc/helpers": "0.5.5", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001579", + "graceful-fs": "^4.2.11", + "postcss": "8.4.31", + "styled-jsx": "5.1.1" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=18.17.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "14.2.5", + "@next/swc-darwin-x64": "14.2.5", + "@next/swc-linux-arm64-gnu": "14.2.5", + "@next/swc-linux-arm64-musl": "14.2.5", + "@next/swc-linux-x64-gnu": "14.2.5", + "@next/swc-linux-x64-musl": "14.2.5", + "@next/swc-win32-arm64-msvc": "14.2.5", + "@next/swc-win32-ia32-msvc": "14.2.5", + "@next/swc-win32-x64-msvc": "14.2.5" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.41.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/node-releases": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/notistack": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/notistack/-/notistack-3.0.1.tgz", + "integrity": "sha512-ntVZXXgSQH5WYfyU+3HfcXuKaapzAJ8fBLQ/G618rn3yvSzEbnOB8ZSOwhX+dAORy/lw+GC2N061JA0+gYWTVA==", + "dependencies": { + "clsx": "^1.1.0", + "goober": "^2.0.33" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/notistack" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/notistack/node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nwsapi": { + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.12.tgz", + "integrity": "sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.hasown": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz", + "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "devOptional": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "optional": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dev": true, + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "devOptional": true + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "devOptional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/pretty-format/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "peer": true + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true, + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pure-rand": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", + "integrity": "sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "optional": true, + "peer": true + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-hook-form": { + "version": "7.52.1", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.52.1.tgz", + "integrity": "sha512-uNKIhaoICJ5KQALYZ4TOaOLElyM+xipord+Ha3crEFhTntdLvWZqVY49Wqd/0GiVCA/f9NjemLeiNPjG7Hpurg==", + "license": "MIT", + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18 || ^19" + } + }, + "node_modules/react-i18next": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.0.0.tgz", + "integrity": "sha512-2O3IgF4zivg57Q6p6i+ChDgJ371IDcEWbuWC6gvoh5NbkDMs0Q+O7RPr4v61+Se32E0V+LmtwePAeqWZW0bi6g==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.24.8", + "html-parse-stringify": "^3.0.1" + }, + "peerDependencies": { + "i18next": ">= 23.2.3", + "react": ">= 16.8.0" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/react-universal-interface": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/react-universal-interface/-/react-universal-interface-0.6.2.tgz", + "integrity": "sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==", + "peerDependencies": { + "react": "*", + "tslib": "*" + } + }, + "node_modules/react-use": { + "version": "17.5.1", + "resolved": "https://registry.npmjs.org/react-use/-/react-use-17.5.1.tgz", + "integrity": "sha512-LG/uPEVRflLWMwi3j/sZqR00nF6JGqTTDblkXK2nzXsIvij06hXl1V/MZIlwj1OKIQUtlh1l9jK8gLsRyCQxMg==", + "license": "Unlicense", + "dependencies": { + "@types/js-cookie": "^2.2.6", + "@xobotyi/scrollbar-width": "^1.9.5", + "copy-to-clipboard": "^3.3.1", + "fast-deep-equal": "^3.1.3", + "fast-shallow-equal": "^1.0.0", + "js-cookie": "^2.2.1", + "nano-css": "^5.6.2", + "react-universal-interface": "^0.6.2", + "resize-observer-polyfill": "^1.5.1", + "screenfull": "^5.1.0", + "set-harmonic-interval": "^1.0.1", + "throttle-debounce": "^3.0.1", + "ts-easing": "^0.2.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", + "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.1", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==", + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.6", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz", + "integrity": "sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==", + "devOptional": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "devOptional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz", + "integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^11.0.0", + "package-json-from-dist": "^1.0.0" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", + "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^4.0.1", + "minimatch": "^10.0.0", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/jackspeak": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.1.tgz", + "integrity": "sha512-cub8rahkh0Q/bw1+GxP7aeSe29hHHn2V4m29nnDlvCdlgU+3UGxkZp7Z53jLUdpX3jdTO0nJZUDl3xvbWc2Xog==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/rimraf/node_modules/lru-cache": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.0.tgz", + "integrity": "sha512-Qv32eSV1RSCfhY3fpPE2GNZ8jgM9X7rdAfemLWqTUxwiyIC4jJ6Sy0fZ8H+oLWevO6i4/bizg7c8d8i6bxrzbA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/path-scurry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", + "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@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.2" + } + }, + "node_modules/rrweb-cssom": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", + "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", + "dev": true + }, + "node_modules/rtl-css-js": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.16.1.tgz", + "integrity": "sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.1.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/screenfull": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/screenfull/-/screenfull-5.2.0.tgz", + "integrity": "sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-harmonic-interval": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-harmonic-interval/-/set-harmonic-interval-1.0.1.tgz", + "integrity": "sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g==", + "license": "Unlicense", + "engines": { + "node": ">=6.9" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/stack-generator": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/stack-generator/-/stack-generator-2.0.10.tgz", + "integrity": "sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==", + "license": "MIT", + "dependencies": { + "stackframe": "^1.3.4" + } + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/stackframe": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==", + "license": "MIT" + }, + "node_modules/stacktrace-gps": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/stacktrace-gps/-/stacktrace-gps-3.1.2.tgz", + "integrity": "sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ==", + "license": "MIT", + "dependencies": { + "source-map": "0.5.6", + "stackframe": "^1.3.4" + } + }, + "node_modules/stacktrace-gps/node_modules/source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stacktrace-js": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stacktrace-js/-/stacktrace-js-2.0.2.tgz", + "integrity": "sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==", + "license": "MIT", + "dependencies": { + "error-stack-parser": "^2.0.6", + "stack-generator": "^2.0.5", + "stacktrace-gps": "^3.0.4" + } + }, + "node_modules/state-local": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", + "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==" + }, + "node_modules/std-env": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", + "dev": true + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", + "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "regexp.prototype.flags": "^1.5.2", + "set-function-name": "^2.0.2", + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", + "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "devOptional": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tauri-plugin-autostart-api": { + "version": "0.0.0", + "resolved": "git+ssh://git@github.com/tauri-apps/tauri-plugin-autostart.git#1e02acce1b4bb5ee461f7670012d7d105a13be4c", + "license": "MIT or APACHE-2.0", + "dependencies": { + "@tauri-apps/api": "1.6.0" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/throttle-debounce": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-3.0.1.tgz", + "integrity": "sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/tinybench": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", + "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==", + "dev": true + }, + "node_modules/tinypool": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.0.tgz", + "integrity": "sha512-KIKExllK7jp3uvrNtvRBYBWBOAXSX8ZvoaD8T+7KB/QHIuoJW3Pmr60zucywjAlMb5TeXUkcs/MWeWLu0qvuAQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.0.tgz", + "integrity": "sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "optional": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==", + "license": "MIT" + }, + "node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", + "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "dev": true, + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/ts-easing": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/ts-easing/-/ts-easing-0.2.0.tgz", + "integrity": "sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==", + "license": "Unlicense" + }, + "node_modules/tsconfck": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.0.3.tgz", + "integrity": "sha512-4t0noZX9t6GcPTfBAbIbbIU4pfpCwh0ueq3S4O/5qXI1VwK1outmxhe9dOiEWqMz3MW2LKgDTpqWV+37IWuVbA==", + "dev": true, + "bin": { + "tsconfck": "bin/tsconfck.js" + }, + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "optional": true, + "peer": true, + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/v8-to-istanbul": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.3.tgz", + "integrity": "sha512-9lDD+EVI2fjFsMWXc6dy5JJzBsVTcQ2fVkfBvncZ6xJWG9wtBhOldG+mHkSL0+V1K/xgZz0JDO5UT5hFwHUghg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/vite": { + "version": "5.2.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz", + "integrity": "sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==", + "dev": true, + "dependencies": { + "esbuild": "^0.20.1", + "postcss": "^8.4.38", + "rollup": "^4.13.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.0.4.tgz", + "integrity": "sha512-ZpJVkxcakYtig5iakNeL7N3trufe3M6vGuzYAr4GsbCTwobDeyPJpE4cjDhhPluv8OvQCFzu2LWp6GkoKRITXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.5", + "pathe": "^1.1.2", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite-tsconfig-paths": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-4.3.2.tgz", + "integrity": "sha512-0Vd/a6po6Q+86rPlntHye7F31zA2URZMbH8M3saAZ/xR9QoGN/L21bxEGfXdWmFdNkqPpRdxFT7nmNe12e9/uA==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "globrex": "^0.1.2", + "tsconfck": "^3.0.3" + }, + "peerDependencies": { + "vite": "*" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/vitest": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.0.4.tgz", + "integrity": "sha512-luNLDpfsnxw5QSW4bISPe6tkxVvv5wn2BBs/PuDRkhXZ319doZyLOBr1sjfB5yCEpTiU7xCAdViM8TNVGPwoog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "@vitest/expect": "2.0.4", + "@vitest/pretty-format": "^2.0.4", + "@vitest/runner": "2.0.4", + "@vitest/snapshot": "2.0.4", + "@vitest/spy": "2.0.4", + "@vitest/utils": "2.0.4", + "chai": "^5.1.1", + "debug": "^4.3.5", + "execa": "^8.0.1", + "magic-string": "^0.30.10", + "pathe": "^1.1.2", + "std-env": "^3.7.0", + "tinybench": "^2.8.0", + "tinypool": "^1.0.0", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0", + "vite-node": "2.0.4", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "2.0.4", + "@vitest/ui": "2.0.4", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/vitest/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vitest/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/vitest/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vitest/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vitest/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vitest/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vitest/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vitest/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dev": true, + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", + "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", + "dev": true, + "dependencies": { + "tr46": "^5.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", + "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "dev": true, + "dependencies": { + "function.prototype.name": "^1.1.5", + "has-tostringtag": "^1.0.0", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "optional": true, + "peer": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..2e5c86f --- /dev/null +++ b/package.json @@ -0,0 +1,60 @@ +{ + "name": "bluetooth-battery-monitor", + "version": "0.3.0", + "license": "MIT", + "homepage": "https://github.com/SARDONYX-sard/bluetooth-battery-monitor", + "private": true, + "type": "module", + "scripts": { + "dev": "tauri dev", + "dev:front": "next ./gui/frontend", + "build": "rimraf ./gui/frontend/out && tauri build", + "build:front": "next build ./gui/frontend", + "build:icons": "cargo tauri icon ./gui/backend/icons/icon.png", + "test": "vitest run", + "test:back": " cargo test --workspace", + "test:all": "npm test && npm run test:back", + "fmt": "biome format ./ && prettier --cache --write \"**/*.+(yml|yaml)\" --ignore-path ./.gitignore && cargo fmt --all", + "lint": "next lint ./gui/frontend && biome lint ./ && cargo clippy --workspace", + "lint:fix": "npm run fmt && next lint ./gui/frontend --fix && biome check --write ./ && cargo clippy --workspace --fix --allow-staged --allow-dirty", + "tauri": "tauri" + }, + "dependencies": { + "@monaco-editor/react": "^4.6.0", + "@mui/icons-material": "^5.16.4", + "@mui/lab": "5.0.0-alpha.170", + "@mui/material": "^5.16.4", + "@tauri-apps/api": "^1.6.0", + "i18next": "^23.12.2", + "next": "14.2.5", + "notistack": "^3.0.1", + "react": "18.3.1", + "react-dom": "18.3.1", + "react-hook-form": "^7.52.1", + "react-i18next": "^15.0.0", + "react-use": "^17.5.1", + "tauri-plugin-autostart-api": "github:tauri-apps/tauri-plugin-autostart#v1" + }, + "devDependencies": { + "@biomejs/biome": "1.8.3", + "@tauri-apps/cli": "^1.6.0", + "@testing-library/jest-dom": "^6.4.7", + "@testing-library/react": "^16.0.0", + "@types/node": "20.14.11", + "@types/react": "18.3.3", + "@types/react-dom": "18.3.0", + "@vitejs/plugin-react-swc": "^3.7.0", + "eslint": "^8.57.0", + "eslint-config-next": "14.2.5", + "jsdom": "^24.1.1", + "prettier": "^3.3.3", + "rimraf": "^6.0.1", + "typescript": "5.5.4", + "vite-tsconfig-paths": "^4.3.2", + "vitest": "2.0.4" + }, + "overrides": { + "monaco-editor": "^0.49.0" + }, + "packageManager": "npm@10.8.1" +} diff --git a/readme.md b/readme.md index 304ac48..02be39a 100644 --- a/readme.md +++ b/readme.md @@ -1,62 +1,128 @@ -# Bluetooth battery monitor +# Bluetooth Battery Monitor + +

- bluetooth battery monitor icon + bluetooth battery monitor icon

-## Supported Features +![index](https://github.com/user-attachments/assets/4b09ce2a-40b9-424c-8f5c-cb716d2771da) +![settings](https://github.com/user-attachments/assets/09d9ac9f-df5d-4736-8bc2-f32d27d0c099) -- [x] Bluetooth classic device search -- [x] Battery information acquisition for Bluetooth classic -- [x] Autostart at PC startup -- [x] Battery information acquisition interval setting -- [x] CSS customization - -## Features to be implemented - -- [ ] Support pages including links to source code pages, license information, version information, etc. -- [ ] Abundant CSS options -- [ ] Localization - -## Unsupported Features - -- Reason: the author does not have a supported device. - -- [ ] Bluetooth LE device search -- [ ] Battery information acquisition for Bluetooth LE +## Getting Started for User -![Bluetooth battery monitor GUI](https://user-images.githubusercontent.com/68905624/233191197-0c2906b7-c823-41dc-a417-11abac34474e.png) +- [Release Page](https://github.com/SARDONYX-sard/bluetooth-battery-monitor/releases) -![settings page](https://user-images.githubusercontent.com/68905624/233191832-4e314825-0b5b-484d-baeb-7c0d3dbdaee9.png) +1. When the application is launched, an icon will appear on the taskbar. -## Development & Build +2. When the Bluetooth Classic battery information is successfully acquired, the icon will switch to battery reporting. -- `src-tauri`: Rust backend -- `www`: Web frontend -- `bundle.ts`: Script to bundle your frontend +3. The icon will change according to the battery %. -Prerequisites: +## Features -- [Rust](https://www.rust-lang.org/) -- [Deno](https://deno.land/) -- [Tauri](https://tauri.studio/v1/guides/getting-started/beginning-tutorial#alternatively-install-tauri-cli-as-a-cargo-subcommand) -- [Tauri os-specific dependencies](https://tauri.studio/v1/guides/getting-started/prerequisites#installing) +- [x] Search Bluetooth(Classic) battery info -Development: - -| Command | Explain | -| :--------- | :----------: | -| make dev | Development | -| make build | Building | -| make fmt | Formatting | -| make lint | Linting | - -And Consider to read the following documentations. - -- [Code of Conduct](./CODE_OF_CONDUCT.md) -- [Guidelines for contribution](./CONTRIBUTING.md) - -## License +- [x] Autostart at PC startup +- [x] Localization(could be customized) +- [x] Custom edit JavaScript & CSS + +## UnSupported Features(I does not have a supported device.) + +- ☒ Bluetooth LE device search +- ☒ Battery information acquisition for Bluetooth LE + +## Wiki + +- If you want to change the design: `Settings` page -> `Editor/Preset` tab -> Click `Preset1` + +- background image randomization(NOTE: Script execution is at your own risk.) + +1. `Settings` page -> `Editor/Preset` tab -> Click `Preset1` +2. Click `JS Auto run` button +3. Copy this code. + +```javascript +//@ts-check +(() => { + const preset1 = ` + --autofill-color: #691c3747; + --convert-btn-color: #ab2b7e6e; + --error-color: #ff1655; + --hover-btn-color: #ff89898b; + --hover-convert-btn-color: #fd3b3b6e; + --theme-color: #ff8e16;`; + const preset2 = ` + --autofill-color: #5eb1ef24; + --convert-btn-color: #3369ad7d; + --hover-btn-color: #1d5aa58b; + --hover-convert-btn-color: #2665b5d1; + --theme-color: #5a9ab9;`; + const preset4 = ` + --autofill-color: #a19c0038; + --convert-btn-color: #94ce7c6e; + --hover-btn-color: #cefb518b; + --hover-convert-btn-color: #81c462a3; + --main-bg-color: #222a; + --theme-color: rgb(185, 185, 90);`; + + let preset =/** @type{const} */ preset2; + const getRandomUrl = () => { + const imgNumList = [1543801, 1547163, 4589833, 7325003, 14133639]; + + const imgNum = imgNumList[Math.floor(Math.random() * imgNumList.length)]; + if ([1547163, 14133639].includes(imgNum)) { + preset = preset1; + } else if ([4589833, 7325003].includes(imgNum)) { + preset = preset4; + } + return `https://images.pexels.com/photos/${imgNum}/pexels-photo-${imgNum}.jpeg`; + }; + + const img = getRandomUrl(); + // Change the background on each page.(JS is executed every time, so the same variable is fine.) + dynImg(/** index */ img, /** settings */ img); + + /** + * Change the background on each page. + * @param {string} indexUrl - Image URI of index(converter) page + * @param {string} settingsUrl - Image URI of settings page + */ + function dynImg(indexUrl, settingsUrl) { + const commonVariables = ` + --image-position-x: center; + --image-position-y: center; + --image-size: cover; + --main-bg-color: #222a; + ${preset} +`; + const style = document.getElementById('dyn-style') ?? document.createElement('style'); + style.id = 'dyn-style'; + const currentPage = window.location.pathname; + if (currentPage === '/') { + style.innerHTML = `:root { ${commonVariables} --image-url: url('${indexUrl}'); }`; + } else if (currentPage === '/settings') { + style.innerHTML = `:root { ${commonVariables} --image-url: url('${settingsUrl}'); }`; + } + document.body.appendChild(style); + } +})(); +``` + +## Licenses Licensed under either of @@ -64,5 +130,3 @@ Licensed under either of ([LICENSE-APACHE](LICENSE-APACHE) or ) - MIT license ([LICENSE-MIT](LICENSE-MIT) or ) - -at your option. diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml deleted file mode 100644 index c0a739e..0000000 --- a/src-tauri/Cargo.toml +++ /dev/null @@ -1,49 +0,0 @@ -[package] -name = "bluetooth-battery-monitor" -version = "0.3.0" -description = "Deno + Tauri app" -edition = "2021" -build = "src/build.rs" - -[build-dependencies] -tauri-build = { version = "1.2.1", features = [] } - -[dependencies] -anyhow = { version = "1.0.70" } -bincode = { version = "1.3.3" } -env_logger = { version = "0.10.0" } -log = { version = "0.4.17" } -once_cell = { version = "1.17.1" } -serde = { version = "1.0.156", features = ["derive"] } -serde_json = { version = "1.0.95" } -tauri = { version = "1.3.0", features = [ - "api-all", - "icon-ico", - "icon-png", - "system-tray", -] } -tauri-plugin-autostart = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "dev" } -tauri-plugin-window-state = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "dev" } -tokio = { version = "1.27.0", features = ["time", "sync"] } -toml = { version = "0.7.3" } - -[target.'cfg(windows)'.dependencies] -windows = { version = "0.48.0", features = [ - "Devices_Bluetooth_Rfcomm", - "Devices_Enumeration", - "Foundation", - "Foundation_Collections", - "Networking_Proximity", - "Win32_Devices_Bluetooth", - "Win32_Foundation", - "Win32_Networking_WinSock", - "Win32_System_Rpc", - "Win32_System_Threading", -] } - -[dev-dependencies] -tokio = { version = "1.27.0", features = ["time", "macros", "rt"] } - -[features] -default = ["custom-protocol"] -custom-protocol = ["tauri/custom-protocol"] diff --git a/src-tauri/icons/128x128.png b/src-tauri/icons/128x128.png deleted file mode 100644 index 67f8ccc..0000000 Binary files a/src-tauri/icons/128x128.png and /dev/null differ diff --git a/src-tauri/icons/128x128@2x.png b/src-tauri/icons/128x128@2x.png deleted file mode 100644 index ad4076d..0000000 Binary files a/src-tauri/icons/128x128@2x.png and /dev/null differ diff --git a/src-tauri/icons/32x32.png b/src-tauri/icons/32x32.png deleted file mode 100644 index f51d342..0000000 Binary files a/src-tauri/icons/32x32.png and /dev/null differ diff --git a/src-tauri/icons/Square107x107Logo.png b/src-tauri/icons/Square107x107Logo.png deleted file mode 100644 index 8f52365..0000000 Binary files a/src-tauri/icons/Square107x107Logo.png and /dev/null differ diff --git a/src-tauri/icons/Square142x142Logo.png b/src-tauri/icons/Square142x142Logo.png deleted file mode 100644 index 461728b..0000000 Binary files a/src-tauri/icons/Square142x142Logo.png and /dev/null differ diff --git a/src-tauri/icons/Square150x150Logo.png b/src-tauri/icons/Square150x150Logo.png deleted file mode 100644 index 2f644c3..0000000 Binary files a/src-tauri/icons/Square150x150Logo.png and /dev/null differ diff --git a/src-tauri/icons/Square284x284Logo.png b/src-tauri/icons/Square284x284Logo.png deleted file mode 100644 index 2070e8e..0000000 Binary files a/src-tauri/icons/Square284x284Logo.png and /dev/null differ diff --git a/src-tauri/icons/Square30x30Logo.png b/src-tauri/icons/Square30x30Logo.png deleted file mode 100644 index 8393bb9..0000000 Binary files a/src-tauri/icons/Square30x30Logo.png and /dev/null differ diff --git a/src-tauri/icons/Square310x310Logo.png b/src-tauri/icons/Square310x310Logo.png deleted file mode 100644 index 7d36d4b..0000000 Binary files a/src-tauri/icons/Square310x310Logo.png and /dev/null differ diff --git a/src-tauri/icons/Square44x44Logo.png b/src-tauri/icons/Square44x44Logo.png deleted file mode 100644 index 8dec532..0000000 Binary files a/src-tauri/icons/Square44x44Logo.png and /dev/null differ diff --git a/src-tauri/icons/Square71x71Logo.png b/src-tauri/icons/Square71x71Logo.png deleted file mode 100644 index fd37dad..0000000 Binary files a/src-tauri/icons/Square71x71Logo.png and /dev/null differ diff --git a/src-tauri/icons/Square89x89Logo.png b/src-tauri/icons/Square89x89Logo.png deleted file mode 100644 index 6a7c49e..0000000 Binary files a/src-tauri/icons/Square89x89Logo.png and /dev/null differ diff --git a/src-tauri/icons/StoreLogo.png b/src-tauri/icons/StoreLogo.png deleted file mode 100644 index 8630a52..0000000 Binary files a/src-tauri/icons/StoreLogo.png and /dev/null differ diff --git a/src-tauri/icons/battery/battery-0.png b/src-tauri/icons/battery/battery-0.png deleted file mode 100644 index 3c24d8a..0000000 Binary files a/src-tauri/icons/battery/battery-0.png and /dev/null differ diff --git a/src-tauri/icons/battery/battery-10.png b/src-tauri/icons/battery/battery-10.png deleted file mode 100644 index 982c2e7..0000000 Binary files a/src-tauri/icons/battery/battery-10.png and /dev/null differ diff --git a/src-tauri/icons/battery/battery-100.png b/src-tauri/icons/battery/battery-100.png deleted file mode 100644 index c6ff251..0000000 Binary files a/src-tauri/icons/battery/battery-100.png and /dev/null differ diff --git a/src-tauri/icons/battery/battery-20.png b/src-tauri/icons/battery/battery-20.png deleted file mode 100644 index 758c4f8..0000000 Binary files a/src-tauri/icons/battery/battery-20.png and /dev/null differ diff --git a/src-tauri/icons/battery/battery-30.png b/src-tauri/icons/battery/battery-30.png deleted file mode 100644 index ff36aa3..0000000 Binary files a/src-tauri/icons/battery/battery-30.png and /dev/null differ diff --git a/src-tauri/icons/battery/battery-40.png b/src-tauri/icons/battery/battery-40.png deleted file mode 100644 index d9c0a0f..0000000 Binary files a/src-tauri/icons/battery/battery-40.png and /dev/null differ diff --git a/src-tauri/icons/battery/battery-50.png b/src-tauri/icons/battery/battery-50.png deleted file mode 100644 index e99930f..0000000 Binary files a/src-tauri/icons/battery/battery-50.png and /dev/null differ diff --git a/src-tauri/icons/battery/battery-60.png b/src-tauri/icons/battery/battery-60.png deleted file mode 100644 index 2eb4665..0000000 Binary files a/src-tauri/icons/battery/battery-60.png and /dev/null differ diff --git a/src-tauri/icons/battery/battery-70.png b/src-tauri/icons/battery/battery-70.png deleted file mode 100644 index 5207111..0000000 Binary files a/src-tauri/icons/battery/battery-70.png and /dev/null differ diff --git a/src-tauri/icons/battery/battery-80.png b/src-tauri/icons/battery/battery-80.png deleted file mode 100644 index 87d89d3..0000000 Binary files a/src-tauri/icons/battery/battery-80.png and /dev/null differ diff --git a/src-tauri/icons/battery/battery-90.png b/src-tauri/icons/battery/battery-90.png deleted file mode 100644 index 2b153e6..0000000 Binary files a/src-tauri/icons/battery/battery-90.png and /dev/null differ diff --git a/src-tauri/icons/icon.icns b/src-tauri/icons/icon.icns deleted file mode 100644 index 390b546..0000000 Binary files a/src-tauri/icons/icon.icns and /dev/null differ diff --git a/src-tauri/icons/icon.ico b/src-tauri/icons/icon.ico deleted file mode 100644 index 31a69cd..0000000 Binary files a/src-tauri/icons/icon.ico and /dev/null differ diff --git a/src-tauri/icons/icon.png b/src-tauri/icons/icon.png deleted file mode 100644 index e8d51d0..0000000 Binary files a/src-tauri/icons/icon.png and /dev/null differ diff --git a/src-tauri/scripts/get-bluetooth-battery.ps1 b/src-tauri/scripts/get-bluetooth-battery.ps1 deleted file mode 100644 index 4413d03..0000000 --- a/src-tauri/scripts/get-bluetooth-battery.ps1 +++ /dev/null @@ -1,23 +0,0 @@ -# Param( -# [string]$InstanceId = "BTHENUM\{0000111E-0000-1000-8000-00805F9B34FB}_LOCALMFG&005D\7&2CDD7520&0&9C431E0131A6_C00000000" -# ) -$local:BatteryLevel = "{104EA319-6EE2-4701-BD47-8DDBF425BBE5} 2" -$local:BluetoothAddressId = "DEVPKEY_Bluetooth_DeviceAddress" -$local:friendlyName = "DEVPKEY_Device_FriendlyName" - -$local:Properties = @{ "instance_id" = $InstanceId }; -Get-PnpDeviceProperty -InstanceId $InstanceId -KeyName $local:BatteryLevel, $local:BluetoothAddressId, $local:friendlyName | -ForEach-Object { - $local:data = $_.Data #! Note: Need local variable! otherwise it will be null. - $local:keyname = $_.KeyName - - switch ($keyName) { - $local:BatteryLevel { $local:keyname = "battery_level" } - $local:BluetoothAddressId { $local:keyname = "bluetooth_address" } - $local:friendlyName { $local:keyname = "friendly_name" } - } - $local:Properties += @{ $local:keyname = $local:data } -} -ConvertTo-Json -InputObject $local:Properties - -# Read-Host "Press any key." diff --git a/src-tauri/src/bluetooth/common.rs b/src-tauri/src/bluetooth/common.rs deleted file mode 100644 index a8054eb..0000000 --- a/src-tauri/src/bluetooth/common.rs +++ /dev/null @@ -1,244 +0,0 @@ -use std::fmt::Display; - -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, Serialize, Deserialize)] -/// Bluetooth device information Json -pub struct BluetoothDeviceInfo { - pub class_of_device: String, - pub bluetooth_address: String, - pub is_connected: bool, - pub is_remembered: bool, - pub is_authenticated: bool, - pub last_seen: SystemTime, - pub last_used: SystemTime, - pub device_name: String, -} - -#[derive(Debug, Clone)] -pub struct BluetoothClass(u32); - -impl From for BluetoothClass { - fn from(value: u32) -> Self { - Self(value) - } -} - -impl From for u32 { - fn from(bt_class: BluetoothClass) -> u32 { - bt_class.0 - } -} - -/// Bluetooth major category -const CC: [&str; 10] = [ - "Miscellaneous", - "Computer", - "Phone", - "LAN/Network Access Point", - "Audio/Video", - "Peripheral", - "Imaging", - "Wearable", - "Toy", - "Health", -]; - -/// Bluetooth sub category 4 -const CC4: [&str; 19] = [ - "Uncategorized", - "Wearable Headset Device", - "Hands-free Device", - "(Reserved)", - "Microphone", - "Loudspeaker", - "Headphones", - "Portable Audio", - "Car audio", - "Set-top box", - "HiFi Audio Device", - "VCR", - "Video Camera", - "Camcorder", - "Video Monitor", - "Video Display and Loudspeaker", - "Video Conferencing", - "(Reserved)", - "Gaming/Toy", -]; - -/// Bluetooth sub category 5 -const CC5: [&str; 4] = ["Unknown", "Keyboard", "Mouse", "Keyboard/Mouse Combo"]; - -impl TryFrom<&str> for BluetoothClass { - type Error = &'static str; - - fn try_from(input: &str) -> Result { - for (major, category) in CC.iter().enumerate() { - if input.starts_with(category) { - let sub = input - .strip_prefix(category) - .map(|s| s.trim().replace(": ", "")); - - let minor = match major { - 4 => CC4 - .iter() - .position(|x| { - trace!("Try from sub: {sub:?}, x:{x}"); - sub == Some(x.to_string()) - }) - .unwrap(), - 5 => { - let sub_major = - CC5.iter().position(|x| sub == Some(x.to_string())).unwrap(); - sub_major << 4 - } - _ => return Err("Unknown"), - }; - let cod = ((major & 0x1f) << 8) | ((minor & 0x3f) << 2); - return Ok(BluetoothClass::from(cod as u32)); - } - } - - Err("Unknown") - } -} - -impl Display for BluetoothClass { - /// This code is converted from C++. - /// See: https://github.com/joric/bluetooth-battery-monitor/blob/master/misc/bt_classic_test.cpp#L6 - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let cod = self.0 as usize; - let major = (cod >> 8) & 0x1f; - let minor = (cod >> 2) & 0x3f; - let cc_count = CC.len(); - let cat = if major < cc_count { - CC[major] - } else { - "Unknown" - }; - let sub = match major { - 4 => Some(CC4[minor]), - 5 => Some(CC5[minor >> 4]), - _ => None, - }; - if let Some(sub_class) = sub { - write!(f, "{}: {}", cat, sub_class) - } else { - write!(f, "{}", cat) - } - } -} - -/// Network byte order(Big endian) u64 -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct BluetoothAddress(u64); - -pub enum ByteOrder { - BigEndian, - LittleEndian, -} - -impl BluetoothAddress { - /// Convert from big endian address to hex string representation. - /// - /// e.g. BigEndian: [0xcc, 0xbb, 0xaa, 0x22, 0x11, 0x00] => "001122aabbcc" - /// e.g. LittleEndian: [0xcc, 0xbb, 0xaa, 0x22, 0x11, 0x00] => "ccbbaa221100" - pub fn as_hex_string(&self) -> String { - self.as_hex_string_with_colon(ByteOrder::BigEndian) - .replace(':', "") - } - - /// Convert from big endian address to hex string with colon representation. - /// - /// e.g. [0xcc, 0xbb, 0xaa, 0x22, 0x11, 0x00] => "00:11:22:aa:bb:cc" - pub fn as_hex_string_with_colon(&self, byte_order: ByteOrder) -> String { - let rg_bytes: [u8; 6] = (*self).clone().into(); - match byte_order { - ByteOrder::BigEndian => format!( - "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}", - rg_bytes[0], rg_bytes[1], rg_bytes[2], rg_bytes[3], rg_bytes[4], rg_bytes[5], - ), - ByteOrder::LittleEndian => format!( - "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}", - rg_bytes[5], rg_bytes[4], rg_bytes[3], rg_bytes[2], rg_bytes[1], rg_bytes[0], - ), - } - } -} - -impl Display for BluetoothAddress { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "{}", - self.as_hex_string_with_colon(ByteOrder::LittleEndian) - ) - } -} - -impl From for BluetoothAddress { - fn from(value: u64) -> Self { - BluetoothAddress(value) - } -} - -impl From for u64 { - fn from(bt_addr: BluetoothAddress) -> Self { - bt_addr.0 - } -} - -impl From<[u8; 6]> for BluetoothAddress { - fn from(slice: [u8; 6]) -> Self { - let mut result: u64 = 0; - for (i, byte) in slice.iter().enumerate() { - result |= (u64::from(*byte)) << ((5 - i) * 8); - } - Self(result) - } -} - -impl From for [u8; 6] { - fn from(address: BluetoothAddress) -> Self { - let mut result = [0u8; 6]; - for i in 0..6 { - result[5 - i] = ((address.0 >> (i * 8)) & 0xFF) as u8; - } - result - } -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct SystemTime { - pub year: u16, - pub month: u16, - pub day_of_week: u16, - pub day: u16, - pub hour: u16, - pub minute: u16, - pub second: u16, - pub milliseconds: u16, -} - -#[cfg(test)] -mod tests { - use super::BluetoothClass; - - #[test] - fn should_parse_class_num_to_name() { - let bt_class_num = 2360324; - let class_name = BluetoothClass::from(bt_class_num).to_string(); - assert_eq!(class_name, "Audio/Video: Wearable Headset Device"); - } - - #[test] - fn should_parse_class_name_to_num_to_name() { - let bt_class_str = "Audio/Video: Wearable Headset Device"; - - let bt_class = BluetoothClass::try_from(bt_class_str).unwrap(); - dbg!(bt_class.0); - let class_name = BluetoothClass::from(bt_class.0).to_string(); - assert_eq!(class_name, bt_class_str); - } -} diff --git a/src-tauri/src/bluetooth/mod.rs b/src-tauri/src/bluetooth/mod.rs deleted file mode 100644 index 4967e30..0000000 --- a/src-tauri/src/bluetooth/mod.rs +++ /dev/null @@ -1,20 +0,0 @@ -mod common; -#[cfg(target_os = "windows")] -pub mod windows; - -#[cfg(target_os = "windows")] -pub use self::windows as sys; - -#[cfg(test)] -mod tests { - use crate::bluetooth::sys::get_bluetooth_info_all; - use std::{fs::File, io::Write}; - - #[test] - fn print_bluetooth_devices() { - let devices_info = get_bluetooth_info_all().unwrap(); - println!("{}", devices_info); - let mut file = File::create("devices.json").unwrap(); - file.write_all(devices_info.to_string().as_bytes()).unwrap(); - } -} diff --git a/src-tauri/src/bluetooth/windows.rs b/src-tauri/src/bluetooth/windows.rs deleted file mode 100644 index 1c04a99..0000000 --- a/src-tauri/src/bluetooth/windows.rs +++ /dev/null @@ -1,259 +0,0 @@ -use std::{os::windows::process::CommandExt, process::Command}; - -use anyhow::Result; -use serde::{ser::SerializeStruct, Deserialize, Serialize}; -use serde_json::Value; -use windows::{ - imp::CloseHandle, - Win32::{ - Devices::Bluetooth::{ - BluetoothFindFirstDevice, BluetoothFindNextDevice, BluetoothGetDeviceInfo, - BLUETOOTH_DEVICE_SEARCH_PARAMS, - }, - Foundation::{FALSE, HANDLE, SYSTEMTIME, TRUE}, - System::Threading::CREATE_NO_WINDOW, - }, -}; - -use crate::bluetooth::common::{BluetoothAddress, BluetoothClass, SystemTime}; -use crate::utils::{json::merge_json_arrays_by_key, string_changer::string_to_u16_slice}; - -type SysBluetoothDeviceInfo = windows::Win32::Devices::Bluetooth::BLUETOOTH_DEVICE_INFO; - -pub fn get_bluetooth_info(instance_id: &str) -> Result { - let script_str = &format!( - "\n$InstanceId = \"{}\";{}", - instance_id, - include_str!("../../scripts/get-bluetooth-battery.ps1") - ); - - debug!("{}", script_str); - - let output = Command::new("powershell.exe") - .args(["-ExecutionPolicy", "ByPass", "-Command", script_str]) - .creation_flags(CREATE_NO_WINDOW.0) - .output() - .expect("Failed to spawn powershell command"); - let result = String::from_utf8_lossy(&output.stdout); - serde_json::from_str(result.trim()) -} - -#[derive(Serialize, Deserialize)] -struct PnpDevice { - instance_id: String, - friendly_name: String, - /// e.g. 80 - battery_level: u8, - /// e.g. "00112233aabb" - bluetooth_address: String, -} - -pub fn get_bluetooth_info_all() -> Result { - let output = Command::new("powershell.exe") - .args([ - "-ExecutionPolicy", - "ByPass", - "-Command", - include_str!("../../scripts/get-bluetooth-battery-all.ps1"), - ]) - .creation_flags(CREATE_NO_WINDOW.0) - .output() - .expect("Failed to spawn powershell command"); - let json_str = String::from_utf8_lossy(&output.stdout); - let external_devices_info = match serde_json::from_str(json_str.trim())? { - Value::Array(json_array) => json_array, - _ => panic!("Failed to parse battery"), - }; - - let devices = get_bluetooth_devices_info().expect("Failed to get bluetooth device"); - let devices_info = devices - .iter() - .map(|device| serde_json::to_value(device).unwrap()) - .collect::>(); - - let merged_json_array = merge_json_arrays_by_key( - external_devices_info.as_slice(), - devices_info.as_slice(), - "bluetooth_address", - ); - serde_json::to_value(merged_json_array) -} - -pub fn get_bluetooth_devices_info() -> Result> { - // See: https://learn.microsoft.com/windows/win32/api/bluetoothapis/ns-bluetoothapis-bluetooth_device_search_params - let search_params: BLUETOOTH_DEVICE_SEARCH_PARAMS = BLUETOOTH_DEVICE_SEARCH_PARAMS { - // size of the structure (in bytes). - dwSize: std::mem::size_of::() as u32, - // A value indicating that an authenticated Bluetooth device must be returned in the search. - fReturnAuthenticated: FALSE, - // value indicating that a remembered Bluetooth device must be returned in the search. - fReturnRemembered: TRUE, - // value that specifies that the search should return an unknown Bluetooth device. - fReturnUnknown: TRUE, - /// a value indicating that the search must return connected Bluetooth devices. - fReturnConnected: FALSE, - /// a value indicating that a new inquiry needs to be issued. - fIssueInquiry: TRUE, - /// A value indicating the inquiry timeout, expressed in 1.28 second increments. - /// For example, the cTimeoutMultiplier value for a 12.8 second inquiry is 10. - /// The maximum value for this member is 48. If a value greater than 48 is used, - /// the calling function will fail immediately and return E_INVALIDARG. - cTimeoutMultiplier: 2, - /// Handle to the radio to perform the query. Set to NULL to perform the query on all local Bluetooth radios. - hRadio: HANDLE(0), - }; - - let mut device_info = SysBluetoothDeviceInfo { - dwSize: std::mem::size_of::() as u32, - ..Default::default() - }; - - let search_handle = match unsafe { BluetoothFindFirstDevice(&search_params, &mut device_info) } - { - Ok(search_handle) => match search_handle.is_invalid() { - true => return Err(windows::core::Error::from_win32().into()), - false => search_handle, - }, - Err(_) => panic!("Couldn't get first device."), - }; - - let mut res: Vec = Vec::new(); - loop { - match unsafe { BluetoothGetDeviceInfo(HANDLE(search_handle.0), &mut device_info) } { - result if result != 0 => { - error!("Error code: {}", result); - break; - } - result => result, - }; - - res.push(device_info.into()); - - if unsafe { !BluetoothFindNextDevice(search_handle, &mut device_info).as_bool() } { - break; - } - } - unsafe { CloseHandle(search_handle.0) }; // End of Bluetooth device search - - Ok(res) -} - -#[derive(Clone, Debug)] -/// wrapped windows crate structure to implement Display and Debug traits. -/// -/// See: https://learn.microsoft.com/windows/win32/api/bluetoothapis/ns-bluetoothapis-bluetooth_device_info_struct -pub struct BluetoothDeviceInfo { - pub class_of_device: BluetoothClass, - pub bluetooth_address: BluetoothAddress, - pub is_connected: bool, - pub is_remembered: bool, - pub is_authenticated: bool, - pub last_seen: SystemTime, - pub last_used: SystemTime, - pub name: String, -} - -impl Serialize for BluetoothDeviceInfo { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - let mut state = serializer.serialize_struct("BluetoothDeviceInfo", 8)?; - state.serialize_field("class_of_device", &self.class_of_device.to_string())?; - state.serialize_field( - "bluetooth_address", - &self.bluetooth_address.as_hex_string().to_uppercase(), - )?; - state.serialize_field("is_connected", &self.is_connected)?; - state.serialize_field("is_remembered", &self.is_remembered)?; - state.serialize_field("is_authenticated", &self.is_authenticated)?; - state.serialize_field("last_seen", &self.last_seen)?; - state.serialize_field("last_used", &self.last_used)?; - state.serialize_field("device_name", &self.name)?; - state.end() - } -} - -impl From for BluetoothDeviceInfo { - fn from(device_info: SysBluetoothDeviceInfo) -> Self { - BluetoothDeviceInfo { - bluetooth_address: BluetoothAddress::from(unsafe { - device_info.Address.Anonymous.ullLong - }), - class_of_device: BluetoothClass::from(device_info.ulClassofDevice), - is_connected: device_info.fConnected.as_bool(), - is_remembered: device_info.fRemembered.as_bool(), - is_authenticated: device_info.fAuthenticated.as_bool(), - last_seen: SystemTime { - year: device_info.stLastSeen.wYear, - month: device_info.stLastSeen.wMonth, - day_of_week: device_info.stLastSeen.wDayOfWeek, - day: device_info.stLastSeen.wDay, - hour: device_info.stLastSeen.wHour, - minute: device_info.stLastSeen.wMinute, - second: device_info.stLastSeen.wSecond, - milliseconds: device_info.stLastSeen.wMilliseconds, - }, - last_used: SystemTime { - year: device_info.stLastUsed.wYear, - month: device_info.stLastUsed.wMonth, - day_of_week: device_info.stLastUsed.wDayOfWeek, - day: device_info.stLastUsed.wDay, - hour: device_info.stLastUsed.wHour, - minute: device_info.stLastUsed.wMinute, - second: device_info.stLastUsed.wSecond, - milliseconds: device_info.stLastUsed.wMilliseconds, - }, - name: String::from_utf16_lossy(&device_info.szName).replace('\0', ""), - } - } -} - -impl From for SysBluetoothDeviceInfo { - fn from(device_info: BluetoothDeviceInfo) -> Self { - SysBluetoothDeviceInfo { - dwSize: std::mem::size_of::() as u32, - Address: windows::Win32::Devices::Bluetooth::BLUETOOTH_ADDRESS { - Anonymous: windows::Win32::Devices::Bluetooth::BLUETOOTH_ADDRESS_0 { - ullLong: device_info.bluetooth_address.into(), - }, - }, - ulClassofDevice: device_info.class_of_device.into(), - fConnected: device_info.is_connected.into(), - fRemembered: device_info.is_remembered.into(), - fAuthenticated: device_info.is_authenticated.into(), - stLastSeen: SYSTEMTIME { - wYear: device_info.last_seen.year, - wMonth: device_info.last_seen.month, - wDayOfWeek: device_info.last_seen.day_of_week, - wDay: device_info.last_seen.day, - wHour: device_info.last_seen.hour, - wMinute: device_info.last_seen.minute, - wSecond: device_info.last_seen.second, - wMilliseconds: device_info.last_seen.milliseconds, - }, - stLastUsed: SYSTEMTIME { - wYear: device_info.last_used.year, - wMonth: device_info.last_used.month, - wDayOfWeek: device_info.last_used.day_of_week, - wDay: device_info.last_used.day, - wHour: device_info.last_used.hour, - wMinute: device_info.last_used.minute, - wSecond: device_info.last_used.second, - wMilliseconds: device_info.last_used.milliseconds, - }, - szName: string_to_u16_slice(&device_info.name), - } - } -} - -#[cfg(test)] -mod tests { - use super::get_bluetooth_devices_info; - - #[test] - fn test_get_devices_info() { - let devices = get_bluetooth_devices_info().unwrap(); - println!("{:?}", devices); - } -} diff --git a/src-tauri/src/commands/bluetooth/mod.rs b/src-tauri/src/commands/bluetooth/mod.rs deleted file mode 100644 index fd42654..0000000 --- a/src-tauri/src/commands/bluetooth/mod.rs +++ /dev/null @@ -1,54 +0,0 @@ -use anyhow::Result; -use serde_json::Value; -use tauri::AppHandle; - -use crate::bluetooth::sys; -use crate::{commands::fs::bincode::write_data, system_tray::update_tray_icon}; - -#[tauri::command] -pub async fn get_bluetooth_info(app: AppHandle, instance_id: &str) -> Result { - match sys::get_bluetooth_info(instance_id) { - Ok(device_json) => { - let battery_level = device_json - .get("battery_level") - .expect("Not found battery_level.") - .as_u64() - .expect("Couldn't covert to u64"); - - let device_name = device_json - .get("device_name") - .expect("Couldn't find device") - .as_str() - .unwrap_or_default(); - - update_tray_icon(&app.clone(), device_name, battery_level) - .await - .err(); - write_data("device_info", device_json.clone()); - // We use `debug!` because we don't want to show it in `info!` for privacy reasons. - debug!("Device_info Json: {}", device_json); - Ok(device_json) - } - Err(err) => Err(err.into()), - } -} - -#[tauri::command] -pub async fn get_bluetooth_info_all() -> Result { - match get_bluetooth_info_all_inner() { - Ok(devices_json) => Ok(devices_json), - Err(err) => Err(err.into()), - } -} - -/// This function exists to separate sync and async. -fn get_bluetooth_info_all_inner() -> Result { - match sys::get_bluetooth_info_all() { - Ok(devices_json) => { - debug!("Devices_info Json: {}", devices_json); - write_data("device_info", devices_json.clone()); - Ok(devices_json) - } - Err(err) => Err(err), - } -} diff --git a/src-tauri/src/commands/fs/bincode.rs b/src-tauri/src/commands/fs/bincode.rs deleted file mode 100644 index 824e359..0000000 --- a/src-tauri/src/commands/fs/bincode.rs +++ /dev/null @@ -1,79 +0,0 @@ -/* -Copyright 2022 Justin Maximillian Kimlim and the Xplorer Contributors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -use std::fs; -use std::path::{Path, PathBuf}; -use std::str; -use tauri::api::path::local_data_dir; - -#[derive(serde::Serialize, Debug)] -pub struct StorageData { - pub data: serde_json::Value, - pub status: bool, -} - -fn get_storage_dir() -> PathBuf { - Path::new(&local_data_dir().expect("Failed to get local dir.")) - .join("bluetooth-battery-monitor") -} - -#[tauri::command] -pub fn write_data(key: &str, value: serde_json::Value) { - let storage_dir = get_storage_dir(); - if let Err(e) = fs::create_dir_all(&storage_dir) { - error!("Failed to create dirs: {:?}", e); - } - let value = bincode::serialize(&serde_json::to_vec(&value).unwrap()).unwrap(); - - if let Err(e) = fs::write(storage_dir.join(key), value) { - error!("Failed to write data: {:?}", e); - } -} - -#[tauri::command] -pub fn read_data(key: &str) -> Result { - let storage_dir = get_storage_dir(); - let mut status = true; - let data: String; - match fs::read(storage_dir.join(key)) { - Ok(result) => match bincode::deserialize(&result) { - Ok(deserialized_bincode) => data = deserialized_bincode, - Err(_) => data = str::from_utf8(&result).unwrap().to_string(), - }, - Err(e) => { - status = false; - data = e.to_string(); - } - } - - let serde_value: Result = serde_json::from_str(&data); - let data = match serde_value { - Ok(result) => result, - Err(_) => { - status = false; - serde_json::Value::Null - } - }; - - Ok(StorageData { data, status }) -} - -#[tauri::command] -pub fn delete_storage_data(key: String) { - let storage_dir = get_storage_dir(); - - if fs::remove_file(storage_dir.join(key)).is_ok() {} -} diff --git a/src-tauri/src/commands/fs/mod.rs b/src-tauri/src/commands/fs/mod.rs deleted file mode 100644 index ed26ddb..0000000 --- a/src-tauri/src/commands/fs/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod bincode; -pub mod settings; diff --git a/src-tauri/src/commands/fs/settings.rs b/src-tauri/src/commands/fs/settings.rs deleted file mode 100644 index 1af41ee..0000000 --- a/src-tauri/src/commands/fs/settings.rs +++ /dev/null @@ -1,99 +0,0 @@ -/// This code was forked by sardonyx -/* -Copyright 2022 Justin Maximillian Kimlim and the Xplorer Contributors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -///! Instead of using the bincode crate to keep the file size small, -///! allow users to directly configure the TOML itself by writing code. -use std::fs; -use std::path::{Path, PathBuf}; -use std::str; -use tauri::api::path::local_data_dir; - -use serde::{self, Deserialize, Serialize}; -const DEFAULT_SETTINGS: &str = include_str!("../../../../assets/default_settings.toml"); -const SETTINGS_FILE_NAME: &str = "settings.toml"; - -#[derive(Debug, Deserialize, Serialize)] -pub struct Settings { - pub base: Base, -} - -#[derive(Debug, Deserialize, Serialize)] -pub struct Base { - /// e.g. `true` Whether to start the app with the window on startup. - pub autostart: bool, - /// e.g. `60`(minutes) == 1hour - pub battery_query_duration_minutes: u64, - /// e.g. `20`(%) - pub notify_battery_level: u8, -} - -impl Default for Settings { - fn default() -> Self { - toml::from_str::(DEFAULT_SETTINGS) - .expect("Wrong syntaxes in default_settings.toml") - } -} - -#[derive(serde::Serialize, Debug)] -pub struct StorageData { - pub data: serde_json::Value, - pub status: bool, -} - -fn get_storage_dir() -> PathBuf { - Path::new(&local_data_dir().expect("Failed to get local dir.")) - .join("bluetooth-battery-monitor") -} - -#[tauri::command] -pub fn write_settings(settings_obj: Settings) -> Result<(), StorageData> { - let storage_dir = get_storage_dir(); - if let Err(e) = fs::create_dir_all(&storage_dir) { - error!("Failed to create dirs: {:?}", e); - } - let toml_str = match toml::to_string(&settings_obj) { - Ok(result) => result, - Err(e) => { - error!("Failed to convert to toml: {:?}", &settings_obj); - return Err(StorageData { - status: false, - data: e.to_string().into(), - }); - } - }; - - if let Err(e) = fs::write(storage_dir.join(SETTINGS_FILE_NAME), toml_str) { - error!("Failed to write data: {:?}", e); - }; - Ok(()) -} - -#[tauri::command] -pub fn read_settings() -> Result { - match fs::read(get_storage_dir().join(SETTINGS_FILE_NAME)) { - Ok(result) => match toml::from_str::(str::from_utf8(&result).unwrap()) { - Ok(settings) => Ok(settings), - Err(e) => Err(e.to_string()), - }, - Err(e) => Err(e.to_string()), - } -} - -#[tauri::command] -pub fn delete_settings() { - if fs::remove_file(get_storage_dir().join(SETTINGS_FILE_NAME)).is_ok() {} -} diff --git a/src-tauri/src/commands/mod.rs b/src-tauri/src/commands/mod.rs deleted file mode 100644 index 325f77e..0000000 --- a/src-tauri/src/commands/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod bluetooth; -pub mod fs; -pub mod notify; -pub mod timer; diff --git a/src-tauri/src/commands/notify.rs b/src-tauri/src/commands/notify.rs deleted file mode 100644 index 77bbbb7..0000000 --- a/src-tauri/src/commands/notify.rs +++ /dev/null @@ -1,19 +0,0 @@ -use tauri::{api::notification::Notification, AppHandle}; - -pub fn notify(app: &AppHandle, title: &str, message: &str) { - // See: [[bug] No notification sound on Windows](https://github.com/tauri-apps/tauri/issues/6652) - #[cfg(windows)] - { - use std::process::Command; - Command::new("powershell.exe") - .arg("[System.Media.SystemSounds]::Asterisk.Play()") - .output() - .expect("Failed to sound"); - } - - Notification::new(&app.config().tauri.bundle.identifier) - .title(title) - .body(message) - .show() - .expect("failed to show notification"); -} diff --git a/src-tauri/src/commands/timer.rs b/src-tauri/src/commands/timer.rs deleted file mode 100644 index 343d1a3..0000000 --- a/src-tauri/src/commands/timer.rs +++ /dev/null @@ -1,211 +0,0 @@ -use std::pin::Pin; -use std::sync::{atomic::Ordering, Arc}; -use std::time::Duration; -use std::{future::Future, sync::atomic::AtomicBool}; - -use once_cell::sync::Lazy; -use tauri::async_runtime::JoinHandle; -use tauri::AppHandle; -use tokio::sync::{Mutex, OnceCell}; -use tokio::time::interval; - -use crate::commands::bluetooth::get_bluetooth_info_all; -use crate::commands::fs::{ - bincode::read_data, - settings::{read_settings, Settings}, -}; -use crate::commands::notify::notify; -use crate::system_tray::update_tray_icon; - -#[tauri::command] -pub async fn update_info_interval(app: AppHandle, duration_mins: u64) { - let mut duration_mins = duration_mins; - if duration_mins == 0 { - duration_mins = 1; - error!("Got invalid duration_mins: {duration_mins}. Fallback to 1"); - } - let duration = Duration::from_secs(duration_mins * 60); // `* 60`: minutes to seconds - - clear_interval().await; - - set_interval( - move || { - let app = app.clone(); - Box::pin(async move { - let devices_info = get_bluetooth_info_all() - .await - .expect("Parse error json") - .as_array() - .expect("Not found devices") - .to_owned(); - let first_device = devices_info[0] - .get("bluetooth_address") - .expect("Not found 'bluetooth_address' key") - .clone(); - - let selected_device_id = match read_data("selected_device_id") { - Ok(device) => match device.status { - true => device.data, - false => { - warn!("Not selected_device file. So fallback to first device."); - first_device - } - }, - Err(err) => { - warn!("Not selected_device file.So fallback to first device: {err}"); - first_device - } - }; - // We use `debug!` because we don't want to show it in `info!` for privacy reasons. - debug!("Selected device: {}", selected_device_id); - let selected_device_info = devices_info - .iter() - .find(|device| device.get("bluetooth_address") == Some(&selected_device_id)) - .expect("Not found selected device"); - let battery_level = selected_device_info - .get("battery_level") - .expect("Couldn't found battery level") - .as_u64() - .expect("Couldn't covert to u64"); - - let device_name = selected_device_info - .get("device_name") - .expect("Couldn't find device") - .as_str() - .unwrap_or_default(); - - let settings = read_settings().unwrap_or(Settings::default()); - if battery_level <= settings.base.notify_battery_level.into() { - notify( - &app, - "[bluetooth battery monitor]", - format!("Configured battery warning.{}%", battery_level).as_str(), - ); - }; - update_tray_icon(&app, device_name, battery_level) - .await - .err() - }) - }, - duration, - ) - .await; -} - -// Define a struct to hold the state of the interval process -struct IntervalProcess { - handle: Option>, - running: Arc, -} - -impl IntervalProcess { - fn new() -> Self { - Self { - handle: None, - running: Arc::new(AtomicBool::new(false)), - } - } - - // Start the interval process with the given callback and interval duration - fn start(&mut self, mut callback: F, duration: Duration) - where - F: FnMut() -> Pin + Send + 'static>> + Send + 'static + Sync, - T: std::fmt::Debug, - { - let running = self.running.clone(); - self.handle = Some(tauri::async_runtime::spawn(async move { - let mut sleep_time = interval(duration); - loop { - sleep_time.tick().await; - if !running.load(Ordering::Relaxed) { - break; - } - let res = callback().await; - debug!("Interval callback res: {:?}", res); - } - })); - self.running.store(true, Ordering::Relaxed); - } - - // Stop the interval process - fn stop(&mut self) { - self.running.store(false, Ordering::Relaxed); - if let Some(handle) = self.handle.take() { - tokio::spawn(async move { - handle.abort(); - }); - } - } -} - -static INTERVAL_PROCESS: Lazy>>> = Lazy::new(OnceCell::new); - -fn get_or_init_interval<'a>() -> impl Future>> { - INTERVAL_PROCESS.get_or_init(|| async { Arc::new(Mutex::new(IntervalProcess::new())) }) -} - -// Define the setInterval and clearInterval functions -async fn set_interval(callback: F, duration: Duration) -where - F: FnMut() -> Pin + Send + 'static>> + Send + 'static + Sync, - T: std::fmt::Debug, -{ - get_or_init_interval() - .await - .lock() - .await - .start(callback, duration); -} - -async fn clear_interval() { - get_or_init_interval().await.lock().await.stop(); -} - -#[cfg(test)] -mod tests { - use tokio::sync::mpsc; - - use super::*; - - async fn is_running_interval() -> bool { - get_or_init_interval() - .await - .lock() - .await - .running - .load(Ordering::Relaxed) - } - - #[tokio::test] - async fn test_interval_process() { - let (tx, mut rx) = mpsc::channel(4); - let send_array = [1, 2, 3, 4, 5]; - let mut i = 0; - set_interval( - move || { - let tx = tx.clone(); - let val = send_array[i]; - i = (i + 1) % send_array.len(); - Box::pin(async move { - tx.send(val).await.unwrap(); - info!("send: {}", val); - }) - }, - Duration::from_secs(1), - ) - .await; - - for expected_val in &send_array { - let res_val = rx.recv().await.unwrap(); - info!("res: {}", res_val); - assert_eq!(res_val, *expected_val); - } - - assert!(is_running_interval().await); - - clear_interval().await; - - info!("Should have stopped the interval"); - assert!(!is_running_interval().await); - } -} diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs deleted file mode 100644 index fff7c41..0000000 --- a/src-tauri/src/main.rs +++ /dev/null @@ -1,67 +0,0 @@ -#![cfg_attr( - all(not(debug_assertions), target_os = "windows"), - windows_subsystem = "windows" -)] - -mod bluetooth; -mod commands; -mod setup; -mod system_tray; -mod utils; -mod window_menu; - -#[macro_use] -extern crate log; - -use tauri::Manager; -use tauri_plugin_autostart::MacosLauncher; - -use setup::tauri_setup; -use system_tray::{create_system_tray, tray_event}; -use window_menu::{create_menu, menu_event}; - -fn main() { - env_logger::init(); - - info!("Entering tauri builder"); - tauri::Builder::default() - .plugin(tauri_plugin_autostart::init( - MacosLauncher::LaunchAgent, - None, - )) - .setup(tauri_setup) - .system_tray(create_system_tray()) - .on_system_tray_event(tray_event) - .menu(create_menu()) - .on_menu_event(menu_event) - .on_window_event(window_event) - .invoke_handler(tauri::generate_handler![ - commands::bluetooth::get_bluetooth_info, - commands::bluetooth::get_bluetooth_info_all, - commands::fs::bincode::delete_storage_data, - commands::fs::bincode::read_data, - commands::fs::bincode::write_data, - commands::fs::settings::delete_settings, - commands::fs::settings::read_settings, - commands::fs::settings::write_settings, - commands::timer::update_info_interval, - ]) - .run(tauri::generate_context!()) - .expect("error while running tauri application"); -} - -fn window_event(event: tauri::GlobalWindowEvent) { - if let tauri::WindowEvent::CloseRequested { api, .. } = event.event() { - event.window().hide().expect("Failed to hide window."); - let tray_toggle_window = event - .window() - .app_handle() - .tray_handle() - .get_item("toggle_window"); - tray_toggle_window - .set_title("show") - .expect("Couldn't set hide title in system tray"); - - api.prevent_close(); - } -} diff --git a/src-tauri/src/setup.rs b/src-tauri/src/setup.rs deleted file mode 100644 index c56bbd6..0000000 --- a/src-tauri/src/setup.rs +++ /dev/null @@ -1,27 +0,0 @@ -use anyhow::Result; -use std::error::Error; -use tauri::{App, AppHandle, Manager}; - -use crate::commands::{ - fs::settings::{read_settings, write_settings, Settings}, - timer::update_info_interval, -}; - -pub fn tauri_setup(app: &mut App) -> Result<(), Box<(dyn Error + 'static)>> { - setup_inner(&app.app_handle()); - Ok(()) -} - -pub fn setup_inner(app: &AppHandle) { - let app = app.clone(); - tauri::async_runtime::spawn(async move { - let settings = read_settings().unwrap_or_else(|err| { - error!("Fallback to default settings. Reason: {err}"); - write_settings(Settings::default()).expect("Failed to write default settings"); - Settings::default() - }); - let duration_mins = settings.base.battery_query_duration_minutes; - info!("duration minutes: {duration_mins}"); - update_info_interval(app, duration_mins).await; - }); -} diff --git a/src-tauri/src/system_tray.rs b/src-tauri/src/system_tray.rs deleted file mode 100644 index 89a65b4..0000000 --- a/src-tauri/src/system_tray.rs +++ /dev/null @@ -1,95 +0,0 @@ -use anyhow::{anyhow, Result}; -use tauri::{AppHandle, CustomMenuItem, SystemTray, SystemTrayEvent, SystemTrayMenu}; -use tauri::{Manager, SystemTrayMenuItem}; - -use crate::setup::setup_inner; - -pub fn create_system_tray() -> SystemTray { - let toggle_window = CustomMenuItem::new("toggle_window".to_string(), "Show"); - let update_info = CustomMenuItem::new("update_info".to_string(), "Update info"); - let quit = CustomMenuItem::new("quit".to_string(), "Quit"); - let tray_menu = SystemTrayMenu::new() - .add_item(update_info) - .add_native_item(SystemTrayMenuItem::Separator) - .add_item(toggle_window) - .add_item(quit); - SystemTray::new() - .with_menu(tray_menu) - .with_tooltip("Getting bluetooth battery...") -} - -pub fn tray_event(app: &AppHandle, event: SystemTrayEvent) { - match event { - SystemTrayEvent::LeftClick { - position: _, - size: _, - .. - } => { - info!("Left click"); - } - SystemTrayEvent::RightClick { - position: _, - size: _, - .. - } => { - info!("Right click"); - } - SystemTrayEvent::DoubleClick { - position: _, - size: _, - .. - } => { - info!("Double click"); - } - SystemTrayEvent::MenuItemClick { id, .. } => match id.as_str() { - "reload_info" => setup_inner(app), - "toggle_window" => { - let item_handle = app.tray_handle().get_item(&id); - let window = app.get_window("main").unwrap(); - match window.is_visible().unwrap() { - true => { - window.hide().expect("Couldn't hide window"); - item_handle.set_title("Show").expect("Couldn't set title"); - } - false => { - window.show().expect("Couldn't show window"); - item_handle.set_title("Hide").expect("Couldn't set title"); - } - } - } - "quit" => { - std::process::exit(0); - } - _ => {} - }, - _ => {} - } -} - -pub async fn update_tray_icon( - app: &AppHandle, - device_name: &str, - battery_level: u64, -) -> Result<()> { - debug!("Change to {} battery icon", battery_level); - let battery_icon = match battery_level { - 0 => include_bytes!("../icons/battery/battery-0.png").to_vec(), - 1..=10 => include_bytes!("../icons/battery/battery-10.png").to_vec(), - 11..=20 => include_bytes!("../icons/battery/battery-20.png").to_vec(), - 21..=30 => include_bytes!("../icons/battery/battery-30.png").to_vec(), - 31..=40 => include_bytes!("../icons/battery/battery-40.png").to_vec(), - 41..=50 => include_bytes!("../icons/battery/battery-50.png").to_vec(), - 51..=60 => include_bytes!("../icons/battery/battery-60.png").to_vec(), - 61..=70 => include_bytes!("../icons/battery/battery-70.png").to_vec(), - 71..=80 => include_bytes!("../icons/battery/battery-80.png").to_vec(), - 81..=90 => include_bytes!("../icons/battery/battery-90.png").to_vec(), - 91..=100 => include_bytes!("../icons/battery/battery-100.png").to_vec(), - _ => unreachable!(), - }; - app.tray_handle() - .set_icon(tauri::Icon::Raw(battery_icon)) - .map_err(|_| anyhow!("Couldn't set new icon"))?; - app.tray_handle() - .set_tooltip(format!("{device_name} {battery_level}%").as_str()) - .map_err(|_| anyhow!("Couldn't set new tooltip.")) -} diff --git a/src-tauri/src/utils/json.rs b/src-tauri/src/utils/json.rs deleted file mode 100644 index 96a41c6..0000000 --- a/src-tauri/src/utils/json.rs +++ /dev/null @@ -1,50 +0,0 @@ -use serde_json::Value; - -pub fn merge_json_arrays_by_key(arr1: &[Value], arr2: &[Value], key: &str) -> Vec { - let mut result = Vec::new(); - - for val1 in arr1 { - if let Some(bluetooth_address) = val1.get(key) { - let merged_value = arr2 - .iter() - .find(|val2| val2.get(key) == Some(bluetooth_address)); - if let Some(val2) = merged_value { - let mut merged_val = val1.clone(); - merged_val - .as_object_mut() - .unwrap() - .extend(val2.as_object().unwrap().clone()); - result.push(merged_val); - } - } - } - - result -} - -#[cfg(test)] -mod tests { - use super::merge_json_arrays_by_key; - use serde_json::json; - - #[test] - fn test_merge_json_arrays_by_key() { - let arr1 = vec![ - json!({"id": 1, "name": "Alice", "age": 25, "bluetooth_address": "00:11:22:33:44:55"}), - json!({"id": 2, "name": "Bob", "age": 30, "bluetooth_address": "66:77:88:99:aa:bb"}), - json!({"id": 3, "name": "Charlie", "age": 35, "bluetooth_address": "dd:ee:ff:11:22:33"}), - ]; - let arr2 = vec![ - json!({"bluetooth_address": "00:11:22:33:44:55", "last_seen": "2022-04-10T12:34:56Z"}), - json!({"bluetooth_address": "66:77:88:99:aa:bb", "last_seen": "2022-04-09T23:45:01Z"}), - json!({"bluetooth_address": "11:22:33:44:55:66", "last_seen": "2022-04-11T08:12:34Z"}), - ]; - let expected_result = vec![ - json!({"id": 1, "name": "Alice", "age": 25, "bluetooth_address": "00:11:22:33:44:55", "last_seen": "2022-04-10T12:34:56Z"}), - json!({"id": 2, "name": "Bob", "age": 30, "bluetooth_address": "66:77:88:99:aa:bb", "last_seen": "2022-04-09T23:45:01Z"}), - ]; - - let result = merge_json_arrays_by_key(&arr1, &arr2, "bluetooth_address"); - assert_eq!(result, expected_result); - } -} diff --git a/src-tauri/src/utils/mod.rs b/src-tauri/src/utils/mod.rs deleted file mode 100644 index fe210bd..0000000 --- a/src-tauri/src/utils/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod json; -pub mod string_changer; diff --git a/src-tauri/src/utils/string_changer.rs b/src-tauri/src/utils/string_changer.rs deleted file mode 100644 index f06745f..0000000 --- a/src-tauri/src/utils/string_changer.rs +++ /dev/null @@ -1,21 +0,0 @@ -pub fn string_to_u16_slice(s: &str) -> [u16; N] { - let utf16_iter = s.encode_utf16(); - let mut array: [u16; N] = [0; N]; - for (i, c) in utf16_iter.enumerate() { - if i >= N { - break; - } - array[i] = c; - } - array -} - -#[test] -fn test_string_to_u16_slice() { - let s = "Hello, world!"; - let expected = [ - 72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33, 0, - ]; - let result = string_to_u16_slice(s); - assert_eq!(result, expected); -} diff --git a/src-tauri/src/window_menu.rs b/src-tauri/src/window_menu.rs deleted file mode 100644 index 9729163..0000000 --- a/src-tauri/src/window_menu.rs +++ /dev/null @@ -1,14 +0,0 @@ -use tauri::{CustomMenuItem, Menu, Submenu, WindowMenuEvent}; - -pub fn create_menu() -> Menu { - let quit = CustomMenuItem::new("quit".to_string(), "Quit"); - let submenu = Submenu::new("File", Menu::new().add_item(quit)); - - Menu::new().add_submenu(submenu) -} - -pub fn menu_event(event: WindowMenuEvent) { - if let "quit" = event.menu_item_id() { - std::process::exit(0); - } -} diff --git a/tailwind.config.js b/tailwind.config.js deleted file mode 100644 index a5d7804..0000000 --- a/tailwind.config.js +++ /dev/null @@ -1,10 +0,0 @@ -// This is a dummy file for tailwind intelligence - -/** @type {import('tailwindcss').Config} */ -// module.exports = { -// content: ["./src/**/*.{html,js}"], -// theme: { -// extend: {}, -// }, -// plugins: [], -// }; diff --git a/tools/version_up.cjs b/tools/version_up.cjs new file mode 100644 index 0000000..03168ee --- /dev/null +++ b/tools/version_up.cjs @@ -0,0 +1,150 @@ +//@ts-check +function usage() { + return ` + Usage: + node version_up.js + + Version Types: + 1. major: Increment the major version.(e.g. 0.0.0 -> 1.0.0) + 2. minor: Increment the minor version.(e.g. 0.0.0 -> 0.1.0) + 3. patch: Increment the patch version.(e.g. 0.0.0 -> 0.0.1) + + Examples: + node version_up.js minor + node version_up.js 2 +`; +} + +// - Special flags configuration +const isDebug = false; +const defaultVersion = '2'; // 2: Bump up `minor` version is default +const useGpg = true; // Verified commit with GPG key. + +// import modules +// biome-ignore lint/correctness/noNodejsModules: +const fs = require('node:fs'); +// biome-ignore lint/correctness/noNodejsModules: +const path = require('node:path'); +// biome-ignore lint/correctness/noNodejsModules: +const { execSync } = require('node:child_process'); +// paths +const basePath = path.resolve(__dirname, '..'); +const packageJsonPath = path.join(basePath, 'package.json'); +const cargoTomlPath = path.join(basePath, 'Cargo.toml'); +const issueTemplatePath = path.join(basePath, '.github', 'ISSUE_TEMPLATE', 'bug-report.yaml'); +// Constants by path +const packageJson = require(packageJsonPath); +const currentVersion = packageJson.version; + +if (isDebug) { + // biome-ignore lint/suspicious/noConsoleLog: + console.log(packageJsonPath); + // biome-ignore lint/suspicious/noConsoleLog: + console.log(cargoTomlPath); + // biome-ignore lint/suspicious/noConsoleLog: + console.log(issueTemplatePath); +} +main(); + +function main() { + const versionType = process.argv[2] || defaultVersion; + const newVersion = updateVersion(currentVersion, versionType); + + updatePackageJson(newVersion); + updateCargoToml(newVersion); + updateIssueTemplate(newVersion); + gitCommitAndTag(currentVersion, newVersion); + + // biome-ignore lint/suspicious/noConsoleLog: + console.log(`Updated version: ${currentVersion} => ${newVersion}`); +} + +/** + * @param {string} currentVersion + * @param {string} versionType + * @returns {string} newVersion + */ +function updateVersion(currentVersion, versionType) { + const [major, minor, patch] = currentVersion.split('.').map(Number); + + switch (versionType) { + case 'major': + case '1': + return `${major + 1}.0.0`; + case 'minor': + case '2': + return `${major}.${minor + 1}.0`; + case 'patch': + case '3': + return `${major}.${minor}.${patch + 1}`; + default: + throw new Error(`Invalid version type. Please specify "major"(1), "minor"(2), or "patch"(3).\n${usage()}`); + } +} + +/** + * @param {string} newVersion + */ +function updatePackageJson(newVersion) { + const packageJson = require(packageJsonPath); + packageJson.version = newVersion; + fs.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`); +} + +/** + * @param {string} newVersion + */ +function updateCargoToml(newVersion) { + let cargoToml = fs.readFileSync(cargoTomlPath, 'utf8'); + cargoToml = cargoToml.replace( + /\[workspace\.package\]\nversion = "(.*)"/, + `[workspace.package]\nversion = "${newVersion}"`, + ); + fs.writeFileSync(cargoTomlPath, cargoToml); +} + +/** + * @param {string} newVersion + */ +function updateIssueTemplate(newVersion) { + let issueTemplate = fs.readFileSync(issueTemplatePath, 'utf8'); + const versionList = issueTemplate.match(/options:\n((\s+- .*\n)+)/)?.[1]; + if (versionList == null) { + throw new Error('Invalid version'); + } + + const versions = versionList.split('\n').map((v) => v.trim().slice(2)); + if (!versions.includes(newVersion)) { + issueTemplate = issueTemplate.replace(/options:\n((\s+- .*\n)+)/, `options:\n$1 - ${newVersion}\n`); + fs.writeFileSync(issueTemplatePath, issueTemplate); + } +} + +/** + * Function to commit changes and create Git tag + * @param {string} currentVersion + * @param {string} newVersion New version + */ +function gitCommitAndTag(currentVersion, newVersion) { + let tagFlags = ''; + let commitFlags = ''; + if (useGpg) { + tagFlags += '-s '; + commitFlags += '-S '; + } + + try { + // Commit changes to Git + execSync( + `git add . && git commit ${commitFlags} -m "build(version): bump ${packageJson.name} from ${currentVersion} to ${newVersion}"`, + ); + + // Create Git tag + execSync(`git tag ${newVersion} ${tagFlags} -m "Version ${newVersion}"`); + + // biome-ignore lint/suspicious/noConsoleLog: + console.log('Git commit and tag created successfully.'); + } catch (error) { + throw new Error(`Failed to create Git commit and tag: ${error}`); + } +} diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..6958587 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,22 @@ +// This file is a test configuration file for gui/frontend. +// By placing the configuration file in the root directory, it eliminates wasted time in directory searches +// and prevents time delays in testing. + +import react from '@vitejs/plugin-react-swc'; +import tsconfigPaths from 'vite-tsconfig-paths'; +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + plugins: [react(), tsconfigPaths()], + test: { + alias: [{ find: '@/', replacement: `${__dirname}/gui/frontend/src/` }], + globals: true, + root: './gui/frontend/src/', + environment: 'jsdom', + setupFiles: ['./vitest.setup.mts'], + testTransformMode: { + ssr: ['**/*'], + }, + reporters: ['default', 'hanging-process'], + }, +}); diff --git a/www/App.tsx b/www/App.tsx deleted file mode 100644 index a0acdfb..0000000 --- a/www/App.tsx +++ /dev/null @@ -1,119 +0,0 @@ -import React, { useCallback, useEffect, useState } from "react/"; -import { clsx } from "clsx"; -import { tw } from "twind"; -import { - IconHome, - IconRotateClockwise2, - IconSettings, -} from "@tabler/icons-react"; - -import { Button } from "./components/ui/reactive-button.tsx"; -import { DEFAULT_SETTINGS, read_settings } from "./commands/fs/settings.ts"; -import { Home, Settings } from "./components/pages/index.ts"; -import { get_bluetooth_info_all } from "./commands/bluetooth.ts"; -import { read_data, write_data } from "./commands/fs/bincode.ts"; -import { update_info_interval } from "./commands/timer.ts"; - -import type { DeviceJson } from "./commands/bluetooth.ts"; -import type { SettingsJson } from "./commands/fs/settings.ts"; - -export default function App() { - const [devices, setDevices] = useState([]); - const [selectedDeviceId, setSelectedDeviceId] = useState(""); - const [toggleSettings, setToggleSettings] = useState(false); - const [settings, setSettings] = useState(DEFAULT_SETTINGS); - const [intervalId, setIntervalId] = useState(null); - - useEffect(() => { - (async () => { - const cache = await read_data("device_info"); - const cacheId = await read_data("selected_device_id"); - const settings = await read_settings(); - cache && setDevices(cache); - cacheId && setSelectedDeviceId(cacheId); - settings && setSettings(settings); - })(); - }, []); - - // To scroll lock For settings page. - if (toggleSettings) { - document.body.classList.add(tw`overflow-y-hidden`); - } else { - document.body.classList.remove(tw`overflow-y-hidden`); - } - - async function getBatteryInfo_all() { - try { - await get_bluetooth_info_all(async (json_array) => { - setDevices(json_array); - await write_data("device_info", json_array); - }); - } catch (error) { - console.error(error); - } - } - - const intervalFn = useCallback(async () => { - const cacheId = await read_data("selected_device_id"); - cacheId && setSelectedDeviceId(cacheId); - }, [setSelectedDeviceId]); - - async function updateSystemTrayInterval() { - if (!settings.base.battery_query_duration_minutes) { - console.error("Invalid value. expected number"); - return; - } - const duration_minutes = settings.base.battery_query_duration_minutes; - - await update_info_interval(duration_minutes); // write battery info by backend - intervalId && clearInterval(intervalId); - const id = setInterval(intervalFn, duration_minutes * 60 * 1000); // minutes to milliseconds - setIntervalId(id); - } - - return ( -
-
-
- - - -
- ); -} diff --git a/www/commands/auto-start.ts b/www/commands/auto-start.ts deleted file mode 100644 index b23dc8e..0000000 --- a/www/commands/auto-start.ts +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2019-2021 Tauri Programme within The Commons Conservancy -// SPDX-License-Identifier: Apache-2.0 -// SPDX-License-Identifier: MIT - -import { invoke } from "@tauri-apps/api"; - -export async function isEnabled(): Promise { - return await invoke("plugin:autostart|is_enabled"); -} - -export async function enable(): Promise { - try { - await invoke("plugin:autostart|enable"); - } catch (error) { - console.error(error); - } -} - -export async function disable(): Promise { - try { - await invoke("plugin:autostart|disable"); - } catch (error) { - console.error(error); - } -} diff --git a/www/commands/bluetooth.ts b/www/commands/bluetooth.ts deleted file mode 100644 index 7f63116..0000000 --- a/www/commands/bluetooth.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { invoke } from "@tauri-apps/api"; - -type Device = { - battery_level: number; - bluetooth_address: string; - class_of_device: string; - device_name: string; - friendly_name: string; - instance_id: string; - is_authenticated: boolean; - is_connected: boolean; - is_remembered: boolean; - last_seen: SystemTime; - last_used: SystemTime; -}; -export type SystemTime = { - day: number; - day_of_week: number; - hour: number; - milliseconds: number; - minute: number; - month: number; - second: number; - year: number; -}; -export type DeviceJson = Partial; - -/** - * - * @param fn - e.g. setter of useState - * @returns return type of callback - */ -export async function get_bluetooth_info_all( - fn: (json_array: U) => T -) { - const json_array = await invoke("get_bluetooth_info_all"); - return fn(json_array); -} - -/** - * @param instanceId - e.g."BTHENUM\{0000111E-0000-1000-8000-00805F9B34FB}_LOCALMFG&005D\7&2CDD7520&0&9C431E0131A6_C00000000" - * @param fn - e.g. setter of useState - * @returns return type of callback - */ -export async function get_bluetooth_info( - instanceId: string, - fn: (json_array: U) => T -) { - const json_array = await invoke("get_bluetooth_info", { - instanceId, - }); - return fn(json_array); -} diff --git a/www/commands/fs/bincode.ts b/www/commands/fs/bincode.ts deleted file mode 100644 index 5e9f266..0000000 --- a/www/commands/fs/bincode.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { invoke } from "@tauri-apps/api"; - -type StorageData = { - data: T; - status: boolean; -}; - -/** - * - * @export - * @param {string} key - * @param {*} value - */ -export async function write_data(key: string, value: T) { - try { - await invoke("write_data", { key, value }); - } catch (err) { - console.error(err); - } -} - -/** - * @param {string} key - key to store - * - * - NOTE: - * JSON.parse() is not necessary and can be used as an object immediately by casting with as. - */ -export async function read_data(key: string) { - let res: StorageData; - try { - res = await invoke("read_data", { key }); - return res.data; - } catch (err) { - console.error(err); - } -} - -/** - * @param {string} key - key to store - * - * - NOTE: - * JSON.parse() is not necessary and can be used as an object immediately by casting with as. - */ -export async function delete_storage_data(key: string) { - let res: StorageData; - try { - res = await invoke("delete_storage_data", { key }); - return res.data; - } catch (err) { - console.error(err); - } -} diff --git a/www/commands/fs/settings.ts b/www/commands/fs/settings.ts deleted file mode 100644 index 84ba209..0000000 --- a/www/commands/fs/settings.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { invoke } from "@tauri-apps/api"; - -export type SettingsJson = { - base: { - autostart: boolean; - battery_query_duration_minutes: number; - notify_battery_level: number; - }; -}; - -export const DEFAULT_SETTINGS = { - base: { - autostart: true, - battery_query_duration_minutes: 60, - notify_battery_level: 20, - }, -} as const satisfies SettingsJson; - -/** - * @param value - */ -export async function write_settings(settingsObj: SettingsJson) { - try { - await invoke("write_settings", { settingsObj }); - } catch (err) { - console.error(err); - } -} - -/** - */ -export async function read_settings() { - let res: SettingsJson; - try { - res = await invoke("read_settings"); - return res; - } catch (err) { - console.error(err); - } -} - -/** - */ -export async function delete_settings() { - let res: SettingsJson; - try { - res = await invoke("read_settings"); - return res; - } catch (err) { - console.error(err); - } -} diff --git a/www/commands/timer.ts b/www/commands/timer.ts deleted file mode 100644 index a1166d9..0000000 --- a/www/commands/timer.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { invoke } from "@tauri-apps/api"; - -/** - * @param durationMins - minutes e.g 60 (60min) - * @returns return type of callback - */ -export async function update_info_interval( - durationMins: number -): Promise { - try { - await invoke("update_info_interval", { durationMins }); - } catch (error) { - console.error(error); - } -} diff --git a/www/components/general-ui/switch.tsx b/www/components/general-ui/switch.tsx deleted file mode 100644 index cce3bae..0000000 --- a/www/components/general-ui/switch.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React from "react"; -import { tw } from "twind"; - -type Props = { - label: string; - isToggled: boolean; - onClick?: ( - event: React.MouseEvent - ) => void | Promise; -}; - -export const SwitchButton = ({ label, isToggled, onClick }: Props) => { - return ( - - ); -}; diff --git a/www/components/hooks/useDebounce.ts b/www/components/hooks/useDebounce.ts deleted file mode 100644 index b5ad466..0000000 --- a/www/components/hooks/useDebounce.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { useState, useEffect } from "react"; - -export function useDebounce(value: T, delay: number) { - const [debouncedValue, setDebouncedValue] = useState(value); - - useEffect(() => { - const timer = setTimeout(() => { - setDebouncedValue(value); - }, delay); - - return () => { - clearTimeout(timer); - }; - }, [value, delay]); - - return debouncedValue; -} diff --git a/www/components/pages/Home.tsx b/www/components/pages/Home.tsx deleted file mode 100644 index b2edc9f..0000000 --- a/www/components/pages/Home.tsx +++ /dev/null @@ -1,191 +0,0 @@ -import React, { TransitionEventHandler } from "react/"; -import { clsx } from "clsx"; -import { tw } from "twind"; -import { - IconHeadphones, - IconHeadset, - IconVideo, - IconMicrophone, - IconDeviceSpeaker, - IconHeadsetOff, - IconHeadphonesOff, - IconDeviceSpeakerOff, - IconDeviceGamepad, - IconVideoOff, - IconMicrophoneOff, - IconHelpOctagon, - IconDeviceLaptop, - IconDeviceLaptopOff, - IconDeviceDesktop, - IconDeviceDesktopOff, - IconDeviceAirpods, - IconDeviceAudioTape, -} from "@tabler/icons-react"; - -import { write_data } from "../../commands/fs/bincode.ts"; - -import type { TablerIconsProps } from "@tabler/icons-react"; -import type { DeviceJson } from "../../commands/bluetooth.ts"; - -type Props = { - devices: DeviceJson[] | []; - selectedDeviceId: string; - className?: string; - onTransitionEnd?: TransitionEventHandler; - setSelectedDeviceId: React.Dispatch>; -}; -export function Home({ - devices, - selectedDeviceId, - className, - onTransitionEnd, - setSelectedDeviceId, -}: Props) { - const selectDevice: React.MouseEventHandler = (e) => { - setSelectedDeviceId(e.currentTarget.value); - write_data("selected_device_id", e.currentTarget.value); - }; - - return ( -
-
- {Array.isArray(devices) ? ( - devices.map((device) => { - const bgColor = - device.bluetooth_address === selectedDeviceId - ? ({ backgroundColor: "#000000bf" } as const) - : undefined; - - return ( - - ); - }) - ) : ( -
- Devices not Found. - Please press `Update devices info` button. -
- )} -
-
- ); -} - -function DeviceInfo({ device }: { device: DeviceJson }) { - const lastUsed = device["last_used"]; - if (!lastUsed) { - return null; - } - const lastUsedDate = `${lastUsed.year}/${lastUsed.month}/${lastUsed.day} ${lastUsed.hour}:${lastUsed.minute}:${lastUsed.second}`; - - const meterOffCss = { - "--background": "#dadada18", - "--optimum": "#868686", - "--sub-optimum": "#868686", - "--sub-sub-optimum": "#868686", - } as React.CSSProperties; - - return ( - -
-
- {device["device_name"]} -
-
- Battery level: {device["battery_level"]}% - -
-
- Last Used: {lastUsedDate} -
-
-
- ); -} - -function DeviceCategoryIcon({ device }: { device: DeviceJson }) { - const device_class = device["class_of_device"] ?? ":"; - const [_cc, sub] = device_class.split(":"); - - const connectedBgColor = device["is_connected"] ? "#ffffff" : "#b1b1b1a2"; - const iconProps: TablerIconsProps = { size: "3rem", color: connectedBgColor }; - - switch (sub.trim()) { - case "Hands-free Device": - case "Wearable Headset Device": - return device["is_connected"] ? ( - - ) : ( - - ); - case "Microphone": - return device["is_connected"] ? ( - - ) : ( - - ); - case "HiFi Audio Device": - case "Loudspeaker": - case "Set-top box": - case "Video Display and Loudspeaker": - return device["is_connected"] ? ( - - ) : ( - - ); - case "Headphones": - return device["is_connected"] ? ( - - ) : ( - - ); - case "Portable Audio": - return ; - case "Car audio": - return ; - case "VCR": - return null; - case "Camcorder": - case "Video Camera": - return device["is_connected"] ? ( - - ) : ( - - ); - case "Video Monitor": - return device["is_connected"] ? ( - - ) : ( - - ); - case "Video Conferencing": - return device["is_connected"] ? ( - - ) : ( - - ); - case "Gaming/Toy": - return ; - default: // "Uncategorized" and "(Reserved)" too - return ; - } -} diff --git a/www/components/pages/Settings.tsx b/www/components/pages/Settings.tsx deleted file mode 100644 index 9da4df1..0000000 --- a/www/components/pages/Settings.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import React, { TransitionEventHandler } from "react"; -import { clsx } from "clsx"; -import { tw } from "twind"; - -import { Form } from "../ui/form.tsx"; -import { CSSText } from "./../ui/css-text.tsx"; -import { AutoStartSwitch } from "../ui/autostart-switch.tsx"; - -import type { SettingsJson } from "../../commands/fs/settings.ts"; - -type Props = { - className?: string; - onTransitionEnd?: TransitionEventHandler; - settings: SettingsJson; - setSettings: React.Dispatch>; -}; - -export function Settings({ - className, - onTransitionEnd, - settings, - setSettings, -}: Props) { - return ( -
-

Settings

-
-
- - -
-
- ); -} diff --git a/www/components/pages/index.ts b/www/components/pages/index.ts deleted file mode 100644 index 635c65a..0000000 --- a/www/components/pages/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { Home } from "./Home.tsx"; -export { Settings } from "./Settings.tsx"; diff --git a/www/components/ui/autostart-switch.tsx b/www/components/ui/autostart-switch.tsx deleted file mode 100644 index 236b2e6..0000000 --- a/www/components/ui/autostart-switch.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import React, { useCallback, useState } from "react"; - -import { isEnabled, enable, disable } from "../../commands/auto-start.ts"; -import { SwitchButton } from "../general-ui/switch.tsx"; -import { SettingsJson, write_settings } from "../../commands/fs/settings.ts"; - -type Props = { - autostart: boolean; - setSettings: React.Dispatch>; -}; - -export function AutoStartSwitch({ autostart, setSettings }: Props) { - const [isToggled, setToggle] = useState(autostart); - useCallback(async () => { - const isAutoStartEnabled = await isEnabled(); - setToggle(isAutoStartEnabled); - }, [setToggle])(); - - const handleOnClick = useCallback( - async (_event: React.MouseEvent) => { - setToggle((prev) => !prev); - setSettings((prev) => { - const res = { - ...prev, - base: { - ...prev.base, - autostart: !isToggled, - }, - } as const satisfies SettingsJson; - write_settings(res); - return res; - }); - - if (!isToggled) { - await enable(); - } else { - await disable(); - } - }, - [setSettings, setToggle, isToggled] - ); - - return ( - - ); -} diff --git a/www/components/ui/css-text.tsx b/www/components/ui/css-text.tsx deleted file mode 100644 index 2cb4373..0000000 --- a/www/components/ui/css-text.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import React, { useEffect, useState } from "react"; -import { clsx } from "clsx"; -import { tw } from "twind"; - -import { useDebounce } from "../hooks/useDebounce.ts"; -import { Button } from "./reactive-button.tsx"; - -export function CSSText() { - const [customCSS, setCustomCSS] = useState( - localStorage.getItem("custom-css") ?? "" - ); - const debouncedText = useDebounce(customCSS, 500); - - useEffect(() => { - localStorage.setItem("custom-css", debouncedText); - }, [debouncedText]); - - const exampleCss1 = `body { - background-image: linear-gradient(43deg, #00b09b, #96c93d); -}`; - - const exampleCss2 = ` body { - background-image: linear-gradient(43deg, #4158d0 0%, #c850c0 46%, #ffcc70 100%) -}`; - - const createClipboardHandler = (text: string) => { - return (e: React.MouseEvent) => { - setCustomCSS(text); - }; - }; - - return ( -
- - -
- ); -} diff --git a/www/components/ui/form.tsx b/www/components/ui/form.tsx deleted file mode 100644 index 7c6aabb..0000000 --- a/www/components/ui/form.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import React, { useCallback, useEffect } from "react"; -import { NumericFormat } from "react-number-format"; -import { clsx } from "clsx"; -import { tw } from "twind"; - -import { write_settings } from "../../commands/fs/settings.ts"; -import { useDebounce } from "./../hooks/useDebounce.ts"; - -import type { ChangeEvent } from "react"; -import type { SettingsJson } from "../../commands/fs/settings.ts"; - -type Props = { - settings: SettingsJson; - setSettings: React.Dispatch>; -}; - -export function Form({ settings, setSettings }: Props) { - const duration = useDebounce( - settings.base.battery_query_duration_minutes, - 500 - ); - - useEffect(() => { - const res = { - ...settings, - ...{ - base: { - ...settings.base, - battery_query_duration_minutes: duration, - }, - }, - } as const satisfies SettingsJson; - write_settings(res); - }, [duration, settings]); - - const handleOnchange = useCallback( - (event: ChangeEvent) => { - setSettings((prev) => { - return { - ...prev, - base: { - ...prev.base, - battery_query_duration_minutes: Number(event.target.value), - }, - } as const satisfies SettingsJson; - }); - }, - [setSettings] - ); - - return ( - -
- - { - return num.floatValue !== 0; - }} - onChange={handleOnchange} - placeholder="Minutes" - value={duration} - /> -
- - ); -} diff --git a/www/components/ui/reactive-button.tsx b/www/components/ui/reactive-button.tsx deleted file mode 100644 index 09bad0f..0000000 --- a/www/components/ui/reactive-button.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React, { useState } from "react"; -import ReactiveButton, { ReactiveButtonProps } from "reactive-button"; - -type Props = { - /** onClick function wrapper with async. - * This will cause loading and completion state transitions. - */ - callback?: (event: React.MouseEvent) => Promise; -}; - -export const Button = (props: ReactiveButtonProps & Props) => { - const [state, setState] = useState<"idle" | "loading" | "success" | "error">( - "idle" - ); - - const onClickHandler = async ( - event: React.MouseEvent - ) => { - setState("loading"); - try { - props.callback && (await props.callback(event)); - setState("success"); - } catch (error) { - setState("error"); - } - }; - - return ( - - ); -}; diff --git a/www/constants.ts b/www/constants.ts deleted file mode 100644 index e69de29..0000000 diff --git a/www/global.css b/www/global.css deleted file mode 100644 index a0089a8..0000000 --- a/www/global.css +++ /dev/null @@ -1,181 +0,0 @@ -:root { - --scroll-color: #324a5c; - --scroll-hover-color: #363d4d; - --scroll-bgcolor: #252525; -} - -::-webkit-scrollbar-thumb { - background-color: var(--scroll-color); -} - -::-webkit-scrollbar-thumb:active { - background-color: var(--scroll-color); -} - -::-webkit-scrollbar-thumb:hover { - background-color: var(--scroll-hover-color); -} - -::-webkit-scrollbar { - background-color: var(--scroll-bgcolor); - color: #cdc5b8; -} - -::-webkit-scrollbar-corner { - background-color: var(--scroll-bgcolor); -} - -body { - background-image: linear-gradient( - 43deg, - #4158d0 0%, - #c850c0 46%, - #ffcc70 100% - ); -} - -.glass { - box-shadow: rgb(0 0 0 / 65%) 20px 20px 60px, rgb(0 0 0 / 50%) -20px -20px 60px; - background-color: #121212a6; -} - -.animate { - transition: all 0.5s ease; -} - -.animate.left-move { - left: 100%; - transform: translate(-100%, 0); -} - -.animate.right-move { - right: 100%; - transform: translate(100%, 0); -} - -.animate.top-move { - top: 100%; - transform: translate(0, -100%); -} - -.animate.bottom-move { - bottom: 100%; - transform: translate(0, 100%); -} - -.translate-x-9999 { - transform: translate(9999px, 0); -} - -.hidden { - display: none; -} - -.form-input { - background-color: #a1adb738; -} - -.switch-label { - position: relative; - display: inline-block; - width: 60px; - height: 30px; -} - -.switch-input { - opacity: 0; - width: 0; - height: 0; -} - -.switch-span { - position: absolute; - cursor: pointer; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: #51556159; - transition: 0.3s; - border-radius: 30px; - border: 0.5px; - border-style: solid; -} - -.switch-span:before { - position: absolute; - content: ""; - height: 25px; - width: 25px; - left: 3px; - bottom: 2.6px; - background-color: #f7be55; - border-radius: 50%; - transition: 0.3s; -} - -.switch-input:checked + span { - background-color: rgba(255, 255, 255, 0.91); -} - -.switch-input:checked + span:before { - transform: translateX(29px); -} - -.switch-strong { - position: absolute; - left: 100%; - width: max-content; - line-height: 30px; - margin-left: 10px; - cursor: pointer; -} - -/* See: https://stackoverflow.com/questions/8094835/how-to-style-html5-meter-tag */ -meter { - --background: #dadada18; - --optimum: forestgreen; - --sub-optimum: gold; - --sub-sub-optimum: crimson; - - /* The gray background in Firefox */ - background: var(--background); - display: block; - /* margin-bottom: 1em; */ - width: 90%; -} - -/* The gray background in Chrome, etc. */ -meter::-webkit-meter-bar { - background: var(--background); -} - -/* The green (optimum) bar in Firefox */ -meter:-moz-meter-optimum::-moz-meter-bar { - background: var(--optimum); -} - -/* The green (optimum) bar in Chrome etc. */ -meter::-webkit-meter-optimum-value { - background: var(--optimum); -} - -/* The yellow (sub-optimum) bar in Firefox */ -meter:-moz-meter-sub-optimum::-moz-meter-bar { - background: var(--sub-optimum); -} - -/* The yellow (sub-optimum) bar in Chrome etc. */ -meter::-webkit-meter-suboptimum-value { - background: var(--sub-optimum); -} - -/* The red (even less good) bar in Firefox */ -meter:-moz-meter-sub-sub-optimum::-moz-meter-bar { - background: var(--sub-sub-optimum); -} - -/* The red (even less good) bar in Chrome etc. */ -meter::-webkit-meter-even-less-good-value { - background: var(--sub-sub-optimum); -} diff --git a/www/index.html b/www/index.html deleted file mode 100644 index 6f9584c..0000000 --- a/www/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - -
- - - - diff --git a/www/index.tsx b/www/index.tsx deleted file mode 100644 index 99300c0..0000000 --- a/www/index.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import React from "react/"; -import { createRoot } from "react-dom/client"; - -import App from "./App.tsx"; - -import "./global.css"; - -const root = createRoot(document.getElementById("root") as HTMLElement); - -root.render(); - -// For hot reload(https://esbuild.github.io/api/#live-reload) -new EventSource("/esbuild").addEventListener("change", () => location.reload());