diff --git a/.github/DISCUSSION_TEMPLATE/feature-request-ideas.yml b/.github/DISCUSSION_TEMPLATE/feature-request-ideas.yml index fe7922d7..242d0640 100644 --- a/.github/DISCUSSION_TEMPLATE/feature-request-ideas.yml +++ b/.github/DISCUSSION_TEMPLATE/feature-request-ideas.yml @@ -1,7 +1,32 @@ -body: - - type: textarea - attributes: - label: Describe the feature you'd like - description: A clear and concise description of what you want to happen - validations: - required: true +--- +labels: ["enhancement"] +body: + - type: markdown + attributes: + value: | + Thanks for sharing an idea πŸ™Œ + Clear context helps me evaluate and prioritize requests faster. + - type: textarea + id: problem + attributes: + label: "πŸ€” Problem to solve" + description: What problem or frustration are you trying to solve? + placeholder: I often need to... + validations: + required: true + - type: textarea + id: proposal + attributes: + label: "πŸ’‘ Proposed solution" + description: What would you like to happen? + placeholder: Add an option to... + validations: + required: true + - type: textarea + id: additional-context + attributes: + label: "πŸ“Ž Additional context" + description: Add mockups, screenshots, links, or examples. + placeholder: Any extra context... + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 60ac91a5..06e2b634 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,41 +1,58 @@ -name: Report an issue -description: Create a report to help us improve -labels: ["bug"] +--- +name: "🐞 Report a bug" +description: Help me fix bugs faster with a clear report +labels: ["bug", "status: needs-triage"] body: - - type: checkboxes + - type: markdown attributes: - label: Browser - description: In which browser(s) did you encounter the issue? - options: - - label: Chrome - - label: Firefox + value: | + Thanks for reporting this πŸ™Œ + Please share as much detail as you can so I can reproduce the issue and ship a fix quickly. + - type: input + id: operating-system + attributes: + label: "πŸ’» Operating system" + description: Which operating system are you using? + placeholder: Windows 11 + validations: + required: false + - type: input + id: browser + attributes: + label: "🌐 Browser and version" + description: Which browser and version are you using? + placeholder: Chrome 144.0.0.0 validations: required: true - type: input + id: extension-version attributes: - label: Extension version - description: What version of the extension are you using? - placeholder: 1.0.0 + label: "🧩 Extension version" + description: Which extension version are you currently using? + placeholder: 2.0.0 validations: required: true - type: input + id: redmine-version attributes: - label: Redmine version - description: What version of Redmine are you using? - placeholder: 5.1.2.stable + label: "🧱 Redmine version" + description: If known, what Redmine version are you using? + placeholder: 6.0.0.stable validations: required: false - type: textarea + id: bug-description attributes: - label: Describe the bug - description: A clear and concise description of what the bug is. - placeholder: A clear and concise description of what the bug is + label: "πŸ› Bug description" + description: What is going wrong? + placeholder: Briefly describe the issue and its impact validations: required: true - type: textarea + id: steps-to-reproduce attributes: - label: To Reproduce - description: Steps to reproduce the behavior. + label: "πŸ§ͺ Steps to reproduce" + description: Share exact steps so I can reproduce it. placeholder: | 1. Go to '...' 2. Click on '....' @@ -44,9 +61,10 @@ body: validations: required: true - type: textarea + id: additional-context attributes: - label: Additional context / Screenshots - description: Add any other context about the problem here. If applicable, add screenshots to help explain your problem. - placeholder: Add other context here (e.g. screenshots, logs, etc.) + label: "πŸ“Ž Additional context / screenshots" + description: Add anything else that may help (screenshots, logs, console errors, related links). + placeholder: Paste logs, screenshots, or extra details here validations: required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 05b20147..9635d2e2 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,8 +1,9 @@ +--- blank_issues_enabled: false contact_links: - - name: Feature request / Ideas + - name: ✨ Feature request url: https://github.com/CrawlerCode/redmine-time-tracking/discussions/new?category=feature-request-ideas - about: Share ideas for new features - - name: Ask a question + about: Discuss early ideas and product direction + - name: ❓ Ask a question url: https://github.com/CrawlerCode/redmine-time-tracking/discussions/new?category=q-a - about: Ask questions + about: Ask usage questions and get help diff --git a/.github/linters/.codespellrc b/.github/linters/.codespellrc new file mode 100644 index 00000000..8446af36 --- /dev/null +++ b/.github/linters/.codespellrc @@ -0,0 +1,2 @@ +[codespell] +skip = */src/lang/*.json,*/public/_locales/*/messages.json \ No newline at end of file diff --git a/.github/linters/.htmlhintrc b/.github/linters/.htmlhintrc new file mode 100644 index 00000000..e3f643bb --- /dev/null +++ b/.github/linters/.htmlhintrc @@ -0,0 +1,25 @@ +{ + "tagname-lowercase": true, + "attr-lowercase": true, + "attr-value-double-quotes": true, + "attr-value-not-empty": false, + "attr-no-duplication": true, + "doctype-first": true, + "tag-pair": true, + "tag-self-close": false, + "spec-char-escape": true, + "id-unique": true, + "src-not-empty": true, + "title-require": false, + "alt-require": true, + "doctype-html5": true, + "id-class-value": false, + "style-disabled": false, + "inline-style-disabled": false, + "inline-script-disabled": false, + "space-tab-mixed-disabled": "space", + "id-class-ad-disabled": false, + "href-abs-or-rel": false, + "attr-unsafe-chars": true, + "head-script-disabled": true +} diff --git a/.github/linters/.stylelintrc.json b/.github/linters/.stylelintrc.json new file mode 100644 index 00000000..c434436e --- /dev/null +++ b/.github/linters/.stylelintrc.json @@ -0,0 +1,3 @@ +{ + "extends": ["../../stylelint.config.mjs"] +} diff --git a/.github/linters/eslint.config.mjs b/.github/linters/eslint.config.mjs new file mode 100644 index 00000000..1b756a22 --- /dev/null +++ b/.github/linters/eslint.config.mjs @@ -0,0 +1,3 @@ +import config from "../../eslint.config.mjs"; + +export default config; diff --git a/.github/linters/zizmor.yaml b/.github/linters/zizmor.yaml new file mode 100644 index 00000000..bbb03663 --- /dev/null +++ b/.github/linters/zizmor.yaml @@ -0,0 +1,6 @@ +--- +rules: + unpinned-uses: + config: + policies: + "*": ref-pin diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 00000000..4a8ec23e --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,42 @@ +--- +name: Lint + +on: + pull_request: null + +permissions: {} + +jobs: + lint: + name: Lint + runs-on: ubuntu-latest + + permissions: + contents: read + statuses: write + + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + persist-credentials: false + + - uses: pnpm/action-setup@v4 + + - uses: actions/setup-node@v6 + with: + node-version: 24 + cache: "pnpm" + + - run: pnpm install --frozen-lockfile + + - name: super-linter + uses: super-linter/super-linter/slim@v8.4.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + IGNORE_GITIGNORED_FILES: true + STRIP_DEFAULT_WORKSPACE_FOR_REGEX: true + FILTER_REGEX_EXCLUDE: ^(CHANGELOG\.md|pnpm-lock\.yaml)$ + VALIDATE_BIOME_FORMAT: false # Prettier is used instead + VALIDATE_BIOME_LINT: false # Prettier is used instead + VALIDATE_JSCPD: false # TODO: Enable this linter in the future to detect code duplication diff --git a/.github/workflows/publish-pre-release.yml b/.github/workflows/publish-pre-release.yml new file mode 100644 index 00000000..2ff78f48 --- /dev/null +++ b/.github/workflows/publish-pre-release.yml @@ -0,0 +1,46 @@ +--- +name: Publish Pre-Release + +on: + release: + types: + - prereleased + +permissions: {} + +jobs: + publish-chrome-pre-release: + name: Publish Pre-Release to Chrome Web Store + runs-on: ubuntu-latest + + permissions: + contents: write + + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - uses: pnpm/action-setup@v4 + + - uses: actions/setup-node@v6 + with: + node-version: 22 + + - run: pnpm install --frozen-lockfile + + - run: pnpm run build:chrome:pre-release + + - run: gh release upload "${RELEASE_TAG}" "$(ls .output/*-chrome.zip)" + env: + GITHUB_TOKEN: ${{ github.token }} + RELEASE_TAG: ${{ github.event.release.tag_name }} + + - run: | + pnpm wxt submit \ + --chrome-zip .output/*-chrome.zip + env: + CHROME_EXTENSION_ID: adgcdimdkkaddeopcabokepmaihfhklb + CHROME_CLIENT_ID: ${{ secrets.CHROME_CLIENT_ID }} + CHROME_CLIENT_SECRET: ${{ secrets.CHROME_CLIENT_SECRET }} + CHROME_REFRESH_TOKEN: ${{ secrets.CHROME_REFRESH_TOKEN }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 188723d4..816d76fc 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,78 +1,81 @@ -name: Publish - -on: - release: - types: [published] - -permissions: - contents: write - -jobs: - publish-chrome: - name: Publish to Chrome Web Store - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - uses: pnpm/action-setup@v4 - - - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: "pnpm" - - - run: pnpm install --frozen-lockfile - - - run: pnpm run build:chrome - - - run: gh release upload ${{ github.event.release.tag_name }} releases/redmine-time-tracking-${{ github.event.release.tag_name }}-chrome.zip - env: - GITHUB_TOKEN: ${{ github.TOKEN }} - - - uses: mnao305/chrome-extension-upload@v5.0.0 - with: - file-path: releases/redmine-time-tracking-${{ github.event.release.tag_name }}-chrome.zip - extension-id: ldcanhhkffokndenejhafhlkapflgcjg - client-id: ${{ secrets.CHROME_CLIENT_ID }} - client-secret: ${{ secrets.CHROME_CLIENT_SECRET }} - refresh-token: ${{ secrets.CHROME_REFRESH_TOKEN }} - - publish-firefox: - name: Publish to Firefox Addon Store - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - uses: pnpm/action-setup@v4 - - - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: "pnpm" - - - run: pnpm install --frozen-lockfile - - - run: pnpm run build:firefox - - - run: gh release upload ${{ github.event.release.tag_name }} releases/redmine-time-tracking-${{ github.event.release.tag_name }}-firefox.zip - env: - GITHUB_TOKEN: ${{ github.TOKEN }} - - - uses: kewisch/action-web-ext@v1 - id: web-ext-sign - with: - cmd: sign - source: releases/redmine-time-tracking-${{ github.event.release.tag_name }}-firefox.zip - artifacts: releases - channel: listed - approvalNotes: "GitHub: https://github.com/CrawlerCode/redmine-time-tracking" - apiKey: ${{ secrets.FIREFOX_API_KEY }} - apiSecret: ${{ secrets.FIREFOX_API_SECRET }} - - - run: mv ${{ steps.web-ext-sign.outputs.target }} releases/redmine-time-tracking-${{ github.event.release.tag_name }}-firefox.xpi - - - run: gh release upload ${{ github.event.release.tag_name }} releases/redmine-time-tracking-${{ github.event.release.tag_name }}-firefox.xpi - env: - GITHUB_TOKEN: ${{ github.TOKEN }} +--- +name: Publish + +on: + release: + types: + - released + +permissions: {} + +jobs: + publish-chrome: + name: Publish to Chrome Web Store + runs-on: ubuntu-latest + + permissions: + contents: write + + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - uses: pnpm/action-setup@v4 + + - uses: actions/setup-node@v6 + with: + node-version: 22 + + - run: pnpm install --frozen-lockfile + + - run: pnpm run build:chrome:release + + - run: gh release upload "${RELEASE_TAG}" "$(ls .output/*-chrome.zip)" + env: + GITHUB_TOKEN: ${{ github.token }} + RELEASE_TAG: ${{ github.event.release.tag_name }} + - run: | + pnpm wxt submit \ + --chrome-zip .output/*-chrome.zip + env: + CHROME_EXTENSION_ID: ldcanhhkffokndenejhafhlkapflgcjg + CHROME_CLIENT_ID: ${{ secrets.CHROME_CLIENT_ID }} + CHROME_CLIENT_SECRET: ${{ secrets.CHROME_CLIENT_SECRET }} + CHROME_REFRESH_TOKEN: ${{ secrets.CHROME_REFRESH_TOKEN }} + + publish-firefox: + name: Publish to Firefox Addon Store + runs-on: ubuntu-latest + + permissions: + contents: write + + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - uses: pnpm/action-setup@v4 + + - uses: actions/setup-node@v6 + with: + node-version: 22 + + - run: pnpm install --frozen-lockfile + + - run: pnpm run build:firefox:release + + - run: gh release upload "${RELEASE_TAG}" "$(ls .output/*-firefox.zip)" + env: + GITHUB_TOKEN: ${{ github.token }} + RELEASE_TAG: ${{ github.event.release.tag_name }} + + - run: | + pnpm wxt submit \ + --firefox-zip .output/*-firefox.zip \ + --firefox-sources-zip .output/*-sources.zip + env: + FIREFOX_EXTENSION_ID: "{ea2ad5bc-e458-414d-8565-5cfe9f7cf0c2}" + FIREFOX_JWT_ISSUER: ${{ secrets.FIREFOX_JWT_ISSUER }} + FIREFOX_JWT_SECRET: ${{ secrets.FIREFOX_JWT_SECRET }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..0f5eb92e --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,36 @@ +--- +name: Release + +on: + push: + branches: + - main + workflow_dispatch: + +permissions: {} + +jobs: + release: + name: Release + runs-on: ubuntu-latest + + permissions: + contents: read + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + persist-credentials: false + + - uses: pnpm/action-setup@v4 + + - uses: actions/setup-node@v6 + with: + node-version: 24 + + - run: pnpm install --frozen-lockfile + + - run: pnpm run release + env: + GITHUB_TOKEN: ${{ secrets.GH_PAT_RELEASE }} diff --git a/.gitignore b/.gitignore index b0dbbf2e..1cfd9215 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,20 @@ node_modules -dist -.env +dist +.output +.wxt .vscode/* !.vscode/extensions.json +!.vscode/settings.json /test-results/ /playwright-report/ /blob-report/ /playwright/.cache/ +/tests/screenshots -releases -release_notes.md \ No newline at end of file +.redmine/data +!.redmine/data/e2e-tests +.redmine/themes/* +!.redmine/themes/.gitkeep \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..661cc633 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,3 @@ +CHANGELOG.md +pnpm-lock.yaml +src/routeTree.gen.ts \ No newline at end of file diff --git a/.redmine/README.md b/.redmine/README.md new file mode 100644 index 00000000..2d494d91 --- /dev/null +++ b/.redmine/README.md @@ -0,0 +1,25 @@ +# Redmine dev setup + +This folder provides local Redmine instances for manual testing against multiple Redmine versions. + +## Start a version + +Run from this directory (`.redmine`): + +```bash +docker compose up -d redmine-v6 +``` + +Available services and ports: + +- Redmine end-to-end tests: [http://localhost:9999](http://localhost:9999) (service `redmine-e2e-tests`) +- Redmine 6: [http://localhost:3006](http://localhost:3006) (service `redmine-v6`) +- Redmine 5: [http://localhost:3005](http://localhost:3005) (service `redmine-v5`) +- Redmine 4: [http://localhost:3004](http://localhost:3004) (service `redmine-v4`) +- Redmine 3: [http://localhost:3003](http://localhost:3003) (service `redmine-v3`) +- Redmine 2: [http://localhost:3002](http://localhost:3002) (service `redmine-v2`) + +## Notes + +- [Default credentials](https://hub.docker.com/_/redmine#accessing-the-application): `admin`/`admin` +- [Themes](https://www.redmine.org/projects/redmine/wiki/theme_list) are mounted from `.redmine/themes` diff --git a/.redmine/data/e2e-tests/sqlite/redmine.db b/.redmine/data/e2e-tests/sqlite/redmine.db new file mode 100644 index 00000000..0ce99e12 Binary files /dev/null and b/.redmine/data/e2e-tests/sqlite/redmine.db differ diff --git a/.redmine/docker-compose.yml b/.redmine/docker-compose.yml new file mode 100644 index 00000000..9a0ae3fb --- /dev/null +++ b/.redmine/docker-compose.yml @@ -0,0 +1,71 @@ +services: + redmine-e2e-tests: + container_name: redmine-e2e-tests + image: redmine:6 + pull_policy: always + restart: unless-stopped + ports: + - "9999:3000" + volumes: + - ./data/e2e-tests/sqlite:/usr/src/redmine/sqlite + - ./themes:/usr/src/redmine/themes:ro + + redmine-v6: + container_name: redmine-v6 + image: redmine:6 + pull_policy: always + restart: unless-stopped + ports: + - "3006:3000" + volumes: + - ./data/v6/files:/usr/src/redmine/files + - ./data/v6/sqlite:/usr/src/redmine/sqlite + - ./themes:/usr/src/redmine/themes:ro + + redmine-v5: + container_name: redmine-v5 + image: redmine:5 + pull_policy: always + restart: unless-stopped + ports: + - "3005:3000" + volumes: + - ./data/v5/files:/usr/src/redmine/files + - ./data/v5/sqlite:/usr/src/redmine/sqlite + - ./themes:/usr/src/redmine/public/themes:ro + + redmine-v4: + container_name: redmine-v4 + image: redmine:4 + pull_policy: always + restart: unless-stopped + ports: + - "3004:3000" + volumes: + - ./data/v4/files:/usr/src/redmine/files + - ./data/v4/sqlite:/usr/src/redmine/sqlite + - ./themes:/usr/src/redmine/public/themes:ro + + redmine-v3: + container_name: redmine-v3 + image: redmine:3 + pull_policy: always + restart: unless-stopped + ports: + - "3003:3000" + volumes: + - ./data/v3/files:/usr/src/redmine/files + - ./data/v3/sqlite:/usr/src/redmine/sqlite + - ./themes:/usr/src/redmine/public/themes:ro + + redmine-v2: + container_name: redmine-v2 + image: redmine:2 + pull_policy: always + restart: unless-stopped + ports: + - "3002:3000" + volumes: + - ./data/v2/files:/usr/src/redmine/files + - ./data/v2/sqlite:/usr/src/redmine/sqlite + - ./themes:/usr/src/redmine/public/themes:ro diff --git a/.redmine/themes/.gitkeep b/.redmine/themes/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..3101be2b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "htmlhint.optionsFile": ".github/linters/.htmlhintrc" +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..cdec4999 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,224 @@ +## [2.0.0-beta.7](https://github.com/CrawlerCode/redmine-time-tracking/compare/v2.0.0-beta.6...v2.0.0-beta.7) (2026-04-19) + +### πŸš€ Features + +* Add issue status badge ([6c5e447](https://github.com/CrawlerCode/redmine-time-tracking/commit/6c5e447c919b35168e0eda61fe5644a6723865d1)) +* Add side panel entrypoint ([3731d5d](https://github.com/CrawlerCode/redmine-time-tracking/commit/3731d5da1c18806e921699b99c669ae662316cd5)) +* **settings:** Add option to show/hide issue done ratio ([bc9b6c3](https://github.com/CrawlerCode/redmine-time-tracking/commit/bc9b6c3c597ff1dca6ebdaa06dc31aba45e07762)) +* **settings:** Add option to show/hide timer sessions ([6022751](https://github.com/CrawlerCode/redmine-time-tracking/commit/602275185fbad50d34cfe1406089842d1ae0cfee)) + +### 🩹 Fixes + +* Fix install listener registration ([8b9b125](https://github.com/CrawlerCode/redmine-time-tracking/commit/8b9b125d37d3360afceabc045e45613001d845f2)) +* **ui:** Fix dark mode for firefox options and sidepanel ([ba6b406](https://github.com/CrawlerCode/redmine-time-tracking/commit/ba6b4065eac518c3b2d4724ceefee7aa3dd57b3a)) + +### 🏑 Chore + +* **deps:** Update npm dependencies ([0132802](https://github.com/CrawlerCode/redmine-time-tracking/commit/01328027f5e027e959165645351d0ea9c39c9c99)) +* **deps:** Update npm dependencies ([b0256f0](https://github.com/CrawlerCode/redmine-time-tracking/commit/b0256f06df6f97353708d2aba7a81bc1eff3d347)) +* **lint:** Fix htmlhint errors ([07604c3](https://github.com/CrawlerCode/redmine-time-tracking/commit/07604c351d4645489529c65e861bd259d1ae81b8)) + +### πŸ“– Documentation + +* Update store screenshots ([702a2c4](https://github.com/CrawlerCode/redmine-time-tracking/commit/702a2c4de603b8cf913aae2bd361112c963558fa)) + +### πŸ§ͺ Tests + +* Fix flaky time drift tests ([cadd015](https://github.com/CrawlerCode/redmine-time-tracking/commit/cadd01521f55b272046d575a0d9e96d198442b32)) + +## [2.0.0-beta.6](https://github.com/CrawlerCode/redmine-time-tracking/compare/v2.0.0-beta.5...v2.0.0-beta.6) (2026-04-12) + +### πŸš€ Features + +* **timers:** Add timer sessions ([#69](https://github.com/CrawlerCode/redmine-time-tracking/issues/69)) ([#71](https://github.com/CrawlerCode/redmine-time-tracking/issues/71)) ([ed42990](https://github.com/CrawlerCode/redmine-time-tracking/commit/ed42990c135ec1c3a577ed372d31bf8715804005)) + +### 🩹 Fixes + +* **timer:** Fix timer name cursor focus ([dee98ec](https://github.com/CrawlerCode/redmine-time-tracking/commit/dee98ecabeaa2caccc83949f740dd5eae4d37d82)) + +### 🏑 Chore + +* **deps:** Update npm dependencies ([e966f7e](https://github.com/CrawlerCode/redmine-time-tracking/commit/e966f7e6803f335260b7a3d68fd0023a79fe6ad3)) +* **security:** Set pnpm minimum release age to 1 days ([0d595c2](https://github.com/CrawlerCode/redmine-time-tracking/commit/0d595c2ab4e2206d9b6b5b58632a46844aca3580)) + +### πŸ“– Documentation + +* Update store screenshots ([cd60ec7](https://github.com/CrawlerCode/redmine-time-tracking/commit/cd60ec707cc67fc87f6c31011ef61dc558967758)) + +### πŸ“¦ Builds + +* **deps-dev:** bump vite from 8.0.3 to 8.0.5 ([#70](https://github.com/CrawlerCode/redmine-time-tracking/issues/70)) ([aed8cdc](https://github.com/CrawlerCode/redmine-time-tracking/commit/aed8cdccb08246745788943193cd755266d59888)) +* **deps:** bump axios from 1.14.0 to 1.15.0 ([#72](https://github.com/CrawlerCode/redmine-time-tracking/issues/72)) ([057ad2c](https://github.com/CrawlerCode/redmine-time-tracking/commit/057ad2c4c63912b58ee747d68e2e3429eb00a508)) + +## [2.0.0-beta.5](https://github.com/CrawlerCode/redmine-time-tracking/compare/v2.0.0-beta.4...v2.0.0-beta.5) (2026-03-30) + +### 🩹 Fixes + +* Fix autoFetchPages for redmine paginated queries ([a925baa](https://github.com/CrawlerCode/redmine-time-tracking/commit/a925baa79ec4c5575dbf81072ead535d09b9e5c2)) +* **ui:** Enhance skeleton components ([d89a901](https://github.com/CrawlerCode/redmine-time-tracking/commit/d89a901413cc12f5411277b883a96a48c07e633f)) +* **ui:** Fix layout inconsistencies depending on style settings ([6cef7e3](https://github.com/CrawlerCode/redmine-time-tracking/commit/6cef7e3a70316e10e9dfae210a998bae2f19c336)) +* **ui:** Improve combobox clear button position ([932d36d](https://github.com/CrawlerCode/redmine-time-tracking/commit/932d36d319515bbdfc0300e1325a6ae886f58ef7)) +* **ui:** Truncate field labels ([e779018](https://github.com/CrawlerCode/redmine-time-tracking/commit/e779018f048e6b90833f309fcfceab12797311b0)) + +### 🏑 Chore + +* Fix eslint errors ([9ec1e07](https://github.com/CrawlerCode/redmine-time-tracking/commit/9ec1e07ee3895d36d0433ff3a899370b58659b46)) +* Introduced script to automate chrome store screenshot generation ([#67](https://github.com/CrawlerCode/redmine-time-tracking/issues/67)) ([c34baa2](https://github.com/CrawlerCode/redmine-time-tracking/commit/c34baa265578f22b6ea46cae13cfd1d6bacb3b63)) +* Update npm dependencies ([a9bb249](https://github.com/CrawlerCode/redmine-time-tracking/commit/a9bb2494a5369159ab24a8c2babd2e72fc8ed5a4)) +* Update shadcn components ([4f9bb88](https://github.com/CrawlerCode/redmine-time-tracking/commit/4f9bb883c8f68977c67e39838e5dbd5f242d4b7c)) +* Upgrade to typescript 6 and hardened ts config ([5e34a03](https://github.com/CrawlerCode/redmine-time-tracking/commit/5e34a039d764a0c482529f9bdb334931b1cebfc0)) +* Upgrade to vite v8 ([8210cb5](https://github.com/CrawlerCode/redmine-time-tracking/commit/8210cb5c64a6dafc2ef0f15cf748bdcae80c5162)) + +### πŸ› οΈ Refactors + +* Fix some warnings and errors from react-doctor ([c4d9c84](https://github.com/CrawlerCode/redmine-time-tracking/commit/c4d9c8493f29ee162e7ae36417aeb63c7b94a261)) +* **ui:** Refactor time entry week overview ([2710d3b](https://github.com/CrawlerCode/redmine-time-tracking/commit/2710d3be7012217ea79b0b23bcef546f7e7ceb69)) + +### πŸ“– Documentation + +* **github:** Enhance issue and feature request templates ([#68](https://github.com/CrawlerCode/redmine-time-tracking/issues/68)) ([e70f419](https://github.com/CrawlerCode/redmine-time-tracking/commit/e70f4192ef8032137d1831568622f249cd0d8913)) + +### πŸ§ͺ Tests + +* Fix flaky tests ([1e0a7a2](https://github.com/CrawlerCode/redmine-time-tracking/commit/1e0a7a2c6ef7b23e460b4ea8f3e04c665feae843)) +* Introduce snapshot-based e2e tests ([#66](https://github.com/CrawlerCode/redmine-time-tracking/issues/66)) ([dfcb7fb](https://github.com/CrawlerCode/redmine-time-tracking/commit/dfcb7fbcb1f6a76c3fb3c628945591b6f7a48ca1)) + +## [2.0.0-beta.4](https://github.com/CrawlerCode/redmine-time-tracking/compare/v2.0.0-beta.3...v2.0.0-beta.4) (2026-03-09) + +### 🩹 Fixes + +* Cleanup local issue data on reset to default data ([9a7adc1](https://github.com/CrawlerCode/redmine-time-tracking/commit/9a7adc1e73be2a11302b579f7f1a15db288e2fd3)) +* Fire toast after query reset ([f051446](https://github.com/CrawlerCode/redmine-time-tracking/commit/f051446513f00e4af352e28d46ce10e4c041d2fb)) +* Prevent empty issues fetch request ([#65](https://github.com/CrawlerCode/redmine-time-tracking/issues/65)) ([6616c64](https://github.com/CrawlerCode/redmine-time-tracking/commit/6616c6430da8649af0f9ccccdd6ab064ff0d402b)) + +## [2.0.0-beta.3](https://github.com/CrawlerCode/redmine-time-tracking/compare/v2.0.0-beta.2...v2.0.0-beta.3) (2026-03-08) + +### πŸš€ Features + +* Add full-screen project sidebar (experimental) ([#64](https://github.com/CrawlerCode/redmine-time-tracking/issues/64)) ([2f4c065](https://github.com/CrawlerCode/redmine-time-tracking/commit/2f4c065f6f0d4e51145318bd41e44f3958217d8e)) + +### 🩹 Fixes + +* Fix 0 value selection for select field ([35af5e4](https://github.com/CrawlerCode/redmine-time-tracking/commit/35af5e4a145a39cf6862120cebaa9b0c6b70fb04)) +* Fix context menu dialog actions ([66cbc7a](https://github.com/CrawlerCode/redmine-time-tracking/commit/66cbc7a9dcb4dd08276eb862c836997c4e73a5a7)) +* Fix default time entry activity ([0f316ae](https://github.com/CrawlerCode/redmine-time-tracking/commit/0f316aefdcb0c72f9283c893812a1d473c753567)) +* Fix suspense settings provider ([#60](https://github.com/CrawlerCode/redmine-time-tracking/issues/60)) ([cfc47f3](https://github.com/CrawlerCode/redmine-time-tracking/commit/cfc47f33f42a0089f5fa1440ab428d5ba8aa9a32)) +* **ui:** Polished various ui elements ([c095c5c](https://github.com/CrawlerCode/redmine-time-tracking/commit/c095c5c0338832d1f73b95ec8f1bcd8a062d25a6)) + +### πŸ”₯ Performance + +* Add query client restoring gate instead of restoring twice ([30b9aeb](https://github.com/CrawlerCode/redmine-time-tracking/commit/30b9aeb2818f0e58c0ea749d22b1e2cfc7de0d80)) +* Improve performance by moving stuff to dedicated components ([f2f7fab](https://github.com/CrawlerCode/redmine-time-tracking/commit/f2f7fab23df7075946090df41288a1e5b941e4e1)) +* Set NODE_ENV=production for release & pre-release builds ([4a922ff](https://github.com/CrawlerCode/redmine-time-tracking/commit/4a922ff9fedd001671c000a16ef1876935b35738)) +* Use react context for permissions management ([#63](https://github.com/CrawlerCode/redmine-time-tracking/issues/63)) ([23f25f0](https://github.com/CrawlerCode/redmine-time-tracking/commit/23f25f00d628bdd1f910b6238aef5a9287538e7c)) + +### 🏑 Chore + +* Add docker compose for dev setup ([bb79a02](https://github.com/CrawlerCode/redmine-time-tracking/commit/bb79a021a9b3c0f65465a2473b69883d8ddb1039)) +* Add install buttons to github releases ([3c97a80](https://github.com/CrawlerCode/redmine-time-tracking/commit/3c97a80ef1046608168c8f927bc47d7a58eb61ff)) +* **deps:** Update dependencies ([2a3f1fb](https://github.com/CrawlerCode/redmine-time-tracking/commit/2a3f1fbdab6fb67da33f91c821bb5e0b0b18885c)) +* Update dependencies ([891fd66](https://github.com/CrawlerCode/redmine-time-tracking/commit/891fd662232a49099abf96a71a8ed4a053eb2fc7)) + +### πŸ› οΈ Refactors + +* Refactor redmine api hooks ([6642499](https://github.com/CrawlerCode/redmine-time-tracking/commit/66424994e80f76c826a518967bc5d6b117b98523)) +* **timer:** Remove the reset timer button ([26e0f2f](https://github.com/CrawlerCode/redmine-time-tracking/commit/26e0f2fe898b6fb9d5d317f28fdec095e4d93864)) + +### ⚑CI + +* Add super-linter for pull requests ([#59](https://github.com/CrawlerCode/redmine-time-tracking/issues/59)) ([9db6385](https://github.com/CrawlerCode/redmine-time-tracking/commit/9db6385931fcb6604368514f8d7fcfe0824b1efc)) +* Fix wxt submit ([74fe75d](https://github.com/CrawlerCode/redmine-time-tracking/commit/74fe75d9b951b42cc049c4cc41273cc4f8ddcc07)) +* Use pat for release creation to trigger publish pipeline ([7b15071](https://github.com/CrawlerCode/redmine-time-tracking/commit/7b15071bc083630ac0d7cbf45756e1edc87f7db0)) + +## [2.0.0-beta.2](https://github.com/CrawlerCode/redmine-time-tracking/compare/v2.0.0-beta.1...v2.0.0-beta.2) (2026-01-27) + +### 🩹 Fixes + +* Enforce next release ([1d7d37c](https://github.com/CrawlerCode/redmine-time-tracking/commit/1d7d37c099aa1de809d5f143eabb9f75bb24950a)) + +### 🏑 Chore + +* **deps:** Update dependencies ([6f800bd](https://github.com/CrawlerCode/redmine-time-tracking/commit/6f800bd82bd7fcb3cf806fddc372b3ff20ef4cc0)) + +### πŸ“– Documentation + +* Update README ([8011225](https://github.com/CrawlerCode/redmine-time-tracking/commit/801122541f2d5590eff14949d5726068b680cb38)) + +### ⚑CI + +* Fix pre-release asset upload ([ac8f132](https://github.com/CrawlerCode/redmine-time-tracking/commit/ac8f1327ef3636142c112d57a7912d8fdea7c7d3)) +* Publish production only for real releases not for pre-releases ([9855905](https://github.com/CrawlerCode/redmine-time-tracking/commit/9855905c077172cec3c3c39853b309d0cb400179)) + +## [2.0.0-beta.1](https://github.com/CrawlerCode/redmine-time-tracking/compare/v1.21.2...v2.0.0-beta.1) (2026-01-27) + +### ⚠ BREAKING CHANGES + +* The next release should be a major version bump + +### πŸš€ Features + +* Add project info tooltip ([f2a1c80](https://github.com/CrawlerCode/redmine-time-tracking/commit/f2a1c809e57c9c73cf17b7a500219916f2054fe2)) +* Allow to specify the rounding mode ([#49](https://github.com/CrawlerCode/redmine-time-tracking/issues/49)) ([2c0322b](https://github.com/CrawlerCode/redmine-time-tracking/commit/2c0322bf5bc70a07c217502c1beacc06c99f05a4)) +* Display custom field values for info tooltips ([2d2bef8](https://github.com/CrawlerCode/redmine-time-tracking/commit/2d2bef89ffc3e56ec51cb80386badc6345a8ca95)) +* Enhance issue grouping ([#38](https://github.com/CrawlerCode/redmine-time-tracking/issues/38)) ([e2a5a98](https://github.com/CrawlerCode/redmine-time-tracking/commit/e2a5a98f33240db32a19b3b563efd85fec7aed2a)) +* Enhance search ([#51](https://github.com/CrawlerCode/redmine-time-tracking/issues/51)) ([770fa4b](https://github.com/CrawlerCode/redmine-time-tracking/commit/770fa4b9035bf6556073e49e4e1836ab12cd0312)), closes [#46](https://github.com/CrawlerCode/redmine-time-tracking/issues/46) +* **filter:** Add issue status filter ([e7807e2](https://github.com/CrawlerCode/redmine-time-tracking/commit/e7807e28a770bb2ee74719f49c75a982ed17859c)) +* Multiple timers & timer tab ([bd55541](https://github.com/CrawlerCode/redmine-time-tracking/commit/bd55541bf7ccaed7cbb4668ec92a847e0d3e6db8)), closes [#39](https://github.com/CrawlerCode/redmine-time-tracking/issues/39) +* **timers:** Group timers by project and sort them by newest first ([d66aa6a](https://github.com/CrawlerCode/redmine-time-tracking/commit/d66aa6ad7e41d1561941d505644db84d4396aa14)) + +### 🩹 Fixes + +* Display translated error message until redmine url is configured and remove errors toasts ([4c2d534](https://github.com/CrawlerCode/redmine-time-tracking/commit/4c2d53472d1152baac70f02d8813ac31601d0c80)) +* Fix broken persistent comments behavior ([6121441](https://github.com/CrawlerCode/redmine-time-tracking/commit/612144169252cabf7a6417380da19e9f4b9b207b)) +* Fix default time entry activity selection ([946c4b6](https://github.com/CrawlerCode/redmine-time-tracking/commit/946c4b634fdb7d842b1e5b33031f338caae34ec4)) +* Fix eslint errors ([a245275](https://github.com/CrawlerCode/redmine-time-tracking/commit/a24527525f93f831bf106743f6570dfe9ab58381)) +* Fix legacy settings migrations ([1336e31](https://github.com/CrawlerCode/redmine-time-tracking/commit/1336e316450d78d6addc601cfff0f1279628b41f)) +* Handle issue priorities when no default is specified ([899c21a](https://github.com/CrawlerCode/redmine-time-tracking/commit/899c21aca56b74526b01d4d282135c69d74a386c)) +* Implement legacy data migrations for issues and timers ([c2fd501](https://github.com/CrawlerCode/redmine-time-tracking/commit/c2fd5017b8375ac114a36b141bb1fa4b697acdf3)) +* Save persistent comments per timer instead of issue ([bff5fcf](https://github.com/CrawlerCode/redmine-time-tracking/commit/bff5fcfc26e6d09432346d582b6327bac8c6d2ef)) +* Skip failed mutations for multi create time spend entires ([a019c16](https://github.com/CrawlerCode/redmine-time-tracking/commit/a019c168d7534bb553604a0e895dce73313db9ea)) +* **timer:** Close alert dialog on reset confirm ([9e51a23](https://github.com/CrawlerCode/redmine-time-tracking/commit/9e51a23141cf2821fc85640f33d81471a7d2b467)) +* **ui:** Display deleted issues as strike-through text ([90933a9](https://github.com/CrawlerCode/redmine-time-tracking/commit/90933a99d14d2684c17dc6552058ebe0b19a0cb3)) +* **ui:** Fix toaster styles inside shadow root ([0319a42](https://github.com/CrawlerCode/redmine-time-tracking/commit/0319a42d50bd77cc0feee0e19f0dda11515c6520)) +* Update min browser versions to match current requirements ([bd1e7d0](https://github.com/CrawlerCode/redmine-time-tracking/commit/bd1e7d01581bfaf1943f3a926434028aa0764e0f)) + +### πŸ”₯ Performance + +* Add react compiler and reduce unnecessary re-renders ([acb8551](https://github.com/CrawlerCode/redmine-time-tracking/commit/acb855150e0f9a38dc8b1445bdf55751f747e835)) +* Improving data loading and increasing page loading speed ([#52](https://github.com/CrawlerCode/redmine-time-tracking/issues/52)) ([6b22f6b](https://github.com/CrawlerCode/redmine-time-tracking/commit/6b22f6b3629206e18bc45dd55299cf0a8bb111eb)) + +### 🏑 Chore + +* Enforce next release version to v2.0.0 ([fade882](https://github.com/CrawlerCode/redmine-time-tracking/commit/fade8829942707b295cc1be8d097cb1f1cd53495)) +* Update npm dependencies ([6c806b9](https://github.com/CrawlerCode/redmine-time-tracking/commit/6c806b9e24c688c8b07aa688424cf04f01920cc0)) + +### πŸ› οΈ Refactors + +* Improve create time entry modal ([49f6eb6](https://github.com/CrawlerCode/redmine-time-tracking/commit/49f6eb6cec9bb43337fce87abd6407465e4011d4)) +* Move to tanstack form + zod (removed formik + yup) ([60b9e43](https://github.com/CrawlerCode/redmine-time-tracking/commit/60b9e430fccc30567ad07dffaf367ecdb68eb195)) +* Remove add notes settings option ([4c3733c](https://github.com/CrawlerCode/redmine-time-tracking/commit/4c3733c1523f6855ccedaca4b6c2ad97b3c0f185)) +* Run settings migration on extension update ([840f48d](https://github.com/CrawlerCode/redmine-time-tracking/commit/840f48d890553c677f4cbef8d5eaba0d3296f8b4)) +* **settings:** Redesign settings page and add testing redmine connection button ([3a65610](https://github.com/CrawlerCode/redmine-time-tracking/commit/3a6561014ddd14a04fdcef07776a18637dbc7607)) +* **timer:** Refactor timer components and permission improvements ([0b32d3e](https://github.com/CrawlerCode/redmine-time-tracking/commit/0b32d3eb435be2aafe4d476070afad029a686fc1)) +* **ui:** Migrate to shadcn components ([#48](https://github.com/CrawlerCode/redmine-time-tracking/issues/48)) ([274e220](https://github.com/CrawlerCode/redmine-time-tracking/commit/274e220fa43123c8f204a844b1c50c4530dcf9f8)) +* **ui:** Move to shadcn base-ui components ([#57](https://github.com/CrawlerCode/redmine-time-tracking/issues/57)) ([70994f0](https://github.com/CrawlerCode/redmine-time-tracking/commit/70994f015994a2f6bdef77ca10547fce65cb0e93)) +* Upgrade tailwindcss to v4 ([aa42fbb](https://github.com/CrawlerCode/redmine-time-tracking/commit/aa42fbb4eaf1a32293fc59f771ee28bf3fe1ce0f)) +* Use null as form default values and update zod to v4 ([cd2f4d8](https://github.com/CrawlerCode/redmine-time-tracking/commit/cd2f4d8a97c4056ae9b53a776c287b4f6134ca73)) +* Use only project id for permission check function ([b31c12f](https://github.com/CrawlerCode/redmine-time-tracking/commit/b31c12f9f2e1c2ec868da4f391bb26cee9f823d8)) + +### πŸ“– Documentation + +* **license:** Update license text for consistency ([37a0ebf](https://github.com/CrawlerCode/redmine-time-tracking/commit/37a0ebf72b6e1701d26db0129385232a771e9d26)) + +### πŸ§ͺ Tests + +* Fix all e2e tests ([c46486f](https://github.com/CrawlerCode/redmine-time-tracking/commit/c46486f666442e249c1626cb6811a654147062f3)) + +### πŸ“¦ Builds + +* Migrate to wxt framework ([#53](https://github.com/CrawlerCode/redmine-time-tracking/issues/53)) ([a83bf30](https://github.com/CrawlerCode/redmine-time-tracking/commit/a83bf3074e9228c57c7672e00e6cf83fab670b0b)) + +### ⚑CI + +* Add build number for canary version ([df1d96c](https://github.com/CrawlerCode/redmine-time-tracking/commit/df1d96ce75f6f623cc20ef6bfcb3fef8e12646aa)) +* Add semantic release ([2ca9621](https://github.com/CrawlerCode/redmine-time-tracking/commit/2ca962157af3027b3600642d283ba45ba931d3c8)) diff --git a/LICENSE b/LICENSE index 163da934..307bc668 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,21 @@ -Copyright 2023 CrawlerCode +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the β€œSoftware”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2023 CrawlerCode -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -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. +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/README.md b/README.md index a2ac97d6..7113dcdc 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,11 @@ -![Package Version](https://img.shields.io/github/package-json/v/CrawlerCode/redmine-time-tracking?logo=github) +# Redmine Time Tracking (Chrome Extension / Firefox Extension) + +

Redmine Time Tracking Banner

+ ![License](https://img.shields.io/github/license/CrawlerCode/redmine-time-tracking?logo=github) -![GitHub Release Date](https://img.shields.io/github/release-date/CrawlerCode/redmine-time-tracking?logo=github) -![GitHub issues](https://img.shields.io/github/issues/CrawlerCode/redmine-time-tracking?logo=github) +[![Semantic-Release](https://img.shields.io/badge/semantic--release-conventional%20commits-e10079?logo=semantic-release)](https://github.com/semantic-release/semantic-release) +![Release Version](https://img.shields.io/github/v/release/CrawlerCode/redmine-time-tracking?logo=github) +![Pre-Release Version](https://img.shields.io/github/v/release/CrawlerCode/redmine-time-tracking?include_prereleases&logo=github&label=pre-release) ![Chrome Web Store Version](https://img.shields.io/chrome-web-store/v/ldcanhhkffokndenejhafhlkapflgcjg?logo=google-chrome&logoColor=white) ![Chrome Web Store Users](https://img.shields.io/chrome-web-store/users/ldcanhhkffokndenejhafhlkapflgcjg?logo=google-chrome&logoColor=white) @@ -11,36 +15,55 @@ ![Mozilla Add-on Users](https://img.shields.io/amo/users/redmine-time-tracking?logo=firefox-browser&logoColor=white) ![Mozilla Add-on Rating](https://img.shields.io/amo/stars/redmine-time-tracking?logo=firefox-browser&logoColor=white) -# Redmine Time Tracking (Chrome Extension / Firefox Extension) - -> Start-stop timer for [Redmine](https://www.redmine.org/). +> Start-stop timer for [Redmine (open source project management web application)](https://www.redmine.org) [![Install-Button-Chrome]][Install-Link-Chrome] [![Install-Button-Firefox]][Install-Link-Firefox] -[Install-Button-Chrome]: https://img.shields.io/badge/Install-71b500?style=for-the-badge&logoColor=white&logo=google-chrome +[Install-Button-Chrome]: https://img.shields.io/badge/Install-Chrome-71b500?style=for-the-badge&logoColor=white&logo=google-chrome [Install-Link-Chrome]: https://chrome.google.com/webstore/detail/redmine-time-tracking/ldcanhhkffokndenejhafhlkapflgcjg "Open in chrome web store" -[Install-Button-Firefox]: https://img.shields.io/badge/Install-71b500?style=for-the-badge&logoColor=white&logo=firefox-browser +[Install-Button-Firefox]: https://img.shields.io/badge/Install-Firefox-71b500?style=for-the-badge&logoColor=white&logo=firefox-browser [Install-Link-Firefox]: https://addons.mozilla.org/de/firefox/addon/redmine-time-tracking "Open in firefox add-on store" -# Features +## πŸš€ Features + +| | | | +| :---------------------------------: | :---------------------------------: | :---------------------------------: | +| ![1](./screenshots/chrome/en/1.png) | ![2](./screenshots/chrome/en/2.png) | ![3](./screenshots/chrome/en/3.png) | +| ![4](./screenshots/chrome/en/4.png) | ![5](./screenshots/chrome/en/5.png) | | - View all your assigned Redmine issues grouped by projects -- Filter issues by projects +- Filter issues by project and status - Group issues by target version -- Search for issues (press `CTRL` + `K` or `CTRL` + `F`) -- Start, stop and edit the timer for your current tasks -- Create entry for time spent (and for multiple users at once) +- Search for issues (`CTRL` + `K` or `CTRL` + `F`) +- Start, stop and edit timers for your tasks +- Create time entries (also for multiple users at once) - Update done ratio for issues -- Pin and unpin issues (display at the top of the project) +- Pin and unpin issues (display at the top) - Remember and forget issue (not assigned to you) - View time entries for current and last week - Multiple languages - Dark & light mode (system default) -# Requirements +## 🌐 Supported languages + +- English +- German +- Russian (thanks [@ASM-Development](https://github.com/ASM-Development)) +- French (thanks [@S8N02000](https://github.com/S8N02000)) + +> If you want to add more languages or extend existing ones, feel free to contribute. Just create a pull request with the desired changes. The language files are located under [src/lang](src/lang) and [public/\_locales](public/_locales). + +## πŸ› οΈ Requirements -At least Redmine version `3.0` or higher required. Recommended version `5.0` or higher. +Supported browsers: + +- **Chrome 122** or higher +- **Firefox 127** or higher + +Supported Redmine versions: + +At least **Redmine version `3.0` or higher** required. Recommended version `5.0` or higher. ### Unsupported features by Redmine versions @@ -52,28 +75,8 @@ At least Redmine version `3.0` or higher required. Recommended version `5.0` or | Select the **default fixed version** when _creating new issues_ | `< 4.1.1` | | Check permissions for admin users who are not members of a project | `< 4.0.0` | | Display project-available time entry activities when _adding spent time entries_ | `< 3.4.0` | -| Extended search | `< 3.3.0` | - -_Tested with Google Chrome Version 130 and Firefox 132_ - -# Supported languages - -- English -- German -- Russian (thanks [@ASM-Development](https://github.com/ASM-Development)) -- French (thanks [@S8N02000](https://github.com/S8N02000)) - -> If you want to add more languages or extend existing ones, feel free to contribute. Just create a pull request with the desired changes. The language files are located under [src/lang](src/lang) and [public/\_locales](public/_locales). - -# Screenshots - -![issues](screenshots/en/dark/issues.png) -![issues-time](screenshots/en/dark/time.png) -![settings](screenshots/en/dark/settings.png) -![issues-search](screenshots/en/dark/issues-search.png) -![issues-add-spent-time](screenshots/en/dark/issues-add-spent-time.png) -![issues-context-menu](screenshots/en/dark/issues-context-menu.png) +| Remote Redmine search | `< 3.3.0` | -# Credits +## Credits -Logo is Copyright (C) 2009 Martin Herr and is licensed under Creative Commons (https://www.redmine.org/projects/redmine/wiki/logo) +Logo is Copyright (C) 2009 Martin Herr and is licensed under Creative Commons ([https://www.redmine.org/projects/redmine/wiki/logo](https://www.redmine.org/projects/redmine/wiki/logo)) diff --git a/components.json b/components.json new file mode 100644 index 00000000..e3125bbf --- /dev/null +++ b/components.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "base-nova", + "rsc": false, + "tsx": true, + "tailwind": { + "config": "", + "css": "src/index.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "iconLibrary": "lucide", + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + } +} diff --git a/eslint.config.js b/eslint.config.js deleted file mode 100644 index fcb170c7..00000000 --- a/eslint.config.js +++ /dev/null @@ -1,43 +0,0 @@ -import js from "@eslint/js"; -import prettierConfig from "eslint-config-prettier"; -import react from "eslint-plugin-react"; -import reactHooks from "eslint-plugin-react-hooks"; -import tailwind from "eslint-plugin-tailwindcss"; -import globals from "globals"; -import ts from "typescript-eslint"; - -/** @type {import('eslint').Linter.Config[]} */ -export default [ - // Ignore - { ignores: ["dist"] }, - // Base - { - files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"], - settings: { - react: { - version: "detect", - }, - }, - }, - { - languageOptions: { globals: globals.browser }, - }, - // TypeScript - js.configs.recommended, - ...ts.configs.recommended, - // React - react.configs.flat.recommended, - { - plugins: { - "react-hooks": reactHooks, - }, - rules: { - "react/react-in-jsx-scope": "off", - ...reactHooks.configs.recommended.rules, - }, - }, - // Prettier - prettierConfig, - // Tailwind CSS - ...tailwind.configs["flat/recommended"], -]; diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 00000000..acf6b033 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,72 @@ +import js from "@eslint/js"; +import tanstackQuery from "@tanstack/eslint-plugin-query"; +import tanstackRouter from "@tanstack/eslint-plugin-router"; +import prettierConfig from "eslint-config-prettier"; +import react from "eslint-plugin-react"; +import reactHooks from "eslint-plugin-react-hooks"; +import globals from "globals"; +import ts from "typescript-eslint"; + +/** @type {import('eslint').Linter.Config[]} */ +export default [ + // Ignore + { ignores: ["dist"] }, + // Base + { + files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"], + settings: { + react: { + version: "detect", + }, + }, + }, + { + languageOptions: { globals: globals.browser }, + }, + // TypeScript + js.configs.recommended, + ...ts.configs.recommended, + // React + react.configs.flat.recommended, + { + plugins: { + "react-hooks": reactHooks, + }, + rules: { + "react/react-in-jsx-scope": "off", + ...reactHooks.configs.recommended.rules, + }, + }, + // Prettier + prettierConfig, + // Tailwind CSS + //...tailwind.configs["flat/recommended"], // TODO: Wait until working with Tailwind CSS v4, + // Tanstack + ...tanstackRouter.configs["flat/recommended"], + ...tanstackQuery.configs["flat/recommended"], + // Customizations + { + rules: { + "@tanstack/query/exhaustive-deps": [ + "error", + { + allowlist: { + types: ["RedmineApiClient"], + }, + }, + ], + "@typescript-eslint/no-unused-vars": [ + "error", + { + args: "all", + argsIgnorePattern: "^_", + caughtErrors: "all", + caughtErrorsIgnorePattern: "^_", + destructuredArrayIgnorePattern: "^_", + varsIgnorePattern: "^_", + ignoreRestSiblings: true, + }, + ], + }, + }, +]; diff --git a/fixtures/chromeExtension.ts b/fixtures/chromeExtension.ts deleted file mode 100644 index 5d7cb08d..00000000 --- a/fixtures/chromeExtension.ts +++ /dev/null @@ -1,74 +0,0 @@ -/* eslint-disable react-hooks/rules-of-hooks */ -import { test as base, chromium, type BrowserContext, type Page } from "@playwright/test"; -import "dotenv/config"; -import path from "path"; - -export const test = base.extend<{ - context: BrowserContext; - extensionId: string; - issuesPage: Page; - timePage: Page; - settingsPage: Page; -}>({ - // eslint-disable-next-line no-empty-pattern - context: async ({}, use) => { - const pathToExtension = path.join(process.cwd(), "dist"); - const context = await chromium.launchPersistentContext("", { - headless: false, - args: [process.env.CI ? `--headless=new` : "", `--disable-extensions-except=${pathToExtension}`, `--load-extension=${pathToExtension}`], - }); - - await use(context); - await context.close(); - }, - extensionId: async ({ context }, use) => { - let [background] = context.serviceWorkers(); - if (!background) background = await context.waitForEvent("serviceworker"); - - const extensionId = background.url().split("/")[2]; - - await use(extensionId); - }, - page: async ({ extensionId, page }, use) => { - // To to settings page - await page.goto(`chrome-extension://${extensionId}/index.html#/settings`); - - // Wait for redmine url and api key inputs - await page.waitForSelector('[name="redmineURL"]'); - await page.waitForTimeout(100); - - // Insert redmine url and api key - await page.fill('[name="redmineURL"]', process.env.REDMINE_URL!); - await page.fill('[name="redmineApiKey"]', process.env.REDMINE_API_KEY!); - - // Save settings - await page.click('[type="submit"]'); - - // Wait for alert (settings saved) - await page.waitForSelector('[role="alert"]'); - - // Go to default page - await page.goto(`chrome-extension://${extensionId}/index.html`); - - await use(page); - }, - issuesPage: async ({ extensionId, page }, use) => { - // Go to issues page - await page.goto(`chrome-extension://${extensionId}/index.html?location=popup#/issues`); - - await use(page); - }, - timePage: async ({ extensionId, page }, use) => { - // Go to time page - await page.goto(`chrome-extension://${extensionId}/index.html?location=popup#/time`); - - await use(page); - }, - settingsPage: async ({ extensionId, page }, use) => { - // Go to settings page - await page.goto(`chrome-extension://${extensionId}/index.html?location=popup#/settings`); - - await use(page); - }, -}); -export const expect = test.expect; diff --git a/package.json b/package.json index fe3f26b5..36e279f3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "redmine-time-tracking", - "description": "Redmine Time Tracking", - "version": "1.21.2", + "description": "Start-stop timer for Redmine", + "version": "2.0.0-beta.7", "author": { "name": "CrawlerCode", "email": "crawlercode@outlook.de" @@ -12,84 +12,96 @@ }, "type": "module", "scripts": { - "dev:chrome": "tsc && cross-env PLATFORM=chrome vite build --watch --mode development", - "dev:firefox": "tsc && cross-env PLATFORM=firefox vite build --watch --mode development", - "build": "pnpm run build:chrome && pnpm run build:firefox", - "build:chrome": "tsc && cross-env PLATFORM=chrome vite build", - "build:firefox": "tsc && cross-env PLATFORM=firefox vite build", - "release": "gh release create v%npm_package_version% --notes-file release_notes.md --generate-notes", - "lint": "eslint --fix src tests fixtures", - "format": "prettier --write src tests public fixtures", - "test": "playwright test" + "postinstall": "wxt prepare", + "dev:chrome": "wxt -b chrome", + "dev:firefox": "wxt -b firefox --mv2", + "build:chrome": "wxt build -b chrome", + "build:firefox": "wxt build -b firefox --mv3", + "build:chrome:pre-release": "cross-env NODE_ENV=production wxt zip -b chrome --mode pre-release", + "build:firefox:pre-release": "cross-env NODE_ENV=production wxt zip -b firefox --mv3 --mode pre-release", + "build:chrome:release": "cross-env NODE_ENV=production wxt zip -b chrome --mode release", + "build:firefox:release": "cross-env NODE_ENV=production wxt zip -b firefox --mv3 --mode release", + "format": "prettier --write .", + "lint:all": "pnpm run lint:eslint && pnpm run lint:ts && pnpm run lint:stylelint && pnpm run lint:htmlhint && pnpm run lint:lang && pnpm run lint:react-doctor", + "lint:eslint": "eslint --fix src tests", + "lint:ts": "tsc --noEmit", + "lint:stylelint": "stylelint --fix src/**/*.css", + "lint:htmlhint": "pnpx htmlhint --config .github/linters/.htmlhintrc src/**/*.html", + "lint:lang": "formatjs verify --source-locale en --missing-keys src/lang/*.json", + "lint:react-doctor": "pnpx react-doctor@latest -y --verbose .", + "test": "playwright test", + "test:update-snapshots": "playwright test --update-snapshots=changed", + "generate-store-screenshots": "tsx screenshots/generate-store-screenshots.ts", + "release": "semantic-release" }, "dependencies": { - "@fortawesome/fontawesome-svg-core": "^6.7.2", - "@fortawesome/free-brands-svg-icons": "^6.7.2", - "@fortawesome/free-regular-svg-icons": "^6.7.2", - "@fortawesome/free-solid-svg-icons": "^6.7.2", - "@fortawesome/react-fontawesome": "^0.2.2", - "@tanstack/query-async-storage-persister": "^5.66.0", - "@tanstack/react-query": "^5.66.0", - "@tanstack/react-query-devtools": "^5.66.0", - "@tanstack/react-query-persist-client": "^5.66.0", - "axios": "^1.7.9", + "@base-ui/react": "^1.4.0", + "@tanstack/query-async-storage-persister": "^5.99.0", + "@tanstack/react-form": "^1.29.0", + "@tanstack/react-query": "^5.99.0", + "@tanstack/react-query-devtools": "^5.99.0", + "@tanstack/react-query-persist-client": "^5.99.0", + "@tanstack/react-router": "^1.168.22", + "axios": "^1.15.0", + "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", - "country-flag-icons": "^1.5.14", - "date-fns": "^3.6.0", + "country-flag-icons": "^1.6.16", + "date-fns": "^4.1.0", "deepmerge": "^4.3.1", - "flatpickr": "^4.6.13", - "formik": "^2.4.6", - "qs": "^6.14.0", - "react": "^19.0.0", - "react-dom": "^19.0.0", - "react-flatpickr": "^3.10.13", - "react-intl": "^7.1.5", - "react-router-dom": "^7.1.5", - "react-select": "^5.10.0", - "react-tooltip": "^5.28.0", - "tailwind-merge": "^2.6.0", - "tailwindcss-shadow-fill": "^1.0.1", - "tailwindcss-text-fill": "^0.2.0", - "yup": "^1.6.1" + "lucide-react": "^1.8.0", + "qs": "^6.15.1", + "react": "^19.2.5", + "react-day-picker": "^9.14.0", + "react-dom": "^19.2.5", + "react-intl": "^10.1.2", + "sonner": "^2.0.7", + "tailwind-merge": "^3.5.0", + "usehooks-ts": "^3.1.1", + "zod": "^4.3.6" }, "devDependencies": { - "@eslint/js": "^9.19.0", - "@playwright/test": "^1.50.1", - "@types/chrome": "^0.0.301", - "@types/node": "^22.13.1", - "@types/qs": "^6.9.18", - "@types/react": "^19.0.8", - "@types/react-dom": "^19.0.3", - "@types/react-flatpickr": "^3.8.11", - "@typescript-eslint/eslint-plugin": "^8.23.0", - "@typescript-eslint/parser": "^8.23.0", - "@vitejs/plugin-react": "^4.3.4", - "autoprefixer": "^10.4.20", - "cross-env": "^7.0.3", - "dotenv": "^16.4.7", - "eslint": "^9.19.0", - "eslint-config-prettier": "^10.0.1", - "eslint-plugin-react": "^7.37.4", - "eslint-plugin-react-hooks": "^5.1.0", - "eslint-plugin-tailwindcss": "^3.18.0", - "globals": "^15.14.0", - "postcss": "^8.5.1", - "prettier": "^3.4.2", - "prettier-plugin-tailwindcss": "^0.6.11", - "sharp": "^0.33.5", - "tailwindcss": "^3.4.17", - "tailwindcss-animate": "^1.0.7", - "typescript": "^5.7.3", - "typescript-eslint": "^8.23.0", - "vite": "^6.1.0", - "vite-plugin-static-copy": "^2.2.0", - "vite-plugin-zip-pack": "^1.2.4" + "@eslint/js": "^9.39.4", + "@formatjs/cli": "^6.14.2", + "@playwright/test": "^1.59.1", + "@rolldown/plugin-babel": "^0.2.3", + "@semantic-release/changelog": "^6.0.3", + "@semantic-release/git": "^10.0.1", + "@tailwindcss/vite": "^4.2.2", + "@tanstack/eslint-plugin-query": "^5.99.0", + "@tanstack/eslint-plugin-router": "^1.161.6", + "@tanstack/router-plugin": "^1.167.22", + "@types/chrome": "^0.1.40", + "@types/node": "^24.12.2", + "@types/qs": "^6.15.0", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@typescript-eslint/eslint-plugin": "^8.58.2", + "@typescript-eslint/parser": "^8.58.2", + "@vitejs/plugin-react": "^6.0.1", + "babel-plugin-react-compiler": "1.0.0", + "conventional-changelog-conventionalcommits": "^9.3.1", + "cross-env": "^10.1.0", + "dotenv": "^17.4.2", + "eslint": "^9.39.4", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-react": "^7.37.5", + "eslint-plugin-react-hooks": "^7.1.1", + "eslint-plugin-tailwindcss": "^3.18.3", + "globals": "^17.5.0", + "prettier": "^3.8.3", + "prettier-plugin-tailwindcss": "^0.7.2", + "semantic-release": "^25.0.3", + "shadcn": "^4.3.0", + "sharp": "^0.34.5", + "stylelint": "^17.8.0", + "stylelint-config-standard": "^40.0.0", + "stylelint-config-tailwindcss": "^1.0.1", + "tailwindcss": "^4.2.2", + "tw-animate-css": "^1.4.0", + "typescript": "^6.0.3", + "typescript-eslint": "^8.58.2", + "vite": "^8.0.8", + "wxt": "^0.20.25" }, - "packageManager": "pnpm@10.2.0", - "pnpm": { - "onlyBuiltDependencies": [ - "esbuild", - "sharp" - ] - } + "packageManager": "pnpm@10.33.0" } diff --git a/playwright.config.ts b/playwright.config.ts index 38bf7acd..6246cdbd 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -1,7 +1,7 @@ import { defineConfig, devices } from "@playwright/test"; -const LANGUAGES = ["en", "de", "ru", "fr"] as const; -const COLOR_SCHEMES = ["dark", "light"] as const; +const LANGUAGES = ["en", "de", "fr", "ru"] as const; +const COLOR_SCHEMES = ["dark"] as const; /** * @see https://playwright.dev/docs/test-configuration. @@ -9,21 +9,32 @@ const COLOR_SCHEMES = ["dark", "light"] as const; export default defineConfig({ testDir: "./tests", fullyParallel: true, - forbidOnly: !!process.env.CI, - retries: process.env.CI ? 2 : 1, - workers: process.env.CI ? 1 : undefined, + retries: 1, + workers: 3, + timeout: 10_000, reporter: [["list"], ["html"]], use: { trace: "on-first-retry", screenshot: "only-on-failure", }, - + expect: { + toHaveScreenshot: { + maxDiffPixelRatio: 0.02, + pathTemplate: "{testDir}/screenshots{/projectName}/{testFilePath}/{testName}{ext}", + }, + }, projects: [ ...LANGUAGES.map((locale) => COLOR_SCHEMES.map((colorScheme) => ({ - name: `Chrome | ${locale} (${colorScheme})`, + name: `Chrome popup | ${colorScheme}/${locale}`, use: { ...devices["Desktop Chrome"], viewport: { width: 320, height: 548 }, colorScheme, locale, timezoneId: "Europe/Berlin" }, })) ).flat(), + ...LANGUAGES.map((locale) => + COLOR_SCHEMES.map((colorScheme) => ({ + name: `Chrome fullscreen | ${colorScheme}/${locale}`, + use: { ...devices["Desktop Chrome"], viewport: { width: 1280, height: 720 }, colorScheme, locale, timezoneId: "Europe/Berlin" }, + })) + ).flat(), ], }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6ee988c0..e5e62881 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,714 +8,1004 @@ importers: .: dependencies: - '@fortawesome/fontawesome-svg-core': - specifier: ^6.7.2 - version: 6.7.2 - '@fortawesome/free-brands-svg-icons': - specifier: ^6.7.2 - version: 6.7.2 - '@fortawesome/free-regular-svg-icons': - specifier: ^6.7.2 - version: 6.7.2 - '@fortawesome/free-solid-svg-icons': - specifier: ^6.7.2 - version: 6.7.2 - '@fortawesome/react-fontawesome': - specifier: ^0.2.2 - version: 0.2.2(@fortawesome/fontawesome-svg-core@6.7.2)(react@19.0.0) + '@base-ui/react': + specifier: ^1.4.0 + version: 1.4.0(@date-fns/tz@1.4.1)(@types/react@19.2.14)(date-fns@4.1.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@tanstack/query-async-storage-persister': - specifier: ^5.66.0 - version: 5.66.0 + specifier: ^5.99.0 + version: 5.99.0 + '@tanstack/react-form': + specifier: ^1.29.0 + version: 1.29.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@tanstack/react-query': - specifier: ^5.66.0 - version: 5.66.0(react@19.0.0) + specifier: ^5.99.0 + version: 5.99.0(react@19.2.5) '@tanstack/react-query-devtools': - specifier: ^5.66.0 - version: 5.66.0(@tanstack/react-query@5.66.0(react@19.0.0))(react@19.0.0) + specifier: ^5.99.0 + version: 5.99.0(@tanstack/react-query@5.99.0(react@19.2.5))(react@19.2.5) '@tanstack/react-query-persist-client': - specifier: ^5.66.0 - version: 5.66.0(@tanstack/react-query@5.66.0(react@19.0.0))(react@19.0.0) + specifier: ^5.99.0 + version: 5.99.0(@tanstack/react-query@5.99.0(react@19.2.5))(react@19.2.5) + '@tanstack/react-router': + specifier: ^1.168.22 + version: 1.168.22(react-dom@19.2.5(react@19.2.5))(react@19.2.5) axios: - specifier: ^1.7.9 - version: 1.7.9 + specifier: ^1.15.0 + version: 1.15.0 + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 clsx: specifier: ^2.1.1 version: 2.1.1 country-flag-icons: - specifier: ^1.5.14 - version: 1.5.14 + specifier: ^1.6.16 + version: 1.6.16 date-fns: - specifier: ^3.6.0 - version: 3.6.0 + specifier: ^4.1.0 + version: 4.1.0 deepmerge: specifier: ^4.3.1 version: 4.3.1 - flatpickr: - specifier: ^4.6.13 - version: 4.6.13 - formik: - specifier: ^2.4.6 - version: 2.4.6(react@19.0.0) + lucide-react: + specifier: ^1.8.0 + version: 1.8.0(react@19.2.5) qs: - specifier: ^6.14.0 - version: 6.14.0 + specifier: ^6.15.1 + version: 6.15.1 react: - specifier: ^19.0.0 - version: 19.0.0 + specifier: ^19.2.5 + version: 19.2.5 + react-day-picker: + specifier: ^9.14.0 + version: 9.14.0(react@19.2.5) react-dom: - specifier: ^19.0.0 - version: 19.0.0(react@19.0.0) - react-flatpickr: - specifier: ^3.10.13 - version: 3.10.13(react@19.0.0) + specifier: ^19.2.5 + version: 19.2.5(react@19.2.5) react-intl: - specifier: ^7.1.5 - version: 7.1.5(react@19.0.0)(typescript@5.7.3) - react-router-dom: - specifier: ^7.1.5 - version: 7.1.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react-select: - specifier: ^5.10.0 - version: 5.10.0(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react-tooltip: - specifier: ^5.28.0 - version: 5.28.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + specifier: ^10.1.2 + version: 10.1.2(@types/react@19.2.14)(react@19.2.5) + sonner: + specifier: ^2.0.7 + version: 2.0.7(react-dom@19.2.5(react@19.2.5))(react@19.2.5) tailwind-merge: - specifier: ^2.6.0 - version: 2.6.0 - tailwindcss-shadow-fill: - specifier: ^1.0.1 - version: 1.0.1(tailwindcss@3.4.17) - tailwindcss-text-fill: - specifier: ^0.2.0 - version: 0.2.0(tailwindcss@3.4.17) - yup: - specifier: ^1.6.1 - version: 1.6.1 + specifier: ^3.5.0 + version: 3.5.0 + usehooks-ts: + specifier: ^3.1.1 + version: 3.1.1(react@19.2.5) + zod: + specifier: ^4.3.6 + version: 4.3.6 devDependencies: '@eslint/js': - specifier: ^9.19.0 - version: 9.19.0 + specifier: ^9.39.4 + version: 9.39.4 + '@formatjs/cli': + specifier: ^6.14.2 + version: 6.14.2 '@playwright/test': - specifier: ^1.50.1 - version: 1.50.1 + specifier: ^1.59.1 + version: 1.59.1 + '@rolldown/plugin-babel': + specifier: ^0.2.3 + version: 0.2.3(@babel/core@7.29.0)(@babel/runtime@7.29.2)(rolldown@1.0.0-rc.15)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.7.1)) + '@semantic-release/changelog': + specifier: ^6.0.3 + version: 6.0.3(semantic-release@25.0.3(typescript@6.0.3)) + '@semantic-release/git': + specifier: ^10.0.1 + version: 10.0.1(semantic-release@25.0.3(typescript@6.0.3)) + '@tailwindcss/vite': + specifier: ^4.2.2 + version: 4.2.2(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.7.1)) + '@tanstack/eslint-plugin-query': + specifier: ^5.99.0 + version: 5.99.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3) + '@tanstack/eslint-plugin-router': + specifier: ^1.161.6 + version: 1.161.6(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3) + '@tanstack/router-plugin': + specifier: ^1.167.22 + version: 1.167.22(@tanstack/react-router@1.168.22(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.7.1)) '@types/chrome': - specifier: ^0.0.301 - version: 0.0.301 + specifier: ^0.1.40 + version: 0.1.40 '@types/node': - specifier: ^22.13.1 - version: 22.13.1 + specifier: ^24.12.2 + version: 24.12.2 '@types/qs': - specifier: ^6.9.18 - version: 6.9.18 + specifier: ^6.15.0 + version: 6.15.0 '@types/react': - specifier: ^19.0.8 - version: 19.0.8 + specifier: ^19.2.14 + version: 19.2.14 '@types/react-dom': - specifier: ^19.0.3 - version: 19.0.3(@types/react@19.0.8) - '@types/react-flatpickr': - specifier: ^3.8.11 - version: 3.8.11 + specifier: ^19.2.3 + version: 19.2.3(@types/react@19.2.14) '@typescript-eslint/eslint-plugin': - specifier: ^8.23.0 - version: 8.23.0(@typescript-eslint/parser@8.23.0(eslint@9.19.0(jiti@1.21.6))(typescript@5.7.3))(eslint@9.19.0(jiti@1.21.6))(typescript@5.7.3) + specifier: ^8.58.2 + version: 8.58.2(@typescript-eslint/parser@8.58.2(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3))(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3) '@typescript-eslint/parser': - specifier: ^8.23.0 - version: 8.23.0(eslint@9.19.0(jiti@1.21.6))(typescript@5.7.3) + specifier: ^8.58.2 + version: 8.58.2(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3) '@vitejs/plugin-react': - specifier: ^4.3.4 - version: 4.3.4(vite@6.1.0(@types/node@22.13.1)(jiti@1.21.6)(yaml@2.6.1)) - autoprefixer: - specifier: ^10.4.20 - version: 10.4.20(postcss@8.5.1) + specifier: ^6.0.1 + version: 6.0.1(@rolldown/plugin-babel@0.2.3(@babel/core@7.29.0)(@babel/runtime@7.29.2)(rolldown@1.0.0-rc.15)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.7.1)))(babel-plugin-react-compiler@1.0.0)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.7.1)) + babel-plugin-react-compiler: + specifier: 1.0.0 + version: 1.0.0 + conventional-changelog-conventionalcommits: + specifier: ^9.3.1 + version: 9.3.1 cross-env: - specifier: ^7.0.3 - version: 7.0.3 + specifier: ^10.1.0 + version: 10.1.0 dotenv: - specifier: ^16.4.7 - version: 16.4.7 + specifier: ^17.4.2 + version: 17.4.2 eslint: - specifier: ^9.19.0 - version: 9.19.0(jiti@1.21.6) + specifier: ^9.39.4 + version: 9.39.4(jiti@2.6.1) eslint-config-prettier: - specifier: ^10.0.1 - version: 10.0.1(eslint@9.19.0(jiti@1.21.6)) + specifier: ^10.1.8 + version: 10.1.8(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-react: - specifier: ^7.37.4 - version: 7.37.4(eslint@9.19.0(jiti@1.21.6)) + specifier: ^7.37.5 + version: 7.37.5(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-react-hooks: - specifier: ^5.1.0 - version: 5.1.0(eslint@9.19.0(jiti@1.21.6)) + specifier: ^7.1.1 + version: 7.1.1(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-tailwindcss: - specifier: ^3.18.0 - version: 3.18.0(tailwindcss@3.4.17) + specifier: ^3.18.3 + version: 3.18.3(tailwindcss@4.2.2) globals: - specifier: ^15.14.0 - version: 15.14.0 - postcss: - specifier: ^8.5.1 - version: 8.5.1 + specifier: ^17.5.0 + version: 17.5.0 prettier: - specifier: ^3.4.2 - version: 3.4.2 + specifier: ^3.8.3 + version: 3.8.3 prettier-plugin-tailwindcss: - specifier: ^0.6.11 - version: 0.6.11(prettier@3.4.2) + specifier: ^0.7.2 + version: 0.7.2(prettier@3.8.3) + semantic-release: + specifier: ^25.0.3 + version: 25.0.3(typescript@6.0.3) + shadcn: + specifier: ^4.3.0 + version: 4.3.0(@types/node@24.12.2)(typescript@6.0.3) sharp: - specifier: ^0.33.5 - version: 0.33.5 + specifier: ^0.34.5 + version: 0.34.5 + stylelint: + specifier: ^17.8.0 + version: 17.8.0(typescript@6.0.3) + stylelint-config-standard: + specifier: ^40.0.0 + version: 40.0.0(stylelint@17.8.0(typescript@6.0.3)) + stylelint-config-tailwindcss: + specifier: ^1.0.1 + version: 1.0.1(stylelint@17.8.0(typescript@6.0.3))(tailwindcss@4.2.2) tailwindcss: - specifier: ^3.4.17 - version: 3.4.17 - tailwindcss-animate: - specifier: ^1.0.7 - version: 1.0.7(tailwindcss@3.4.17) + specifier: ^4.2.2 + version: 4.2.2 + tw-animate-css: + specifier: ^1.4.0 + version: 1.4.0 typescript: - specifier: ^5.7.3 - version: 5.7.3 + specifier: ^6.0.3 + version: 6.0.3 typescript-eslint: - specifier: ^8.23.0 - version: 8.23.0(eslint@9.19.0(jiti@1.21.6))(typescript@5.7.3) + specifier: ^8.58.2 + version: 8.58.2(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3) vite: - specifier: ^6.1.0 - version: 6.1.0(@types/node@22.13.1)(jiti@1.21.6)(yaml@2.6.1) - vite-plugin-static-copy: - specifier: ^2.2.0 - version: 2.2.0(vite@6.1.0(@types/node@22.13.1)(jiti@1.21.6)(yaml@2.6.1)) - vite-plugin-zip-pack: - specifier: ^1.2.4 - version: 1.2.4(vite@6.1.0(@types/node@22.13.1)(jiti@1.21.6)(yaml@2.6.1)) + specifier: ^8.0.8 + version: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.7.1) + wxt: + specifier: ^0.20.25 + version: 0.20.25(@types/node@24.12.2)(eslint@9.39.4(jiti@2.6.1))(jiti@2.6.1)(rollup@4.59.0)(tsx@4.21.0)(yaml@2.7.1) packages: - '@aashutoshrathi/word-wrap@1.2.6': - resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} - engines: {node: '>=0.10.0'} + '@1natsu/wait-element@4.2.0': + resolution: {integrity: sha512-Om0Q+WE9mNrpY4AwMTvkFiYHv8VM7TML3PvOqXy+w6kAjLjKhGYHYX+305+a6J8RVpds9s7IF2Z5aOPYwULFNw==} - '@alloc/quick-lru@5.2.0': - resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} - engines: {node: '>=10'} + '@actions/core@3.0.0': + resolution: {integrity: sha512-zYt6cz+ivnTmiT/ksRVriMBOiuoUpDCJJlZ5KPl2/FRdvwU3f7MPh9qftvbkXJThragzUZieit2nyHUyw53Seg==} - '@ampproject/remapping@2.2.1': - resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} - engines: {node: '>=6.0.0'} + '@actions/exec@3.0.0': + resolution: {integrity: sha512-6xH/puSoNBXb72VPlZVm7vQ+svQpFyA96qdDBvhB8eNZOE8LtPf9L4oAsfzK/crCL8YZ+19fKYVnM63Sl+Xzlw==} + + '@actions/http-client@4.0.0': + resolution: {integrity: sha512-QuwPsgVMsD6qaPD57GLZi9sqzAZCtiJT8kVBCDpLtxhL5MydQ4gS+DrejtZZPdIYyB1e95uCK9Luyds7ybHI3g==} + + '@actions/io@3.0.2': + resolution: {integrity: sha512-nRBchcMM+QK1pdjO7/idu86rbJI5YHUKCvKs0KxnSYbVe3F51UfGxuZX4Qy/fWlp6l7gWFwIkrOzN+oUK03kfw==} + + '@aklinker1/rollup-plugin-visualizer@5.12.0': + resolution: {integrity: sha512-X24LvEGw6UFmy0lpGJDmXsMyBD58XmX1bbwsaMLhNoM+UMQfQ3b2RtC+nz4b/NoRK5r6QJSKJHBNVeUdwqybaQ==} + engines: {node: '>=14'} + hasBin: true + peerDependencies: + rollup: 2.x || 3.x || 4.x + peerDependenciesMeta: + rollup: + optional: true + + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.29.0': + resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.28.6': + resolution: {integrity: sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 - '@babel/code-frame@7.26.2': - resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.26.2': - resolution: {integrity: sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==} + '@babel/helper-member-expression-to-functions@7.28.5': + resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} engines: {node: '>=6.9.0'} - '@babel/core@7.26.0': - resolution: {integrity: sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==} + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} engines: {node: '>=6.9.0'} - '@babel/generator@7.26.2': - resolution: {integrity: sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==} + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 - '@babel/helper-compilation-targets@7.25.9': - resolution: {integrity: sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==} + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.25.9': - resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} + '@babel/helper-plugin-utils@7.28.6': + resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.26.0': - resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} + '@babel/helper-replace-supers@7.28.6': + resolution: {integrity: sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-plugin-utils@7.25.9': - resolution: {integrity: sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==} + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.25.9': - resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.25.9': - resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.25.9': - resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.26.0': - resolution: {integrity: sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==} + '@babel/helpers@7.29.2': + resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} engines: {node: '>=6.9.0'} - '@babel/parser@7.26.2': - resolution: {integrity: sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==} + '@babel/parser@7.29.2': + resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/plugin-transform-react-jsx-self@7.25.9': - resolution: {integrity: sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==} + '@babel/plugin-syntax-jsx@7.28.6': + resolution: {integrity: sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx-source@7.25.9': - resolution: {integrity: sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==} + '@babel/plugin-syntax-typescript@7.28.6': + resolution: {integrity: sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/runtime@7.24.0': - resolution: {integrity: sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==} + '@babel/plugin-transform-modules-commonjs@7.28.6': + resolution: {integrity: sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==} engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@babel/template@7.25.9': - resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} + '@babel/plugin-transform-typescript@7.28.6': + resolution: {integrity: sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==} engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@babel/traverse@7.25.9': - resolution: {integrity: sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==} + '@babel/preset-typescript@7.28.5': + resolution: {integrity: sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==} engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 - '@babel/types@7.26.0': - resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} + '@babel/runtime@7.28.2': + resolution: {integrity: sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==} engines: {node: '>=6.9.0'} - '@emnapi/runtime@1.2.0': - resolution: {integrity: sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==} + '@babel/runtime@7.29.2': + resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} + engines: {node: '>=6.9.0'} - '@emotion/babel-plugin@11.11.0': - resolution: {integrity: sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==} + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} - '@emotion/cache@11.11.0': - resolution: {integrity: sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==} + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + engines: {node: '>=6.9.0'} - '@emotion/hash@0.9.1': - resolution: {integrity: sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==} + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} - '@emotion/memoize@0.8.1': - resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==} + '@base-ui/react@1.4.0': + resolution: {integrity: sha512-QcqdVbr/+ba2/RAKJIV1PV6S02Q5+r6a4Eym8ndBw+ZbBILkkmQAyRxXCg/pArrHnkrGeU8goe26aw0h6eE8pg==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@date-fns/tz': ^1.2.0 + '@types/react': ^17 || ^18 || ^19 + date-fns: ^4.0.0 + react: ^17 || ^18 || ^19 + react-dom: ^17 || ^18 || ^19 + peerDependenciesMeta: + '@types/react': + optional: true - '@emotion/react@11.11.1': - resolution: {integrity: sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==} + '@base-ui/utils@0.2.7': + resolution: {integrity: sha512-nXYKhiL/0JafyJE8PfcflipGftOftlIwKd72rU15iZ1M5yqgg5J9P8NHU71GReDuXco5MJA/eVQqUT5WRqX9sA==} peerDependencies: - '@types/react': '*' - react: '>=16.8.0' + '@types/react': ^17 || ^18 || ^19 + react: ^17 || ^18 || ^19 + react-dom: ^17 || ^18 || ^19 peerDependenciesMeta: '@types/react': optional: true - '@emotion/serialize@1.1.2': - resolution: {integrity: sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==} + '@cacheable/memory@2.0.8': + resolution: {integrity: sha512-FvEb29x5wVwu/Kf93IWwsOOEuhHh6dYCJF3vcKLzXc0KXIW181AOzv6ceT4ZpBHDvAfG60eqb+ekmrnLHIy+jw==} - '@emotion/sheet@1.2.2': - resolution: {integrity: sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==} + '@cacheable/utils@2.4.1': + resolution: {integrity: sha512-eiFgzCbIneyMlLOmNG4g9xzF7Hv3Mga4LjxjcSC/ues6VYq2+gUbQI8JqNuw/ZM8tJIeIaBGpswAsqV2V7ApgA==} - '@emotion/unitless@0.8.1': - resolution: {integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==} + '@colors/colors@1.5.0': + resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} + engines: {node: '>=0.1.90'} - '@emotion/use-insertion-effect-with-fallbacks@1.0.1': - resolution: {integrity: sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==} + '@csstools/css-calc@3.2.0': + resolution: {integrity: sha512-bR9e6o2BDB12jzN/gIbjHa5wLJ4UjD1CB9pM7ehlc0ddk6EBz+yYS1EV2MF55/HUxrHcB/hehAyt5vhsA3hx7w==} + engines: {node: '>=20.19.0'} peerDependencies: - react: '>=16.8.0' + '@csstools/css-parser-algorithms': ^4.0.0 + '@csstools/css-tokenizer': ^4.0.0 + + '@csstools/css-parser-algorithms@4.0.0': + resolution: {integrity: sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@csstools/css-tokenizer': ^4.0.0 + + '@csstools/css-syntax-patches-for-csstree@1.1.3': + resolution: {integrity: sha512-SH60bMfrRCJF3morcdk57WklujF4Jr/EsQUzqkarfHXEFcAR1gg7fS/chAE922Sehgzc1/+Tz5H3Ypa1HiEKrg==} + peerDependencies: + css-tree: ^3.2.1 + peerDependenciesMeta: + css-tree: + optional: true + + '@csstools/css-tokenizer@4.0.0': + resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==} + engines: {node: '>=20.19.0'} + + '@csstools/media-query-list-parser@5.0.0': + resolution: {integrity: sha512-T9lXmZOfnam3eMERPsszjY5NK0jX8RmThmmm99FZ8b7z8yMaFZWKwLWGZuTwdO3ddRY5fy13GmmEYZXB4I98Eg==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@csstools/css-parser-algorithms': ^4.0.0 + '@csstools/css-tokenizer': ^4.0.0 + + '@csstools/selector-resolve-nested@4.0.0': + resolution: {integrity: sha512-9vAPxmp+Dx3wQBIUwc1v7Mdisw1kbbaGqXUM8QLTgWg7SoPGYtXBsMXvsFs/0Bn5yoFhcktzxNZGNaUt0VjgjA==} + engines: {node: '>=20.19.0'} + peerDependencies: + postcss-selector-parser: ^7.1.1 + + '@csstools/selector-specificity@6.0.0': + resolution: {integrity: sha512-4sSgl78OtOXEX/2d++8A83zHNTgwCJMaR24FvsYL7Uf/VS8HZk9PTwR51elTbGqMuwH3szLvvOXEaVnqn0Z3zA==} + engines: {node: '>=20.19.0'} + peerDependencies: + postcss-selector-parser: ^7.1.1 + + '@date-fns/tz@1.4.1': + resolution: {integrity: sha512-P5LUNhtbj6YfI3iJjw5EL9eUAG6OitD0W3fWQcpQjDRc/QIsL0tRNuO1PcDvPccWL1fSTXXdE1ds+l95DV/OFA==} - '@emotion/utils@1.2.1': - resolution: {integrity: sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==} + '@devicefarmer/adbkit-logcat@2.1.3': + resolution: {integrity: sha512-yeaGFjNBc/6+svbDeul1tNHtNChw6h8pSHAt5D+JsedUrMTN7tla7B15WLDyekxsuS2XlZHRxpuC6m92wiwCNw==} + engines: {node: '>= 4'} + + '@devicefarmer/adbkit-monkey@1.2.1': + resolution: {integrity: sha512-ZzZY/b66W2Jd6NHbAhLyDWOEIBWC11VizGFk7Wx7M61JZRz7HR9Cq5P+65RKWUU7u6wgsE8Lmh9nE4Mz+U2eTg==} + engines: {node: '>= 0.10.4'} + + '@devicefarmer/adbkit@3.3.8': + resolution: {integrity: sha512-7rBLLzWQnBwutH2WZ0EWUkQdihqrnLYCUMaB44hSol9e0/cdIhuNFcqZO0xNheAU6qqHVA8sMiLofkYTgb+lmw==} + engines: {node: '>= 0.10.4'} + hasBin: true + + '@dotenvx/dotenvx@1.61.1': + resolution: {integrity: sha512-2OUX4KDKvQA6oa7oESG8eNcV4K/2C5jgrbxUcT0VoH9Zelg6dT+rDYew4w2GmXRV3db0tUaM4QZG3MyJL3fU5Q==} + hasBin: true + + '@ecies/ciphers@0.2.6': + resolution: {integrity: sha512-patgsRPKGkhhoBjETV4XxD0En4ui5fbX0hzayqI3M8tvNMGUoUvmyYAIWwlxBc1KX5cturfqByYdj5bYGRpN9g==} + engines: {bun: '>=1', deno: '>=2.7.10', node: '>=16'} + peerDependencies: + '@noble/ciphers': ^1.0.0 - '@emotion/weak-memoize@0.3.1': - resolution: {integrity: sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==} + '@emnapi/core@1.9.2': + resolution: {integrity: sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==} - '@esbuild/aix-ppc64@0.24.2': - resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==} + '@emnapi/runtime@1.10.0': + resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + + '@emnapi/runtime@1.9.2': + resolution: {integrity: sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==} + + '@emnapi/wasi-threads@1.2.1': + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + + '@epic-web/invariant@1.0.0': + resolution: {integrity: sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==} + + '@esbuild/aix-ppc64@0.27.7': + resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.24.2': - resolution: {integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==} + '@esbuild/android-arm64@0.27.7': + resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.24.2': - resolution: {integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==} + '@esbuild/android-arm@0.27.7': + resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.24.2': - resolution: {integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==} + '@esbuild/android-x64@0.27.7': + resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.24.2': - resolution: {integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==} + '@esbuild/darwin-arm64@0.27.7': + resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.24.2': - resolution: {integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==} + '@esbuild/darwin-x64@0.27.7': + resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.24.2': - resolution: {integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==} + '@esbuild/freebsd-arm64@0.27.7': + resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.24.2': - resolution: {integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==} + '@esbuild/freebsd-x64@0.27.7': + resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.24.2': - resolution: {integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==} + '@esbuild/linux-arm64@0.27.7': + resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.24.2': - resolution: {integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==} + '@esbuild/linux-arm@0.27.7': + resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.24.2': - resolution: {integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==} + '@esbuild/linux-ia32@0.27.7': + resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.24.2': - resolution: {integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==} + '@esbuild/linux-loong64@0.27.7': + resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.24.2': - resolution: {integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==} + '@esbuild/linux-mips64el@0.27.7': + resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.24.2': - resolution: {integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==} + '@esbuild/linux-ppc64@0.27.7': + resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.24.2': - resolution: {integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==} + '@esbuild/linux-riscv64@0.27.7': + resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.24.2': - resolution: {integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==} + '@esbuild/linux-s390x@0.27.7': + resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.24.2': - resolution: {integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==} + '@esbuild/linux-x64@0.27.7': + resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.24.2': - resolution: {integrity: sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==} + '@esbuild/netbsd-arm64@0.27.7': + resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.24.2': - resolution: {integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==} + '@esbuild/netbsd-x64@0.27.7': + resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.24.2': - resolution: {integrity: sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==} + '@esbuild/openbsd-arm64@0.27.7': + resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.24.2': - resolution: {integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==} + '@esbuild/openbsd-x64@0.27.7': + resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/sunos-x64@0.24.2': - resolution: {integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==} + '@esbuild/openharmony-arm64@0.27.7': + resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.27.7': + resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.24.2': - resolution: {integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==} + '@esbuild/win32-arm64@0.27.7': + resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.24.2': - resolution: {integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==} + '@esbuild/win32-ia32@0.27.7': + resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.24.2': - resolution: {integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==} + '@esbuild/win32-x64@0.27.7': + resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} engines: {node: '>=18'} cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.4.0': - resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.12.1': - resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/config-array@0.19.2': - resolution: {integrity: sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==} + '@eslint/config-array@0.21.2': + resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.10.0': - resolution: {integrity: sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==} + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/eslintrc@3.2.0': - resolution: {integrity: sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==} + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.19.0': - resolution: {integrity: sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ==} + '@eslint/eslintrc@3.3.5': + resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/object-schema@2.1.6': - resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} + '@eslint/js@9.39.4': + resolution: {integrity: sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/plugin-kit@0.2.5': - resolution: {integrity: sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==} + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@floating-ui/core@1.2.6': - resolution: {integrity: sha512-EvYTiXet5XqweYGClEmpu3BoxmsQ4hkj3QaYA6qEnigCWffTP3vNRwBReTdrwDwo7OoJ3wM8Uoe9Uk4n+d4hfg==} - - '@floating-ui/dom@1.6.3': - resolution: {integrity: sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==} - - '@floating-ui/utils@0.2.1': - resolution: {integrity: sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==} - - '@formatjs/ecma402-abstract@2.3.2': - resolution: {integrity: sha512-6sE5nyvDloULiyOMbOTJEEgWL32w+VHkZQs8S02Lnn8Y/O5aQhjOEXwWzvR7SsBE/exxlSpY2EsWZgqHbtLatg==} + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@formatjs/fast-memoize@2.2.6': - resolution: {integrity: sha512-luIXeE2LJbQnnzotY1f2U2m7xuQNj2DA8Vq4ce1BY9ebRZaoPB1+8eZ6nXpLzsxuW5spQxr7LdCg+CApZwkqkw==} + '@floating-ui/core@1.7.5': + resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} - '@formatjs/icu-messageformat-parser@2.11.0': - resolution: {integrity: sha512-Hp81uTjjdTk3FLh/dggU5NK7EIsVWc5/ZDWrIldmf2rBuPejuZ13CZ/wpVE2SToyi4EiroPTQ1XJcJuZFIxTtw==} + '@floating-ui/dom@1.7.6': + resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==} - '@formatjs/icu-skeleton-parser@1.8.12': - resolution: {integrity: sha512-QRAY2jC1BomFQHYDMcZtClqHR55EEnB96V7Xbk/UiBodsuFc5kujybzt87+qj1KqmJozFhk6n4KiT1HKwAkcfg==} + '@floating-ui/react-dom@2.1.8': + resolution: {integrity: sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' - '@formatjs/intl-localematcher@0.5.10': - resolution: {integrity: sha512-af3qATX+m4Rnd9+wHcjJ4w2ijq+rAVP3CCinJQvFv1kgSu1W6jypUmvleJxcewdxmutM8dmIRZFxO/IQBZmP2Q==} + '@floating-ui/utils@0.2.11': + resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==} - '@formatjs/intl@3.1.3': - resolution: {integrity: sha512-yWtB1L4vOr17MLII3bcNRmjx6qBkSupJuA6nJz1zVxpWbJXKQL5vgvjRCehTO3z7HolxFjtLdfV0/RN+bC34Fg==} + '@formatjs/cli@6.14.2': + resolution: {integrity: sha512-0aZLIRcrxIf6QU2u04bIorYIVA1Sm8hHlHzlK9ROGB2BLN0WbiBCwK3jAPV9um+pPS6O4ZFT6K9c2j/3iMkmSw==} + engines: {node: '>= 20.12.0'} + hasBin: true peerDependencies: - typescript: '5' + '@glimmer/env': '*' + '@glimmer/reference': '*' + '@glimmer/syntax': ^0.84.3 || ^0.95.0 + '@glimmer/validator': '*' + '@vue/compiler-core': ^3.5.0 + content-tag: ^4.1.0 + vue: ^3.5.0 peerDependenciesMeta: - typescript: + '@glimmer/env': + optional: true + '@glimmer/reference': + optional: true + '@glimmer/syntax': + optional: true + '@glimmer/validator': + optional: true + '@vue/compiler-core': + optional: true + content-tag: + optional: true + vue: optional: true - '@fortawesome/fontawesome-common-types@6.7.2': - resolution: {integrity: sha512-Zs+YeHUC5fkt7Mg1l6XTniei3k4bwG/yo3iFUtZWd/pMx9g3fdvkSK9E0FOC+++phXOka78uJcYb8JaFkW52Xg==} - engines: {node: '>=6'} - - '@fortawesome/fontawesome-svg-core@6.7.2': - resolution: {integrity: sha512-yxtOBWDrdi5DD5o1pmVdq3WMCvnobT0LU6R8RyyVXPvFRd2o79/0NCuQoCjNTeZz9EzA9xS3JxNWfv54RIHFEA==} - engines: {node: '>=6'} + '@formatjs/fast-memoize@3.1.2': + resolution: {integrity: sha512-vPnriihkfK0lzoQGaXq+qXH23VsYyansRTkTgo2aTG0k1NjLFyZimFVdfj4C9JkSE5dm7CEngcQ5TTc1yAyBfQ==} - '@fortawesome/free-brands-svg-icons@6.7.2': - resolution: {integrity: sha512-zu0evbcRTgjKfrr77/2XX+bU+kuGfjm0LbajJHVIgBWNIDzrhpRxiCPNT8DW5AdmSsq7Mcf9D1bH0aSeSUSM+Q==} - engines: {node: '>=6'} + '@formatjs/icu-messageformat-parser@3.5.4': + resolution: {integrity: sha512-JVY39ROgLt+pIYngo6piyj4OVfZmXs/2FkC4wLS+ql1Eig/sGJKB7YwDO/5bkJFkfwaFAeIpgEiJc8hiYxNalw==} - '@fortawesome/free-regular-svg-icons@6.7.2': - resolution: {integrity: sha512-7Z/ur0gvCMW8G93dXIQOkQqHo2M5HLhYrRVC0//fakJXxcF1VmMPsxnG6Ee8qEylA8b8Q3peQXWMNZ62lYF28g==} - engines: {node: '>=6'} + '@formatjs/icu-skeleton-parser@2.1.4': + resolution: {integrity: sha512-8bSFZbrlvGX11ywMZxtgkPBt5Q8/etyts7j7j+GWpOVK1g43zwMIH3LZxk43HAtEP7L/jtZ+OZaMiFTOiBj9CA==} - '@fortawesome/free-solid-svg-icons@6.7.2': - resolution: {integrity: sha512-GsBrnOzU8uj0LECDfD5zomZJIjrPhIlWU82AHwa2s40FKH+kcxQaBvBo3Z4TxyZHIyX8XTDxsyA33/Vx9eFuQA==} - engines: {node: '>=6'} + '@formatjs/intl@4.1.6': + resolution: {integrity: sha512-eQuZCkG7kVBIjMhLhvsRZmYnVbTHBiiM+fNxIbDg7LZ9WXcpWUISuv58baq2dov7vz3qXYtDEgJ9AODZK6idaQ==} - '@fortawesome/react-fontawesome@0.2.2': - resolution: {integrity: sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g==} + '@hono/node-server@1.19.14': + resolution: {integrity: sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==} + engines: {node: '>=18.14.1'} peerDependencies: - '@fortawesome/fontawesome-svg-core': ~1 || ~6 - react: '>=16.3' + hono: ^4 + + '@humanfs/core@0.19.2': + resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} + engines: {node: '>=18.18.0'} - '@humanfs/core@0.19.1': - resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + '@humanfs/node@0.16.8': + resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==} engines: {node: '>=18.18.0'} - '@humanfs/node@0.16.6': - resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + '@humanfs/types@0.15.0': + resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==} engines: {node: '>=18.18.0'} '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} - '@humanwhocodes/retry@0.3.1': - resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} - '@humanwhocodes/retry@0.4.1': - resolution: {integrity: sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==} - engines: {node: '>=18.18'} + '@img/colour@1.1.0': + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} + engines: {node: '>=18'} - '@img/sharp-darwin-arm64@0.33.5': - resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + '@img/sharp-darwin-arm64@0.34.5': + resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [darwin] - '@img/sharp-darwin-x64@0.33.5': - resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + '@img/sharp-darwin-x64@0.34.5': + resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [darwin] - '@img/sharp-libvips-darwin-arm64@1.0.4': - resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + '@img/sharp-libvips-darwin-arm64@1.2.4': + resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} cpu: [arm64] os: [darwin] - '@img/sharp-libvips-darwin-x64@1.0.4': - resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + '@img/sharp-libvips-darwin-x64@1.2.4': + resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} cpu: [x64] os: [darwin] - '@img/sharp-libvips-linux-arm64@1.0.4': - resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + '@img/sharp-libvips-linux-arm64@1.2.4': + resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} cpu: [arm64] os: [linux] + libc: [glibc] - '@img/sharp-libvips-linux-arm@1.0.5': - resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + '@img/sharp-libvips-linux-arm@1.2.4': + resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} cpu: [arm] os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-ppc64@1.2.4': + resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-riscv64@1.2.4': + resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} + cpu: [riscv64] + os: [linux] + libc: [glibc] - '@img/sharp-libvips-linux-s390x@1.0.4': - resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} + '@img/sharp-libvips-linux-s390x@1.2.4': + resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} cpu: [s390x] os: [linux] + libc: [glibc] - '@img/sharp-libvips-linux-x64@1.0.4': - resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} + '@img/sharp-libvips-linux-x64@1.2.4': + resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} cpu: [x64] os: [linux] + libc: [glibc] - '@img/sharp-libvips-linuxmusl-arm64@1.0.4': - resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} cpu: [arm64] os: [linux] + libc: [musl] - '@img/sharp-libvips-linuxmusl-x64@1.0.4': - resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} cpu: [x64] os: [linux] + libc: [musl] - '@img/sharp-linux-arm64@0.33.5': - resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} + '@img/sharp-linux-arm64@0.34.5': + resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [glibc] - '@img/sharp-linux-arm@0.33.5': - resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} + '@img/sharp-linux-arm@0.34.5': + resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] + libc: [glibc] + + '@img/sharp-linux-ppc64@0.34.5': + resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-riscv64@0.34.5': + resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] - '@img/sharp-linux-s390x@0.33.5': - resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} + '@img/sharp-linux-s390x@0.34.5': + resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] + libc: [glibc] - '@img/sharp-linux-x64@0.33.5': - resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} + '@img/sharp-linux-x64@0.34.5': + resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [glibc] - '@img/sharp-linuxmusl-arm64@0.33.5': - resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} + '@img/sharp-linuxmusl-arm64@0.34.5': + resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [musl] - '@img/sharp-linuxmusl-x64@0.33.5': - resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} + '@img/sharp-linuxmusl-x64@0.34.5': + resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [musl] - '@img/sharp-wasm32@0.33.5': - resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} + '@img/sharp-wasm32@0.34.5': + resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [wasm32] - '@img/sharp-win32-ia32@0.33.5': - resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} + '@img/sharp-win32-arm64@0.34.5': + resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.34.5': + resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ia32] os: [win32] - '@img/sharp-win32-x64@0.33.5': - resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + '@img/sharp-win32-x64@0.34.5': + resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [win32] - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} + '@inquirer/ansi@2.0.5': + resolution: {integrity: sha512-doc2sWgJpbFQ64UflSVd17ibMGDuxO1yKgOgLMwavzESnXjFWJqUeG8saYosqKpHp4kWiM5x1nXvEjbpx90gzw==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - '@jridgewell/gen-mapping@0.3.5': - resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} - engines: {node: '>=6.0.0'} + '@inquirer/confirm@6.0.11': + resolution: {integrity: sha512-pTpHjg0iEIRMYV/7oCZUMf27/383E6Wyhfc/MY+AVQGEoUobffIYWOK9YLP2XFRGz/9i6WlTQh1CkFVIo2Y7XA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true - '@jridgewell/resolve-uri@3.1.0': - resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} - engines: {node: '>=6.0.0'} + '@inquirer/core@11.1.8': + resolution: {integrity: sha512-/u+yJk2pOKNDOh1ZgdUH2RQaRx6OOH4I0uwL95qPvTFTIL38YBsuSC4r1yXBB3Q6JvNqFFc202gk0Ew79rrcjA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/figures@2.0.5': + resolution: {integrity: sha512-NsSs4kzfm12lNetHwAn3GEuH317IzpwrMCbOuMIVytpjnJ90YYHNwdRgYGuKmVxwuIqSgqk3M5qqQt1cDk0tGQ==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + + '@inquirer/type@4.0.5': + resolution: {integrity: sha512-aetVUNeKNc/VriqXlw1NRSW0zhMBB0W4bNbWRJgzRl/3d0QNDQFfk0GO5SDdtjMZVg6o8ZKEiadd7SCCzoOn5Q==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} - '@jridgewell/set-array@1.2.1': - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - '@jridgewell/sourcemap-codec@1.4.15': - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@keyv/bigmap@1.3.1': + resolution: {integrity: sha512-WbzE9sdmQtKy8vrNPa9BRnwZh5UF4s1KTmSK0KUVLo3eff5BlQNNWDnFOouNpKfPKDnms9xynJjsMYjMaT/aFQ==} + engines: {node: '>= 18'} + peerDependencies: + keyv: ^5.6.0 + + '@keyv/serialize@1.1.1': + resolution: {integrity: sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==} - '@jridgewell/trace-mapping@0.3.25': - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@modelcontextprotocol/sdk@1.29.0': + resolution: {integrity: sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==} + engines: {node: '>=18'} + peerDependencies: + '@cfworker/json-schema': ^4.1.1 + zod: ^3.25 || ^4.0 + peerDependenciesMeta: + '@cfworker/json-schema': + optional: true + + '@mswjs/interceptors@0.41.3': + resolution: {integrity: sha512-cXu86tF4VQVfwz8W1SPbhoRyHJkti6mjH/XJIxp40jhO4j2k1m4KYrEykxqWPkFF3vrK4rgQppBh//AwyGSXPA==} + engines: {node: '>=18'} + + '@napi-rs/wasm-runtime@1.1.4': + resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 + + '@noble/ciphers@1.3.0': + resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.9.7': + resolution: {integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} + engines: {node: ^14.21.3 || >=16} '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} @@ -729,280 +1019,842 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} + '@octokit/auth-token@6.0.0': + resolution: {integrity: sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==} + engines: {node: '>= 20'} + + '@octokit/core@7.0.6': + resolution: {integrity: sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==} + engines: {node: '>= 20'} + + '@octokit/endpoint@11.0.3': + resolution: {integrity: sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag==} + engines: {node: '>= 20'} + + '@octokit/graphql@9.0.3': + resolution: {integrity: sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==} + engines: {node: '>= 20'} + + '@octokit/openapi-types@27.0.0': + resolution: {integrity: sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==} - '@playwright/test@1.50.1': - resolution: {integrity: sha512-Jii3aBg+CEDpgnuDxEp/h7BimHcUTDlpEtce89xEumlJ5ef2hqepZ+PWp1DDpYC/VO9fmWVI1IlEaoI5fK9FXQ==} + '@octokit/plugin-paginate-rest@14.0.0': + resolution: {integrity: sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==} + engines: {node: '>= 20'} + peerDependencies: + '@octokit/core': '>=6' + + '@octokit/plugin-retry@8.1.0': + resolution: {integrity: sha512-O1FZgXeiGb2sowEr/hYTr6YunGdSAFWnr2fyW39Ah85H8O33ELASQxcvOFF5LE6Tjekcyu2ms4qAzJVhSaJxTw==} + engines: {node: '>= 20'} + peerDependencies: + '@octokit/core': '>=7' + + '@octokit/plugin-throttling@11.0.3': + resolution: {integrity: sha512-34eE0RkFCKycLl2D2kq7W+LovheM/ex3AwZCYN8udpi6bxsyjZidb2McXs69hZhLmJlDqTSP8cH+jSRpiaijBg==} + engines: {node: '>= 20'} + peerDependencies: + '@octokit/core': ^7.0.0 + + '@octokit/request-error@7.1.0': + resolution: {integrity: sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==} + engines: {node: '>= 20'} + + '@octokit/request@10.0.8': + resolution: {integrity: sha512-SJZNwY9pur9Agf7l87ywFi14W+Hd9Jg6Ifivsd33+/bGUQIjNujdFiXII2/qSlN2ybqUHfp5xpekMEjIBTjlSw==} + engines: {node: '>= 20'} + + '@octokit/types@16.0.0': + resolution: {integrity: sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==} + + '@open-draft/deferred-promise@2.2.0': + resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} + + '@open-draft/deferred-promise@3.0.0': + resolution: {integrity: sha512-XW375UK8/9SqUVNVa6M0yEy8+iTi4QN5VZ7aZuRFQmy76LRwI9wy5F4YIBU6T+eTe2/DNDo8tqu8RHlwLHM6RA==} + + '@open-draft/logger@0.3.0': + resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} + + '@open-draft/until@2.1.0': + resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} + + '@oxc-project/types@0.124.0': + resolution: {integrity: sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg==} + + '@pkgr/core@0.2.9': + resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + + '@playwright/test@1.59.1': + resolution: {integrity: sha512-PG6q63nQg5c9rIi4/Z5lR5IVF7yU5MqmKaPOe0HSc0O2cX1fPi96sUQu5j7eo4gKCkB2AnNGoWt7y4/Xx3Kcqg==} engines: {node: '>=18'} hasBin: true - '@rollup/rollup-android-arm-eabi@4.34.3': - resolution: {integrity: sha512-8kq/NjMKkMTGKMPldWihncOl62kgnLYk7cW+/4NCUWfS70/wz4+gQ7rMxMMpZ3dIOP/xw7wKNzIuUnN/H2GfUg==} - cpu: [arm] - os: [android] + '@pnpm/config.env-replace@1.1.0': + resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==} + engines: {node: '>=12.22.0'} + + '@pnpm/network.ca-file@1.0.2': + resolution: {integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==} + engines: {node: '>=12.22.0'} + + '@pnpm/npm-conf@3.0.2': + resolution: {integrity: sha512-h104Kh26rR8tm+a3Qkc5S4VLYint3FE48as7+/5oCEcKR2idC/pF1G6AhIXKI+eHPJa/3J9i5z0Al47IeGHPkA==} + engines: {node: '>=12'} - '@rollup/rollup-android-arm64@4.34.3': - resolution: {integrity: sha512-1PqMHiuRochQ6++SDI7SaRDWJKr/NgAlezBi5nOne6Da6IWJo3hK0TdECBDwd92IUDPG4j/bZmWuwOnomNT8wA==} + '@rolldown/binding-android-arm64@1.0.0-rc.15': + resolution: {integrity: sha512-YYe6aWruPZDtHNpwu7+qAHEMbQ/yRl6atqb/AhznLTnD3UY99Q1jE7ihLSahNWkF4EqRPVC4SiR4O0UkLK02tA==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.34.3': - resolution: {integrity: sha512-fqbrykX4mGV3DlCDXhF4OaMGcchd2tmLYxVt3On5oOZWVDFfdEoYAV2alzNChl8OzNaeMAGqm1f7gk7eIw/uDg==} + '@rolldown/binding-darwin-arm64@1.0.0-rc.15': + resolution: {integrity: sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.34.3': - resolution: {integrity: sha512-8Wxrx/KRvMsTyLTbdrMXcVKfpW51cCNW8x7iQD72xSEbjvhCY3b+w83Bea3nQfysTMR7K28esc+ZFITThXm+1w==} + '@rolldown/binding-darwin-x64@1.0.0-rc.15': + resolution: {integrity: sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.34.3': - resolution: {integrity: sha512-lpBmV2qSiELh+ATQPTjQczt5hvbTLsE0c43Rx4bGxN2VpnAZWy77we7OO62LyOSZNY7CzjMoceRPc+Lt4e9J6A==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.34.3': - resolution: {integrity: sha512-sNPvBIXpgaYcI6mAeH13GZMXFrrw5mdZVI1M9YQPRG2LpjwL8DSxSIflZoh/B5NEuOi53kxsR/S2GKozK1vDXA==} + '@rolldown/binding-freebsd-x64@1.0.0-rc.15': + resolution: {integrity: sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.34.3': - resolution: {integrity: sha512-MW6N3AoC61OfE1VgnN5O1OW0gt8VTbhx9s/ZEPLBM11wEdHjeilPzOxVmmsrx5YmejpGPvez8QwGGvMU+pGxpw==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-musleabihf@4.34.3': - resolution: {integrity: sha512-2SQkhr5xvatYq0/+H6qyW0zvrQz9LM4lxGkpWURLoQX5+yP8MsERh4uWmxFohOvwCP6l/+wgiHZ1qVwLDc7Qmw==} + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15': + resolution: {integrity: sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.34.3': - resolution: {integrity: sha512-R3JLYt8YoRwKI5shJsovLpcR6pwIMui/MGG/MmxZ1DYI3iRSKI4qcYrvYgDf4Ss2oCR3RL3F3dYK7uAGQgMIuQ==} + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15': + resolution: {integrity: sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.34.3': - resolution: {integrity: sha512-4XQhG8v/t3S7Rxs7rmFUuM6j09hVrTArzONS3fUZ6oBRSN/ps9IPQjVhp62P0W3KhqJdQADo/MRlYRMdgxr/3w==} + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.15': + resolution: {integrity: sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [musl] - '@rollup/rollup-linux-loongarch64-gnu@4.34.3': - resolution: {integrity: sha512-QlW1jCUZ1LHUIYCAK2FciVw1ptHsxzApYVi05q7bz2A8oNE8QxQ85NhM4arLxkAlcnS42t4avJbSfzSQwbIaKg==} - cpu: [loong64] - os: [linux] - - '@rollup/rollup-linux-powerpc64le-gnu@4.34.3': - resolution: {integrity: sha512-kMbLToizVeCcN69+nnm20Dh0hrRIAjgaaL+Wh0gWZcNt8e542d2FUGtsyuNsHVNNF3gqTJrpzUGIdwMGLEUM7g==} + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.15': + resolution: {integrity: sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-riscv64-gnu@4.34.3': - resolution: {integrity: sha512-YgD0DnZ3CHtvXRH8rzjVSxwI0kMTr0RQt3o1N92RwxGdx7YejzbBO0ELlSU48DP96u1gYYVWfUhDRyaGNqJqJg==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-s390x-gnu@4.34.3': - resolution: {integrity: sha512-dIOoOz8altjp6UjAi3U9EW99s8nta4gzi52FeI45GlPyrUH4QixUoBMH9VsVjt+9A2RiZBWyjYNHlJ/HmJOBCQ==} + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.15': + resolution: {integrity: sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.34.3': - resolution: {integrity: sha512-lOyG3aF4FTKrhpzXfMmBXgeKUUXdAWmP2zSNf8HTAXPqZay6QYT26l64hVizBjq+hJx3pl0DTEyvPi9sTA6VGA==} + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.15': + resolution: {integrity: sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.34.3': - resolution: {integrity: sha512-usztyYLu2i+mYzzOjqHZTaRXbUOqw3P6laNUh1zcqxbPH1P2Tz/QdJJCQSnGxCtsRQeuU2bCyraGMtMumC46rw==} + '@rolldown/binding-linux-x64-musl@1.0.0-rc.15': + resolution: {integrity: sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [musl] - '@rollup/rollup-win32-arm64-msvc@4.34.3': - resolution: {integrity: sha512-ojFOKaz/ZyalIrizdBq2vyc2f0kFbJahEznfZlxdB6pF9Do6++i1zS5Gy6QLf8D7/S57MHrmBLur6AeRYeQXSA==} + '@rolldown/binding-openharmony-arm64@1.0.0-rc.15': + resolution: {integrity: sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] - os: [win32] + os: [openharmony] - '@rollup/rollup-win32-ia32-msvc@4.34.3': - resolution: {integrity: sha512-K/V97GMbNa+Da9mGcZqmSl+DlJmWfHXTuI9V8oB2evGsQUtszCl67+OxWjBKpeOnYwox9Jpmt/J6VhpeRCYqow==} - cpu: [ia32] + '@rolldown/binding-wasm32-wasi@1.0.0-rc.15': + resolution: {integrity: sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15': + resolution: {integrity: sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.34.3': - resolution: {integrity: sha512-CUypcYP31Q8O04myV6NKGzk9GVXslO5EJNfmARNSzLF2A+5rmZUlDJ4et6eoJaZgBT9wrC2p4JZH04Vkic8HdQ==} + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.15': + resolution: {integrity: sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - '@tanstack/query-async-storage-persister@5.66.0': - resolution: {integrity: sha512-Uh3YHhKhbub/U5Px+iUIWRXq95QHgvM1gqtfx6mkfsbCdWBC84jS+8FRcEybhzZl1sUuNsE4mawcBHarJyLaWQ==} + '@rolldown/plugin-babel@0.2.3': + resolution: {integrity: sha512-+zEk16yGlz1F9STiRr6uG9hmIXb6nprjLczV/htGptYuLoCuxb+itZ03RKCEeOhBpDDd1NU7qF6x1VLMUp62bw==} + engines: {node: '>=22.12.0 || ^24.0.0'} + peerDependencies: + '@babel/core': ^7.29.0 || ^8.0.0-rc.1 + '@babel/plugin-transform-runtime': ^7.29.0 || ^8.0.0-rc.1 + '@babel/runtime': ^7.27.0 || ^8.0.0-rc.1 + rolldown: ^1.0.0-rc.5 + vite: ^8.0.0 + peerDependenciesMeta: + '@babel/plugin-transform-runtime': + optional: true + '@babel/runtime': + optional: true + vite: + optional: true - '@tanstack/query-core@5.66.0': - resolution: {integrity: sha512-J+JeBtthiKxrpzUu7rfIPDzhscXF2p5zE/hVdrqkACBP8Yu0M96mwJ5m/8cPPYQE9aRNvXztXHlNwIh4FEeMZw==} + '@rolldown/pluginutils@1.0.0-rc.15': + resolution: {integrity: sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g==} - '@tanstack/query-devtools@5.65.0': - resolution: {integrity: sha512-g5y7zc07U9D3esMdqUfTEVu9kMHoIaVBsD0+M3LPdAdD710RpTcLiNvJY1JkYXqkq9+NV+CQoemVNpQPBXVsJg==} + '@rolldown/pluginutils@1.0.0-rc.7': + resolution: {integrity: sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==} - '@tanstack/query-persist-client-core@5.66.0': - resolution: {integrity: sha512-y6bolShmbOmexexZfnmTiHsBOm4ruJxc2MQJzqi6PxkSPjkKAU+Zqviy4ZwQos5skwSw0g7b9L6V6Rd64oZc9g==} + '@rollup/rollup-android-arm-eabi@4.59.0': + resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} + cpu: [arm] + os: [android] - '@tanstack/react-query-devtools@5.66.0': - resolution: {integrity: sha512-uB57wA2YZaQ2fPcFW0E9O1zAGDGSbRKRx84uMk/86VyU9jWVxvJ3Uzp+zNm+nZJYsuekCIo2opTdgNuvM3cKgA==} - peerDependencies: - '@tanstack/react-query': ^5.66.0 - react: ^18 || ^19 + '@rollup/rollup-android-arm64@4.59.0': + resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==} + cpu: [arm64] + os: [android] - '@tanstack/react-query-persist-client@5.66.0': - resolution: {integrity: sha512-LpocQrJF9HCR6N09X7+k8TjkgYsVHPB4e4AvV2qvCeL5aOsQWORttEqCHldohnJwdVm/68tWacw2jVP/8AuI1w==} - peerDependencies: - '@tanstack/react-query': ^5.66.0 - react: ^18 || ^19 + '@rollup/rollup-darwin-arm64@4.59.0': + resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==} + cpu: [arm64] + os: [darwin] - '@tanstack/react-query@5.66.0': - resolution: {integrity: sha512-z3sYixFQJe8hndFnXgWu7C79ctL+pI0KAelYyW+khaNJ1m22lWrhJU2QrsTcRKMuVPtoZvfBYrTStIdKo+x0Xw==} - peerDependencies: - react: ^18 || ^19 + '@rollup/rollup-darwin-x64@4.59.0': + resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==} + cpu: [x64] + os: [darwin] - '@types/babel__core@7.20.5': - resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + '@rollup/rollup-freebsd-arm64@4.59.0': + resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==} + cpu: [arm64] + os: [freebsd] - '@types/babel__generator@7.6.5': - resolution: {integrity: sha512-h9yIuWbJKdOPLJTbmSpPzkF67e659PbQDba7ifWm5BJ8xTv+sDmS7rFmywkWOvXedGTivCdeGSIIX8WLcRTz8w==} + '@rollup/rollup-freebsd-x64@4.59.0': + resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==} + cpu: [x64] + os: [freebsd] - '@types/babel__template@7.4.2': - resolution: {integrity: sha512-/AVzPICMhMOMYoSx9MoKpGDKdBRsIXMNByh1PXSZoa+v6ZoLa8xxtsT/uLQ/NJm0XVAWl/BvId4MlDeXJaeIZQ==} + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} + cpu: [arm] + os: [linux] + libc: [glibc] - '@types/babel__traverse@7.20.2': - resolution: {integrity: sha512-ojlGK1Hsfce93J0+kn3H5R73elidKUaZonirN33GSmgTUMpzI/MIFfSpF3haANe3G1bEBS9/9/QEqwTzwqFsKw==} + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} + cpu: [arm] + os: [linux] + libc: [musl] - '@types/chrome@0.0.301': - resolution: {integrity: sha512-BljW7InXXOfDYr4nG79y5lnaklrZ0gmeTwCUkuCXK2+69dHnZIrg13KhXJE/HrcFUmy8NG/EK+RTGScsh/Hbiw==} + '@rollup/rollup-linux-arm64-gnu@4.59.0': + resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} + cpu: [arm64] + os: [linux] + libc: [glibc] - '@types/cookie@0.6.0': - resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + '@rollup/rollup-linux-arm64-musl@4.59.0': + resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} + cpu: [arm64] + os: [linux] + libc: [musl] - '@types/estree@1.0.6': - resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + '@rollup/rollup-linux-loong64-gnu@4.59.0': + resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} + cpu: [loong64] + os: [linux] + libc: [glibc] - '@types/filesystem@0.0.32': - resolution: {integrity: sha512-Yuf4jR5YYMR2DVgwuCiP11s0xuVRyPKmz8vo6HBY3CGdeMj8af93CFZX+T82+VD1+UqHOxTq31lO7MI7lepBtQ==} + '@rollup/rollup-linux-loong64-musl@4.59.0': + resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} + cpu: [loong64] + os: [linux] + libc: [musl] - '@types/filewriter@0.0.29': - resolution: {integrity: sha512-BsPXH/irW0ht0Ji6iw/jJaK8Lj3FJemon2gvEqHKpCdDCeemHa+rI3WBGq5z7cDMZgoLjY40oninGxqk+8NzNQ==} + '@rollup/rollup-linux-ppc64-gnu@4.59.0': + resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} + cpu: [ppc64] + os: [linux] + libc: [glibc] - '@types/har-format@1.2.10': - resolution: {integrity: sha512-o0J30wqycjF5miWDKYKKzzOU1ZTLuA42HZ4HE7/zqTOc/jTLdQ5NhYWvsRQo45Nfi1KHoRdNhteSI4BAxTF1Pg==} + '@rollup/rollup-linux-ppc64-musl@4.59.0': + resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} + cpu: [ppc64] + os: [linux] + libc: [musl] - '@types/hoist-non-react-statics@3.3.1': - resolution: {integrity: sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==} + '@rollup/rollup-linux-riscv64-gnu@4.59.0': + resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} + cpu: [riscv64] + os: [linux] + libc: [glibc] - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@rollup/rollup-linux-riscv64-musl@4.59.0': + resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} + cpu: [riscv64] + os: [linux] + libc: [musl] - '@types/node@22.13.1': - resolution: {integrity: sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==} + '@rollup/rollup-linux-s390x-gnu@4.59.0': + resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} + cpu: [s390x] + os: [linux] + libc: [glibc] - '@types/parse-json@4.0.0': - resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} + '@rollup/rollup-linux-x64-gnu@4.59.0': + resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} + cpu: [x64] + os: [linux] + libc: [glibc] - '@types/qs@6.9.18': - resolution: {integrity: sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==} + '@rollup/rollup-linux-x64-musl@4.59.0': + resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} + cpu: [x64] + os: [linux] + libc: [musl] - '@types/react-dom@19.0.3': - resolution: {integrity: sha512-0Knk+HJiMP/qOZgMyNFamlIjw9OFCsyC2ZbigmEEyXXixgre6IQpm/4V+r3qH4GC1JPvRJKInw+on2rV6YZLeA==} - peerDependencies: - '@types/react': ^19.0.0 + '@rollup/rollup-openbsd-x64@4.59.0': + resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} + cpu: [x64] + os: [openbsd] - '@types/react-flatpickr@3.8.11': - resolution: {integrity: sha512-wXGyGRpUjiGknioxWzWJdNvF2XxKw5lAI7H64Iv7w4iL+1iT7QvAzrigz5FkW4lTg9IJOww6t7g21FzsrmRV6A==} + '@rollup/rollup-openharmony-arm64@4.59.0': + resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==} + cpu: [arm64] + os: [openharmony] - '@types/react-transition-group@4.4.6': - resolution: {integrity: sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==} + '@rollup/rollup-win32-arm64-msvc@4.59.0': + resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==} + cpu: [arm64] + os: [win32] - '@types/react@19.0.8': - resolution: {integrity: sha512-9P/o1IGdfmQxrujGbIMDyYaaCykhLKc0NGCtYcECNUr9UAaDe4gwvV9bR6tvd5Br1SG0j+PBpbKr2UYY8CwqSw==} + '@rollup/rollup-win32-ia32-msvc@4.59.0': + resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.59.0': + resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.59.0': + resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==} + cpu: [x64] + os: [win32] + + '@sec-ant/readable-stream@0.4.1': + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + + '@semantic-release/changelog@6.0.3': + resolution: {integrity: sha512-dZuR5qByyfe3Y03TpmCvAxCyTnp7r5XwtHRf/8vD9EAn4ZWbavUX8adMtXYzE86EVh0gyLA7lm5yW4IV30XUag==} + engines: {node: '>=14.17'} + peerDependencies: + semantic-release: '>=18.0.0' + + '@semantic-release/commit-analyzer@13.0.1': + resolution: {integrity: sha512-wdnBPHKkr9HhNhXOhZD5a2LNl91+hs8CC2vsAVYxtZH3y0dV3wKn+uZSN61rdJQZ8EGxzWB3inWocBHV9+u/CQ==} + engines: {node: '>=20.8.1'} + peerDependencies: + semantic-release: '>=20.1.0' + + '@semantic-release/error@3.0.0': + resolution: {integrity: sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==} + engines: {node: '>=14.17'} + + '@semantic-release/error@4.0.0': + resolution: {integrity: sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==} + engines: {node: '>=18'} + + '@semantic-release/git@10.0.1': + resolution: {integrity: sha512-eWrx5KguUcU2wUPaO6sfvZI0wPafUKAMNC18aXY4EnNcrZL86dEmpNVnC9uMpGZkmZJ9EfCVJBQx4pV4EMGT1w==} + engines: {node: '>=14.17'} + peerDependencies: + semantic-release: '>=18.0.0' + + '@semantic-release/github@12.0.6': + resolution: {integrity: sha512-aYYFkwHW3c6YtHwQF0t0+lAjlU+87NFOZuH2CvWFD0Ylivc7MwhZMiHOJ0FMpIgPpCVib/VUAcOwvrW0KnxQtA==} + engines: {node: ^22.14.0 || >= 24.10.0} + peerDependencies: + semantic-release: '>=24.1.0' + + '@semantic-release/npm@13.1.5': + resolution: {integrity: sha512-Hq5UxzoatN3LHiq2rTsWS54nCdqJHlsssGERCo8WlvdfFA9LoN0vO+OuKVSjtNapIc/S8C2LBj206wKLHg62mg==} + engines: {node: ^22.14.0 || >= 24.10.0} + peerDependencies: + semantic-release: '>=20.1.0' + + '@semantic-release/release-notes-generator@14.1.0': + resolution: {integrity: sha512-CcyDRk7xq+ON/20YNR+1I/jP7BYKICr1uKd1HHpROSnnTdGqOTburi4jcRiTYz0cpfhxSloQO3cGhnoot7IEkA==} + engines: {node: '>=20.8.1'} + peerDependencies: + semantic-release: '>=20.1.0' + + '@simple-libs/stream-utils@1.2.0': + resolution: {integrity: sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==} + engines: {node: '>=18'} + + '@sindresorhus/is@4.6.0': + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} + + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + + '@tabby_ai/hijri-converter@1.0.5': + resolution: {integrity: sha512-r5bClKrcIusDoo049dSL8CawnHR6mRdDwhlQuIgZRNty68q0x8k3Lf1BtPAMxRf/GgnHBnIO4ujd3+GQdLWzxQ==} + engines: {node: '>=16.0.0'} + + '@tailwindcss/node@4.2.2': + resolution: {integrity: sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA==} + + '@tailwindcss/oxide-android-arm64@4.2.2': + resolution: {integrity: sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.2.2': + resolution: {integrity: sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.2.2': + resolution: {integrity: sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.2.2': + resolution: {integrity: sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ==} + engines: {node: '>= 20'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2': + resolution: {integrity: sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ==} + engines: {node: '>= 20'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.2.2': + resolution: {integrity: sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@tailwindcss/oxide-linux-arm64-musl@4.2.2': + resolution: {integrity: sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@tailwindcss/oxide-linux-x64-gnu@4.2.2': + resolution: {integrity: sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@tailwindcss/oxide-linux-x64-musl@4.2.2': + resolution: {integrity: sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@tailwindcss/oxide-wasm32-wasi@4.2.2': + resolution: {integrity: sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.2.2': + resolution: {integrity: sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.2.2': + resolution: {integrity: sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA==} + engines: {node: '>= 20'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.2.2': + resolution: {integrity: sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg==} + engines: {node: '>= 20'} + + '@tailwindcss/vite@4.2.2': + resolution: {integrity: sha512-mEiF5HO1QqCLXoNEfXVA1Tzo+cYsrqV7w9Juj2wdUFyW07JRenqMG225MvPwr3ZD9N1bFQj46X7r33iHxLUW0w==} + peerDependencies: + vite: ^5.2.0 || ^6 || ^7 || ^8 + + '@tanstack/devtools-event-client@0.4.3': + resolution: {integrity: sha512-OZI6QyULw0FI0wjgmeYzCIfbgPsOEzwJtCpa69XrfLMtNXLGnz3d/dIabk7frg0TmHo+Ah49w5I4KC7Tufwsvw==} + engines: {node: '>=18'} + hasBin: true + + '@tanstack/eslint-plugin-query@5.99.0': + resolution: {integrity: sha512-jVp1AEL7S7BeuQvH5SN1F5UdrNW/AbryKDeWUUMeAKNzh9C+Ik/bRSa/HeuJLlmaN+WOUkdDFbtCK0go7BxnUQ==} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ^5.4.0 || ^6.0.0 + peerDependenciesMeta: + typescript: + optional: true + + '@tanstack/eslint-plugin-router@1.161.6': + resolution: {integrity: sha512-aHln6x6mhtQmrbwMI0lmnMh7t9nEvrJrFOl1vGtQknEKdgKEEqSh9a9/MZKNm3kENaHotoqpRcfbE/or9aAYfQ==} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + + '@tanstack/form-core@1.29.0': + resolution: {integrity: sha512-uyeKEdJBfbj0bkBSwvSYVRtWLOaXvfNX3CeVw1HqGOXVLxpBBGAqWdYLc+UoX/9xcoFwFXrjR9QqMPzvwm2yyQ==} + + '@tanstack/history@1.161.6': + resolution: {integrity: sha512-NaOGLRrddszbQj9upGat6HG/4TKvXLvu+osAIgfxPYA+eIvYKv8GKDJOrY2D3/U9MRnKfMWD7bU4jeD4xmqyIg==} + engines: {node: '>=20.19'} + + '@tanstack/pacer-lite@0.1.1': + resolution: {integrity: sha512-y/xtNPNt/YeyoVxE/JCx+T7yjEzpezmbb+toK8DDD1P4m7Kzs5YR956+7OKexG3f8aXgC3rLZl7b1V+yNUSy5w==} + engines: {node: '>=18'} + + '@tanstack/query-async-storage-persister@5.99.0': + resolution: {integrity: sha512-RUG++yZf8RoRK1Yz83WHHYJ6EF8DqKIF/UNNUUDEw/cY9SLKhAeEd4a0+kDzNRdb4RGXXeF5UIuzoEFJ7elLwQ==} + + '@tanstack/query-core@5.99.0': + resolution: {integrity: sha512-3Jv3WQG0BCcH7G+7lf/bP8QyBfJOXeY+T08Rin3GZ1bshvwlbPt7NrDHMEzGdKIOmOzvIQmxjk28YEQX60k7pQ==} + + '@tanstack/query-devtools@5.99.0': + resolution: {integrity: sha512-m4ufXaJ8FjWXw7xDtyzE/6fkZAyQFg9WrbMrUpt8ZecRJx58jiFOZ2lxZMphZdIpAnIeto/S8stbwLKLusyckQ==} + + '@tanstack/query-persist-client-core@5.99.0': + resolution: {integrity: sha512-FzXoxqGYa+ozGNGBIPHJT06rJD4geiHGbVXNS8K7cwN34te64LXlO5Ep+roQYvZjXJFNrLa4W48DIYITpMxzuA==} + + '@tanstack/react-form@1.29.0': + resolution: {integrity: sha512-jj425NNX0QKqbUzqSNiYI3HCPHSk2df47acXCJyXczWOTmG81ECZGkgofgqamFsSU9kMiH6Di5RLUnftrlhWSw==} + peerDependencies: + '@tanstack/react-start': '*' + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@tanstack/react-start': + optional: true + + '@tanstack/react-query-devtools@5.99.0': + resolution: {integrity: sha512-CqqX7LCU9yOfCY/vBURSx2YSD83ryfX+QkfkaKionTfg1s2Hdm572Ro99gW3QPoJjzvsj1HM4pnN4nbDy3MXKA==} + peerDependencies: + '@tanstack/react-query': ^5.99.0 + react: ^18 || ^19 + + '@tanstack/react-query-persist-client@5.99.0': + resolution: {integrity: sha512-A3TTaaYZOy6dFUNJj3r10rwmUBWaXqc2N71a7jzpFXilYAYWLKJf9ivT5n5bhXsJnSkdvv1RLifUg/GdvDGaDw==} + peerDependencies: + '@tanstack/react-query': ^5.99.0 + react: ^18 || ^19 + + '@tanstack/react-query@5.99.0': + resolution: {integrity: sha512-OY2bCqPemT1LlqJ8Y2CUau4KELnIhhG9Ol3ZndPbdnB095pRbPo1cHuXTndg8iIwtoHTgwZjyaDnQ0xD0mYwAw==} + peerDependencies: + react: ^18 || ^19 + + '@tanstack/react-router@1.168.22': + resolution: {integrity: sha512-W2LyfkfJtDCf//jOjZeUBWwOVl8iDRVTECpGHa2M28MT3T5/VVnjgicYNHR/ax0Filk1iU67MRjcjHheTYvK1Q==} + engines: {node: '>=20.19'} + peerDependencies: + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + + '@tanstack/react-store@0.9.3': + resolution: {integrity: sha512-y2iHd/N9OkoQbFJLUX1T9vbc2O9tjH0pQRgTcx1/Nz4IlwLvkgpuglXUx+mXt0g5ZDFrEeDnONPqkbfxXJKwRg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@tanstack/router-core@1.168.15': + resolution: {integrity: sha512-Wr0424NDtD8fT/uALobMZ9DdcfsTyXtW5IPR++7zvW8/7RaIOeaqXpVDId8ywaGtqPWLWOfaUg2zUtYtukoXYA==} + engines: {node: '>=20.19'} + hasBin: true + + '@tanstack/router-generator@1.166.32': + resolution: {integrity: sha512-VuusKwEXcgKq+myq1JQfZogY8scTXIIeFls50dJ/UXgCXWp5n14iFreYNlg41wURcak2oA3M+t2TVfD0xUUD6g==} + engines: {node: '>=20.19'} + + '@tanstack/router-plugin@1.167.22': + resolution: {integrity: sha512-wYPzIvBK8bcmXVUpZfSgGBXOrfBAdF4odKevz6rejio5rEd947NtKDF5R7eYdwlAOmRqYpLJnJ1QHkc5t8bY4w==} + engines: {node: '>=20.19'} + hasBin: true + peerDependencies: + '@rsbuild/core': '>=1.0.2' + '@tanstack/react-router': ^1.168.21 + vite: '>=5.0.0 || >=6.0.0 || >=7.0.0 || >=8.0.0' + vite-plugin-solid: ^2.11.10 || ^3.0.0-0 + webpack: '>=5.92.0' + peerDependenciesMeta: + '@rsbuild/core': + optional: true + '@tanstack/react-router': + optional: true + vite: + optional: true + vite-plugin-solid: + optional: true + webpack: + optional: true + + '@tanstack/router-utils@1.161.6': + resolution: {integrity: sha512-nRcYw+w2OEgK6VfjirYvGyPLOK+tZQz1jkYcmH5AjMamQ9PycnlxZF2aEZtPpNoUsaceX2bHptn6Ub5hGXqNvw==} + engines: {node: '>=20.19'} + + '@tanstack/store@0.9.3': + resolution: {integrity: sha512-8reSzl/qGWGGVKhBoxXPMWzATSbZLZFWhwBAFO9NAyp0TxzfBP0mIrGb8CP8KrQTmvzXlR/vFPPUrHTLBGyFyw==} + + '@tanstack/virtual-file-routes@1.161.7': + resolution: {integrity: sha512-olW33+Cn+bsCsZKPwEGhlkqS6w3M2slFv11JIobdnCFKMLG97oAI2kWKdx5/zsywTL8flpnoIgaZZPlQTFYhdQ==} + engines: {node: '>=20.19'} + hasBin: true - '@typescript-eslint/eslint-plugin@8.23.0': - resolution: {integrity: sha512-vBz65tJgRrA1Q5gWlRfvoH+w943dq9K1p1yDBY2pc+a1nbBLZp7fB9+Hk8DaALUbzjqlMfgaqlVPT1REJdkt/w==} + '@ts-morph/common@0.27.0': + resolution: {integrity: sha512-Wf29UqxWDpc+i61k3oIOzcUfQt79PIT9y/MWfAGlrkjg6lBC1hwDECLXPVJAhWjiGbfBCxZd65F/LIZF3+jeJQ==} + + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + + '@types/chrome@0.1.40': + resolution: {integrity: sha512-UnfyRAe8ORu9HSuTH0EqyOEUin3JrWW9Nl/gDXezNfTUrfIoxw+WRZgKOxGz0t5BnjbfXBnS2eCYfW2PxH1wcA==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/filesystem@0.0.36': + resolution: {integrity: sha512-vPDXOZuannb9FZdxgHnqSwAG/jvdGM8Wq+6N4D/d80z+D4HWH+bItqsZaVRQykAn6WEVeEkLm2oQigyHtgb0RA==} + + '@types/filewriter@0.0.33': + resolution: {integrity: sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==} + + '@types/har-format@1.2.16': + resolution: {integrity: sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/minimatch@3.0.5': + resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==} + + '@types/node@24.12.2': + resolution: {integrity: sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==} + + '@types/normalize-package-data@2.4.4': + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + + '@types/qs@6.15.0': + resolution: {integrity: sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow==} + + '@types/react-dom@19.2.3': + resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} + peerDependencies: + '@types/react': ^19.2.0 + + '@types/react@19.2.14': + resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} + + '@types/set-cookie-parser@2.4.10': + resolution: {integrity: sha512-GGmQVGpQWUe5qglJozEjZV/5dyxbOOZ0LHe/lqyWssB88Y4svNfst0uqBVscdDeIKl5Jy5+aPSvy7mI9tYRguw==} + + '@types/statuses@2.0.6': + resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==} + + '@types/validate-npm-package-name@4.0.2': + resolution: {integrity: sha512-lrpDziQipxCEeK5kWxvljWYhUvOiB2A9izZd9B2AFarYAkqZshb4lPbRs7zKEic6eGtH8V/2qJW+dPp9OtF6bw==} + + '@typescript-eslint/eslint-plugin@8.58.2': + resolution: {integrity: sha512-aC2qc5thQahutKjP+cl8cgN9DWe3ZUqVko30CMSZHnFEHyhOYoZSzkGtAI2mcwZ38xeImDucI4dnqsHiOYuuCw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.8.0' + '@typescript-eslint/parser': ^8.58.2 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/parser@8.23.0': - resolution: {integrity: sha512-h2lUByouOXFAlMec2mILeELUbME5SZRN/7R9Cw2RD2lRQQY08MWMM+PmVVKKJNK1aIwqTo9t/0CvOxwPbRIE2Q==} + '@typescript-eslint/parser@8.58.2': + resolution: {integrity: sha512-/Zb/xaIDfxeJnvishjGdcR4jmr7S+bda8PKNhRGdljDM+elXhlvN0FyPSsMnLmJUrVG9aPO6dof80wjMawsASg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.8.0' + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/project-service@8.58.2': + resolution: {integrity: sha512-Cq6UfpZZk15+r87BkIh5rDpi38W4b+Sjnb8wQCPPDDweS/LRCFjCyViEbzHk5Ck3f2QDfgmlxqSa7S7clDtlfg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/scope-manager@8.58.2': + resolution: {integrity: sha512-SgmyvDPexWETQek+qzZnrG6844IaO02UVyOLhI4wpo82dpZJY9+6YZCKAMFzXb7qhx37mFK1QcPQ18tud+vo6Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/scope-manager@8.23.0': - resolution: {integrity: sha512-OGqo7+dXHqI7Hfm+WqkZjKjsiRtFUQHPdGMXzk5mYXhJUedO7e/Y7i8AK3MyLMgZR93TX4bIzYrfyVjLC+0VSw==} + '@typescript-eslint/tsconfig-utils@8.58.2': + resolution: {integrity: sha512-3SR+RukipDvkkKp/d0jP0dyzuls3DbGmwDpVEc5wqk5f38KFThakqAAO0XMirWAE+kT00oTauTbzMFGPoAzB0A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/type-utils@8.23.0': - resolution: {integrity: sha512-iIuLdYpQWZKbiH+RkCGc6iu+VwscP5rCtQ1lyQ7TYuKLrcZoeJVpcLiG8DliXVkUxirW/PWlmS+d6yD51L9jvA==} + '@typescript-eslint/type-utils@8.58.2': + resolution: {integrity: sha512-Z7EloNR/B389FvabdGeTo2XMs4W9TjtPiO9DAsmT0yom0bwlPyRjkJ1uCdW1DvrrrYP50AJZ9Xc3sByZA9+dcg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.8.0' + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/types@8.23.0': - resolution: {integrity: sha512-1sK4ILJbCmZOTt9k4vkoulT6/y5CHJ1qUYxqpF1K/DBAd8+ZUL4LlSCxOssuH5m4rUaaN0uS0HlVPvd45zjduQ==} + '@typescript-eslint/types@8.58.2': + resolution: {integrity: sha512-9TukXyATBQf/Jq9AMQXfvurk+G5R2MwfqQGDR2GzGz28HvY/lXNKGhkY+6IOubwcquikWk5cjlgPvD2uAA7htQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.23.0': - resolution: {integrity: sha512-LcqzfipsB8RTvH8FX24W4UUFk1bl+0yTOf9ZA08XngFwMg4Kj8A+9hwz8Cr/ZS4KwHrmo9PJiLZkOt49vPnuvQ==} + '@typescript-eslint/typescript-estree@8.58.2': + resolution: {integrity: sha512-ELGuoofuhhoCvNbQjFFiobFcGgcDCEm0ThWdmO4Z0UzLqPXS3KFvnEZ+SHewwOYHjM09tkzOWXNTv9u6Gqtyuw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '>=4.8.4 <5.8.0' + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.23.0': - resolution: {integrity: sha512-uB/+PSo6Exu02b5ZEiVtmY6RVYO7YU5xqgzTIVZwTHvvK3HsL8tZZHFaTLFtRG3CsV4A5mhOv+NZx5BlhXPyIA==} + '@typescript-eslint/utils@8.58.2': + resolution: {integrity: sha512-QZfjHNEzPY8+l0+fIXMvuQ2sJlplB4zgDZvA+NmvZsZv3EQwOcc1DuIU1VJUTWZ/RKouBMhDyNaBMx4sWvrzRA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.8.0' + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/visitor-keys@8.23.0': - resolution: {integrity: sha512-oWWhcWDLwDfu++BGTZcmXWqpwtkwb5o7fxUIGksMQQDSdPW9prsSnfIOZMlsj4vBOSrcnjIUZMiIjODgGosFhQ==} + '@typescript-eslint/visitor-keys@8.58.2': + resolution: {integrity: sha512-f1WO2Lx8a9t8DARmcWAUPJbu0G20bJlj8L4z72K00TMeJAoyLr/tHhI/pzYBLrR4dXWkcxO1cWYZEOX8DKHTqA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@vitejs/plugin-react@4.3.4': - resolution: {integrity: sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==} - engines: {node: ^14.18.0 || >=16.0.0} + '@vitejs/plugin-react@6.0.1': + resolution: {integrity: sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ==} + engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: - vite: ^4.2.0 || ^5.0.0 || ^6.0.0 + '@rolldown/plugin-babel': ^0.1.7 || ^0.2.0 + babel-plugin-react-compiler: ^1.0.0 + vite: ^8.0.0 + peerDependenciesMeta: + '@rolldown/plugin-babel': + optional: true + babel-plugin-react-compiler: + optional: true + + '@webext-core/fake-browser@1.3.4': + resolution: {integrity: sha512-nZcVWr3JpwpS5E6hKpbAwAMBM/AXZShnfW0F76udW8oLd6Kv0nbW6vFS07md4Na/0ntQonk3hFnlQYGYBAlTrA==} + + '@webext-core/isolated-element@1.1.5': + resolution: {integrity: sha512-4m6oP8Vzm/68YO1QmkUOZqqUcmyBtA53tji2g00/nYXE3E3IceYgeub7eIqvXDV2Z7xU6cm6qO1IMt4XFVwtvQ==} + + '@webext-core/match-patterns@1.0.3': + resolution: {integrity: sha512-NY39ACqCxdKBmHgw361M9pfJma8e4AZo20w9AY+5ZjIj1W2dvXC8J31G5fjfOGbulW9w4WKpT8fPooi0mLkn9A==} + + '@wxt-dev/browser@0.1.40': + resolution: {integrity: sha512-h2/v/Hpkj5sz//h84ProqBaAcTsDFRKp9b/JVHOK/r7LT0XLE+ZDs5YN1BnFLUEHdM7G3fUjTyBG84cayXQshQ==} + + '@wxt-dev/storage@1.2.8': + resolution: {integrity: sha512-GWCFKgF5+d7eslOxUDFC70ypA9njupmJb1nQM8uZoX0J3sWT2BO5xJLzb1sYahWAfID9p2BMtnUBN1lkWxPsbQ==} + + accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn@8.14.0: - resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} engines: {node: '>=0.4.0'} hasBin: true - ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + adm-zip@0.5.17: + resolution: {integrity: sha512-+Ut8d9LLqwEvHHJl1+PIHqoyDxFgVN847JTVM3Izi3xHDWPE4UtzzXysMZQs64DMcrJfBeS/uoEP4AD3HQHnQQ==} + engines: {node: '>=12.0'} + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + + aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + + aggregate-error@5.0.0: + resolution: {integrity: sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==} + engines: {node: '>=18'} + + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv@6.14.0: + resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} + + ajv@8.18.0: + resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} + + ansi-align@3.0.1: + resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} + + ansi-escapes@7.3.0: + resolution: {integrity: sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==} + engines: {node: '>=18'} ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.1.0: - resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} engines: {node: '>=12'} + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} + ansis@4.2.0: + resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==} + engines: {node: '>=14'} + any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} @@ -1010,30 +1862,37 @@ packages: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} - arg@5.0.2: - resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} - argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - array-buffer-byte-length@1.0.1: - resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} - engines: {node: '>= 0.4'} + argv-formatter@1.0.0: + resolution: {integrity: sha512-F2+Hkm9xFaRg+GkaNnbwXNDV5O6pnCFEmqyhvfC/Ic5LbgOWjJh3L+mN/s91rxVL3znE7DYVpW0GJFT+4YBgWw==} array-buffer-byte-length@1.0.2: resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} engines: {node: '>= 0.4'} - array-includes@3.1.8: - resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + array-differ@4.0.0: + resolution: {integrity: sha512-Q6VPTLMsmXZ47ENG3V+wQyZS1ZxXMxFyYzA+Z/GMrJ6yIutAIEf9wTyroTzmGjNfox9/h3GdGBCVh43GVFx4Uw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + array-ify@1.0.0: + resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} + + array-includes@3.1.9: + resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} engines: {node: '>= 0.4'} + array-union@3.0.1: + resolution: {integrity: sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==} + engines: {node: '>=12'} + array.prototype.findlast@1.2.5: resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} engines: {node: '>= 0.4'} - array.prototype.flat@1.3.1: - resolution: {integrity: sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==} + array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} engines: {node: '>= 0.4'} array.prototype.flatmap@1.3.3: @@ -1044,202 +1903,462 @@ packages: resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} engines: {node: '>= 0.4'} - arraybuffer.prototype.slice@1.0.3: - resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} - engines: {node: '>= 0.4'} - arraybuffer.prototype.slice@1.0.4: resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} engines: {node: '>= 0.4'} + ast-types@0.16.1: + resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} + engines: {node: '>=4'} + + astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + + async-mutex@0.5.0: + resolution: {integrity: sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==} + + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - autoprefixer@10.4.20: - resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} - engines: {node: ^10 || ^12 || >=14} - hasBin: true - peerDependencies: - postcss: ^8.1.0 + atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + + atomically@2.1.1: + resolution: {integrity: sha512-P4w9o2dqARji6P7MHprklbfiArZAWvo07yW7qs3pdljb3BWr12FIB7W+p0zJiuiVsUpRO0iZn1kFFcpPegg0tQ==} available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - axios@1.7.9: - resolution: {integrity: sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==} + axios@1.15.0: + resolution: {integrity: sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==} + + babel-dead-code-elimination@1.0.12: + resolution: {integrity: sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig==} - babel-plugin-macros@3.1.0: - resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} - engines: {node: '>=10', npm: '>=6'} + babel-plugin-react-compiler@1.0.0: + resolution: {integrity: sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==} balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - binary-extensions@2.2.0: - resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + baseline-browser-mapping@2.10.19: + resolution: {integrity: sha512-qCkNLi2sfBOn8XhZQ0FXsT1Ki/Yo5P90hrkRamVFRS7/KV9hpfA4HkoWNU152+8w0zPjnxo5psx5NL3PSGgv5g==} + engines: {node: '>=6.0.0'} + hasBin: true + + before-after-hook@4.0.0: + resolution: {integrity: sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} - brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + + body-parser@2.2.2: + resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} + engines: {node: '>=18'} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + bottleneck@2.19.5: + resolution: {integrity: sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==} + + boxen@8.0.1: + resolution: {integrity: sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==} + engines: {node: '>=18'} + + brace-expansion@1.1.14: + resolution: {integrity: sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==} - brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + brace-expansion@5.0.5: + resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} + engines: {node: 18 || 20 || >=22} braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.23.3: - resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==} + browserslist@4.28.2: + resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true - browserslist@4.24.2: - resolution: {integrity: sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true + buffer-equal-constant-time@1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} - call-bind-apply-helpers@1.0.1: - resolution: {integrity: sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==} - engines: {node: '>= 0.4'} + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + c12@3.3.4: + resolution: {integrity: sha512-cM0ApFQSBXuourJejzwv/AuPRvAxordTyParRVcHjjtXirtkzM0uK2L9TTn9s0cXZbG7E55jCivRQzoxYmRAlA==} + peerDependencies: + magicast: '*' + peerDependenciesMeta: + magicast: + optional: true + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + cac@7.0.0: + resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} + engines: {node: '>=20.19.0'} - call-bind@1.0.7: - resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + cacheable@2.3.4: + resolution: {integrity: sha512-djgxybDbw9fL/ZWMI3+CE8ZilNxcwFkVtDc1gJ+IlOSSWkSMPQabhV/XCHTQ6pwwN6aivXPZ43omTooZiX06Ew==} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} - call-bind@1.0.8: - resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + call-bind@1.0.9: + resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} engines: {node: '>= 0.4'} - call-bound@1.0.3: - resolution: {integrity: sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==} + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} engines: {node: '>= 0.4'} callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - camelcase-css@2.0.1: - resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} - engines: {node: '>= 6'} + camelcase@8.0.0: + resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} + engines: {node: '>=16'} - caniuse-lite@1.0.30001659: - resolution: {integrity: sha512-Qxxyfv3RdHAfJcXelgf0hU4DFUVXBGTjqrBUZLUh8AtlGnsDo+CnncYtTd95+ZKfnANUOzxyIQCuU/UeBZBYoA==} + caniuse-lite@1.0.30001788: + resolution: {integrity: sha512-6q8HFp+lOQtcf7wBK+uEenxymVWkGKkjFpCvw5W25cmMwEDU45p1xQFBQv8JDlMMry7eNxyBaR+qxgmTUZkIRQ==} - caniuse-lite@1.0.30001675: - resolution: {integrity: sha512-/wV1bQwPrkLiQMjaJF5yUMVM/VdRPOCU8QZ+PmG6uW6DvYSrNY1bpwHI/3mOcUosLaJCzYDi5o91IQB51ft6cg==} + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} - chokidar@3.5.3: - resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} - engines: {node: '>= 8.10.0'} + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} - classnames@2.3.2: - resolution: {integrity: sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==} + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} - clsx@2.1.1: - resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} - engines: {node: '>=6'} + chrome-launcher@1.2.0: + resolution: {integrity: sha512-JbuGuBNss258bvGil7FT4HKdC3SC2K7UAEUqiPy3ACS3Yxo3hAW6bvFpCu2HsIJLgTqxgEX6BkujvzZfLpUD0Q==} + engines: {node: '>=12.13.0'} + hasBin: true - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} + ci-info@4.4.0: + resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} + engines: {node: '>=8'} - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + citty@0.2.2: + resolution: {integrity: sha512-+6vJA3L98yv+IdfKGZHBNiGW5KHn22e/JwID0Strsz8h4S/csAu/OuICwxrg44k5MRiZHWIo8XXuJgQTriRP4w==} - color-string@1.9.1: - resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + class-variance-authority@0.7.1: + resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} - color@4.2.3: - resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} - engines: {node: '>=12.5.0'} + clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} + clean-stack@5.3.0: + resolution: {integrity: sha512-9ngPTOhYGQqNVSfeJkYXHmF7AGWp4/nN5D/QqNQs3Dvxd1Kk/WpjHfNujKHYUQ/5CoGyOyFNoWSPk5afzP0QVg==} + engines: {node: '>=14.16'} - commander@4.1.1: - resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} - engines: {node: '>= 6'} + cli-boxes@3.0.0: + resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} + engines: {node: '>=10'} - concat-map@0.0.1: + cli-cursor@5.0.0: + resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} + engines: {node: '>=18'} + + cli-highlight@2.1.11: + resolution: {integrity: sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==} + engines: {node: '>=8.0.0', npm: '>=5.0.0'} + hasBin: true + + cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + + cli-table3@0.6.5: + resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} + engines: {node: 10.* || >= 12.*} + + cli-truncate@5.2.0: + resolution: {integrity: sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==} + engines: {node: '>=20'} + + cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} + + cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + cliui@9.0.1: + resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==} + engines: {node: '>=20'} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + code-block-writer@13.0.3: + resolution: {integrity: sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + colord@2.9.3: + resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} + + commander@14.0.3: + resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} + engines: {node: '>=20'} + + commander@2.9.0: + resolution: {integrity: sha512-bmkUukX8wAOjHdN26xj5c4ctEV22TQ7dQYhSmuckKhToXrkUn0iIaolHdIxYYqD55nhpSPA9zPQ1yP57GdXP2A==} + engines: {node: '>= 0.6.x'} + + commander@9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} + engines: {node: ^12.20.0 || >=14} + + compare-func@2.0.0: + resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} + + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - convert-source-map@1.9.0: - resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + concat-stream@1.6.2: + resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} + engines: {'0': node >= 0.8} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + confbox@0.2.4: + resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==} + + config-chain@1.1.13: + resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} + + configstore@7.1.0: + resolution: {integrity: sha512-N4oog6YJWbR9kGyXvS7jEykLDXIE2C0ILYqNBZBp9iwiJpoCBWYsuAdW6PPFn6w06jjnC+3JstVvWHO4cZqvRg==} + engines: {node: '>=18'} + + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + + content-disposition@1.1.0: + resolution: {integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==} + engines: {node: '>=18'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + conventional-changelog-angular@8.3.1: + resolution: {integrity: sha512-6gfI3otXK5Ph5DfCOI1dblr+kN3FAm5a97hYoQkqNZxOaYa5WKfXH+AnpsmS+iUH2mgVC2Cg2Qw9m5OKcmNrIg==} + engines: {node: '>=18'} + + conventional-changelog-conventionalcommits@9.3.1: + resolution: {integrity: sha512-dTYtpIacRpcZgrvBYvBfArMmK2xvIpv2TaxM0/ZI5CBtNUzvF2x0t15HsbRABWprS6UPmvj+PzHVjSx4qAVKyw==} + engines: {node: '>=18'} + + conventional-changelog-writer@8.4.0: + resolution: {integrity: sha512-HHBFkk1EECxxmCi4CTu091iuDpQv5/OavuCUAuZmrkWpmYfyD816nom1CvtfXJ/uYfAAjavgHvXHX291tSLK8g==} + engines: {node: '>=18'} + hasBin: true + + conventional-commits-filter@5.0.0: + resolution: {integrity: sha512-tQMagCOC59EVgNZcC5zl7XqO30Wki9i9J3acbUvkaosCT6JX3EeFwJD7Qqp4MCikRnzS18WXV3BLIQ66ytu6+Q==} + engines: {node: '>=18'} + + conventional-commits-parser@6.4.0: + resolution: {integrity: sha512-tvRg7FIBNlyPzjdG8wWRlPHQJJHI7DylhtRGeU9Lq+JuoPh5BKpPRX83ZdLrvXuOSu5Eo/e7SzOQhU4Hd2Miuw==} + engines: {node: '>=18'} + hasBin: true + + convert-hrtime@5.0.0: + resolution: {integrity: sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==} + engines: {node: '>=12'} convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - cookie@1.0.2: - resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} + cookie-es@3.1.1: + resolution: {integrity: sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==} + + cookie-signature@1.2.2: + resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} + engines: {node: '>=6.6.0'} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + cookie@1.1.1: + resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} engines: {node: '>=18'} core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - cosmiconfig@7.1.0: - resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} - engines: {node: '>=10'} + cors@2.8.6: + resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} + engines: {node: '>= 0.10'} + + cosmiconfig@9.0.1: + resolution: {integrity: sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true - country-flag-icons@1.5.14: - resolution: {integrity: sha512-GAFsVzHDu3bdAhbQ1LwBRqk/Ad8+ZzS5zU49P+lRla0KGy/V1V8ywNa1SxBOAmI/lyEOT9dfH3Q++q1lqJlvBA==} + country-flag-icons@1.6.16: + resolution: {integrity: sha512-HxJVoE/aaZGcUMx1vK/u9430uKGB3ODZDDZJJOqVJQzoHk5v42c0fSp1rk4tDfyr1dVOJjwxRiaBPliBMo2Liw==} - cross-env@7.0.3: - resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} - engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} + cross-env@10.1.0: + resolution: {integrity: sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==} + engines: {node: '>=20'} hasBin: true cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + crypto-random-string@4.0.0: + resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==} + engines: {node: '>=12'} + + css-functions-list@3.3.3: + resolution: {integrity: sha512-8HFEBPKhOpJPEPu70wJJetjKta86Gw9+CCyCnB3sui2qQfOvRyqBy4IKLKKAwdMpWb2lHXWk9Wb4Z6AmaUT1Pg==} + engines: {node: '>=12'} + + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + + css-tree@3.2.1: + resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} + cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} hasBin: true - csstype@3.1.2: - resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} + cssom@0.5.0: + resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} - data-view-buffer@1.0.1: - resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} - engines: {node: '>= 0.4'} + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} data-view-buffer@1.0.2: resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} engines: {node: '>= 0.4'} - data-view-byte-length@1.0.1: - resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} - engines: {node: '>= 0.4'} - data-view-byte-length@1.0.2: resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} engines: {node: '>= 0.4'} - data-view-byte-offset@1.0.0: - resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} - engines: {node: '>= 0.4'} - data-view-byte-offset@1.0.1: resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} engines: {node: '>= 0.4'} - date-fns@3.6.0: - resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} + date-fns-jalali@4.1.0-0: + resolution: {integrity: sha512-hTIP/z+t+qKwBDcmmsnmjWTduxCg+5KfdqWQvb2X/8C9+knYY6epN/pfxdDuyVlSVeFz0sM5eEfwIUQ70U4ckg==} + + date-fns@4.1.0: + resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} + + debounce@1.2.1: + resolution: {integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==} + + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true - debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -1247,81 +2366,178 @@ packages: supports-color: optional: true - decimal.js@10.4.3: - resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} + dedent@1.7.2: + resolution: {integrity: sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - deepmerge@2.2.1: - resolution: {integrity: sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==} - engines: {node: '>=0.10.0'} - deepmerge@4.3.1: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} + default-browser-id@5.0.1: + resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} + engines: {node: '>=18'} + + default-browser@5.5.0: + resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==} + engines: {node: '>=18'} + define-data-property@1.1.4: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} + define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + define-properties@1.2.1: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} + defu@6.1.7: + resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} + delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} - detect-libc@2.0.3: - resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} - didyoumean@1.2.2: - resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + diff@8.0.4: + resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==} + engines: {node: '>=0.3.1'} - dlv@1.1.3: - resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} doctrine@2.1.0: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} - dom-helpers@5.2.1: - resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + + dot-prop@5.3.0: + resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} + engines: {node: '>=8'} + + dot-prop@9.0.0: + resolution: {integrity: sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==} + engines: {node: '>=18'} + + dotenv-expand@12.0.3: + resolution: {integrity: sha512-uc47g4b+4k/M/SeaW1y4OApx+mtLWl92l5LMPP0GNXctZqELk+YGgOPIIC5elYmUH4OuoK3JLhuRUYegeySiFA==} + engines: {node: '>=12'} + + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + engines: {node: '>=12'} - dotenv@16.4.7: - resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} + dotenv@17.4.2: + resolution: {integrity: sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==} engines: {node: '>=12'} dunder-proto@1.0.1: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + duplexer2@0.1.4: + resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} + + ecdsa-sig-formatter@1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + + eciesjs@0.4.18: + resolution: {integrity: sha512-wG99Zcfcys9fZux7Cft8BAX/YrOJLJSZ3jyYPfhZHqN2E+Ffx+QXBDsv3gubEgPtV6dTzJMSQUwk1H98/t/0wQ==} + engines: {bun: '>=1', deno: '>=2', node: '>=16'} - electron-to-chromium@1.5.18: - resolution: {integrity: sha512-1OfuVACu+zKlmjsNdcJuVQuVE61sZOLbNM4JAQ1Rvh6EOj0/EUKhMJjRH73InPlXSh8HIJk1cVZ8pyOV/FMdUQ==} + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - electron-to-chromium@1.5.49: - resolution: {integrity: sha512-ZXfs1Of8fDb6z7WEYZjXpgIRF6MEu8JdeGA0A40aZq6OQbS+eJpnnV49epZRna2DU/YsEjSQuGtQPPtvt6J65A==} + electron-to-chromium@1.5.340: + resolution: {integrity: sha512-908qahOGocRMinT2nM3ajCEM99H4iPdv84eagPP3FfZy/1ZGeOy2CZYzjhms81ckOPCXPlW7LkY4XpxD8r1DrA==} + + emoji-regex@10.6.0: + resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + emojilib@2.4.0: + resolution: {integrity: sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==} - error-ex@1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} - es-abstract@1.23.3: - resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} - engines: {node: '>= 0.4'} + enhanced-resolve@5.20.1: + resolution: {integrity: sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==} + engines: {node: '>=10.13.0'} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} + engines: {node: '>=0.12'} + + env-ci@11.2.0: + resolution: {integrity: sha512-D5kWfzkmaOQDioPmiviWAVtKmpPT4/iJmMVQxWxMPJTFyTkdc5JQUfc5iXEeWxcOdsYTKSAiA/Age4NUOqKsRA==} + engines: {node: ^18.17 || >=20.6.1} + + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + + environment@1.1.0: + resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} + engines: {node: '>=18'} + + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} - es-abstract@1.23.9: - resolution: {integrity: sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==} + es-abstract@1.24.2: + resolution: {integrity: sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==} engines: {node: '>= 0.4'} es-define-property@1.0.1: @@ -1332,35 +2548,34 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} - es-iterator-helpers@1.2.1: - resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} + es-iterator-helpers@1.3.2: + resolution: {integrity: sha512-HVLACW1TppGYjJ8H6/jqH/pqOtKRw6wMlrB23xfExmFWxFquAIWCmwoLsOyN96K4a5KbmOf5At9ZUO3GZbetAw==} engines: {node: '>= 0.4'} - es-object-atoms@1.0.0: - resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} - engines: {node: '>= 0.4'} + es-module-lexer@2.0.0: + resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==} - es-set-tostringtag@2.0.3: - resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} es-set-tostringtag@2.1.0: resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} engines: {node: '>= 0.4'} - es-shim-unscopables@1.0.2: - resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} - - es-to-primitive@1.2.1: - resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + es-shim-unscopables@1.1.0: + resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} engines: {node: '>= 0.4'} es-to-primitive@1.3.0: resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} - esbuild@0.24.2: - resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==} + es6-error@4.1.1: + resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} + + esbuild@0.27.7: + resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} engines: {node: '>=18'} hasBin: true @@ -1368,48 +2583,67 @@ packages: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} + escape-goat@4.0.0: + resolution: {integrity: sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==} + engines: {node: '>=12'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - eslint-config-prettier@10.0.1: - resolution: {integrity: sha512-lZBts941cyJyeaooiKxAtzoPHTN+GbQTJFAIdQbRhA4/8whaAraEh47Whw/ZFfrjNSnlAxqfm9i0XVAEkULjCw==} + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + eslint-config-prettier@10.1.8: + resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} hasBin: true peerDependencies: eslint: '>=7.0.0' - eslint-plugin-react-hooks@5.1.0: - resolution: {integrity: sha512-mpJRtPgHN2tNAvZ35AMfqeB3Xqeo273QxrHJsbBEPWODRM4r0yB6jfoROqKEYrOn27UtRPpcpHc2UqyBSuUNTw==} - engines: {node: '>=10'} + eslint-plugin-react-hooks@7.1.1: + resolution: {integrity: sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==} + engines: {node: '>=18'} peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0 - eslint-plugin-react@7.37.4: - resolution: {integrity: sha512-BGP0jRmfYyvOyvMoRX/uoUeW+GqNj9y16bPQzqAHf3AYII/tDs+jMN0dBVkl88/OZwNGwrVFxE7riHsXVfy/LQ==} + eslint-plugin-react@7.37.5: + resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} engines: {node: '>=4'} peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 - eslint-plugin-tailwindcss@3.18.0: - resolution: {integrity: sha512-PQDU4ZMzFH0eb2DrfHPpbgo87Zgg2EXSMOj1NSfzdZm+aJzpuwGerfowMIaVehSREEa0idbf/eoNYAOHSJoDAQ==} + eslint-plugin-tailwindcss@3.18.3: + resolution: {integrity: sha512-lqjNX7mt1Ip2qR236hvhbZ9ff2TFLUWou+tBHz82SA1nWFzOZSoEOI+9UBZmuf2977r2MMp9/y3/broyz8AYig==} engines: {node: '>=18.12.0'} peerDependencies: - tailwindcss: ^3.4.0 + tailwindcss: ^3.4.0 || ^4.0.0 - eslint-scope@8.2.0: - resolution: {integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==} + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - eslint-visitor-keys@4.2.0: - resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.19.0: - resolution: {integrity: sha512-ug92j0LepKlbbEv6hD911THhoRHmbdXt2gX+VDABAW/Ir7D3nqKdv5Pf5vtlyY6HQMTEP2skXY43ueqTCWssEA==} + eslint-visitor-keys@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@9.39.4: + resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -1418,12 +2652,17 @@ packages: jiti: optional: true - espree@10.3.0: - resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - esquery@1.5.0: - resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} engines: {node: '>=0.10'} esrecurse@4.3.0: @@ -1434,15 +2673,61 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + eventemitter3@5.0.4: + resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + + eventsource-parser@3.0.7: + resolution: {integrity: sha512-zwxwiQqexizSXFZV13zMiEtW1E3lv7RlUv+1f5FBiR4x7wFhEjm3aFTyYkZQWzyN08WnPdox015GoRH5D/E5YA==} + engines: {node: '>=18.0.0'} + + eventsource@3.0.7: + resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} + engines: {node: '>=18.0.0'} + + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + + execa@9.6.1: + resolution: {integrity: sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==} + engines: {node: ^18.19.0 || >=20.5.0} + + express-rate-limit@8.3.2: + resolution: {integrity: sha512-77VmFeJkO0/rvimEDuUC5H30oqUC4EyOhyGccfqoLebB0oiEYfM7nwPrsDsBL1gsTpwfzX8SFy2MT3TDyRq+bg==} + engines: {node: '>= 16'} + peerDependencies: + express: '>= 4.11' + + express@5.2.1: + resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} + engines: {node: '>= 18'} + + exsolve@1.0.8: + resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} + + fast-content-type-parse@3.0.0: + resolution: {integrity: sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - fast-glob@3.3.2: - resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} fast-json-stable-stringify@2.1.0: @@ -1451,39 +2736,102 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - fastq@1.15.0: - resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + fast-redact@3.5.0: + resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} + engines: {node: '>=6'} + + fast-string-truncated-width@3.0.3: + resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==} + + fast-string-width@3.0.2: + resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} + + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + + fast-wrap-ansi@0.2.0: + resolution: {integrity: sha512-rLV8JHxTyhVmFYhBJuMujcrHqOT2cnO5Zxj37qROj23CP39GXubJRBUFF0z8KFK77Uc0SukZUf7JZhsVEQ6n8w==} + + fastest-levenshtein@1.0.16: + resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} + engines: {node: '>= 4.9.1'} + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + + figures@2.0.0: + resolution: {integrity: sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==} + engines: {node: '>=4'} + + figures@6.1.0: + resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} + engines: {node: '>=18'} + + file-entry-cache@11.1.2: + resolution: {integrity: sha512-N2WFfK12gmrK1c1GXOqiAJ1tc5YE+R53zvQ+t5P8S5XhnmKYVB5eZEiLNZKDSmoG8wqqbF9EXYBBW/nef19log==} file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} + filesize@11.0.15: + resolution: {integrity: sha512-30TpbYxQxCpi4XdVjkwXYQ37CzZltV38+P7MYroQ+4NK/Dmx9mxixFNrolzcmEIBsjT/uowC9T7kiy2+C12r1A==} + engines: {node: '>= 10.8.0'} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} - find-root@1.1.0: - resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} + finalhandler@2.1.1: + resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} + engines: {node: '>= 18.0.0'} + + find-up-simple@1.0.1: + resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==} + engines: {node: '>=18'} + + find-up@2.1.0: + resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==} + engines: {node: '>=4'} find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} + find-versions@6.0.0: + resolution: {integrity: sha512-2kCCtc+JvcZ86IGAz3Z2Y0A1baIz9fL31pH/0S1IqZr9Iwnjq8izfPtrCyQKO6TLMPELLsQMre7VDqeIKCsHkA==} + engines: {node: '>=18'} + + firefox-profile@4.7.0: + resolution: {integrity: sha512-aGApEu5bfCNbA4PGUZiRJAIU6jKmghV2UVdklXAofnNtiDjqYw0czLS46W7IfFqVKgKhFB8Ao2YoNGHY4BoIMQ==} + engines: {node: '>=18'} + hasBin: true + flat-cache@4.0.1: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} - flatpickr@4.6.13: - resolution: {integrity: sha512-97PMG/aywoYpB4IvbvUJi0RQi8vearvU0oov1WW3k0WZPBMrTQVqekSX5CjSG/M4Q3i6A/0FKXC7RyAoAUUSPw==} - - flatted@3.3.2: - resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==} + flat-cache@6.1.22: + resolution: {integrity: sha512-N2dnzVJIphnNsjHcrxGW7DePckJ6haPrSFqpsBUhHYgwtKGVq4JrBGielEGD2fCVnsGm1zlBVZ8wGhkyuetgug==} - flatten-tailwindcss-theme@1.0.0: - resolution: {integrity: sha512-7B795m0qzLF0yQYGkfGanO3NOisEI4EaVObnr3DBq7Qc8Ygq4yWGa0Gpx2rtb10NSgIcimUqu4Xaqh+0bkC87w==} + flatted@3.4.2: + resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} - follow-redirects@1.15.6: - resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} + follow-redirects@1.16.0: + resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} engines: {node: '>=4.0'} peerDependencies: debug: '*' @@ -1491,27 +2839,39 @@ packages: debug: optional: true - for-each@0.3.3: - resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} - foreground-child@3.3.0: - resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} - engines: {node: '>=14'} + form-data-encoder@4.1.0: + resolution: {integrity: sha512-G6NsmEW15s0Uw9XnCg+33H3ViYRyiM0hMrMhhqQOR8NFc5GhYrI+6I3u7OTw7b91J2g8rtvMBZJDbcGb2YUniw==} + engines: {node: '>= 18'} - form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} engines: {node: '>= 6'} - formik@2.4.6: - resolution: {integrity: sha512-A+2EI7U7aG296q2TLGvNapDNTZp1khVt5Vk0Q/fyfSROss0V/V6+txt2aJnwEos44IxTCW/LYAi/zgWzlevj+g==} - peerDependencies: - react: '>=16.8.0' + formdata-node@6.0.3: + resolution: {integrity: sha512-8e1++BCiTzUno9v5IZ2J6bv4RU+3UKDmqWUQD0MIMVCd9AdhWkO1gw57oo1mNEX1dMq2EGI+FbWz4B92pscSQg==} + engines: {node: '>= 18'} + + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} - fraction.js@4.3.7: - resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + from2@2.3.0: + resolution: {integrity: sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==} - fs-extra@11.2.0: - resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + fs-extra@11.3.4: + resolution: {integrity: sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==} engines: {node: '>=14.14'} fsevents@2.3.2: @@ -1527,9 +2887,9 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - function.prototype.name@1.1.6: - resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} - engines: {node: '>= 0.4'} + function-timeout@1.0.2: + resolution: {integrity: sha512-939eZS4gJ3htTHAldmyyuzlrD58P03fHG49v2JfFXbV6OhvZKRC9j2yAtdHw/zrp2zXHuv05zMIy40F0ge7spA==} + engines: {node: '>=18'} function.prototype.name@1.1.8: resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} @@ -1538,26 +2898,74 @@ packages: functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + fuzzysort@3.1.0: + resolution: {integrity: sha512-sR9BNCjBg6LNgwvxlBd0sBABvQitkLzoVY9MYYROQVX/FvfJ4Mai9LsGhDgd8qYdds0bY77VzYd5iuB+v5rwQQ==} + + fx-runner@1.4.0: + resolution: {integrity: sha512-rci1g6U0rdTg6bAaBboP7XdRu01dzTAaKXxFf+PUqGuCv6Xu7o8NZdY1D5MvKGIjb6EdS1g3VlXOgksir1uGkg==} + hasBin: true + + generator-function@2.0.1: + resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} + engines: {node: '>= 0.4'} + gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} - get-intrinsic@1.2.7: - resolution: {integrity: sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==} + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-east-asian-width@1.5.0: + resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==} + engines: {node: '>=18'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} + get-own-enumerable-keys@1.0.0: + resolution: {integrity: sha512-PKsK2FSrQCyxcGHsGrLDcK0lx+0Ke+6e8KFFozA9/fIQLhQzPaRvJFdcz7+Axg3jUH/Mq+NI4xa5u/UT2tQskA==} + engines: {node: '>=14.16'} + + get-port-please@3.2.0: + resolution: {integrity: sha512-I9QVvBw5U/hw3RmWpYKRumUeaDgxTPd401x364rLmWBJcOQ753eov1eTgzDqRG9bqFIfDc7gfzcQEWrUri3o1A==} + get-proto@1.0.1: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} - get-symbol-description@1.0.2: - resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} - engines: {node: '>= 0.4'} + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + get-stream@7.0.1: + resolution: {integrity: sha512-3M8C1EOFN6r8AMUhwUAACIoXZJEOufDU5+0gFFN5uNs6XYOralD2Pqkl7m046va6x77FwposWXbAhPPIOus7mQ==} + engines: {node: '>=16'} + + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + + get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} + engines: {node: '>=18'} get-symbol-description@1.1.0: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} + get-tsconfig@4.14.0: + resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} + + giget@3.2.0: + resolution: {integrity: sha512-GvHTWcykIR/fP8cj8dMpuMMkvaeJfPvYnhq0oW+chSeIr+ldX21ifU2Ms6KBoyKZQZmVaUAAhQ2EZ68KJF8a7A==} + hasBin: true + + git-log-parser@1.2.1: + resolution: {integrity: sha512-PI+sPDvHXNPl5WNOErAK05s3j0lgwUzMN6o8cyQrDaKfT3qd7TmNJKeXX+SknI5I0QhG5fVPAEwSY4tRGDtYoQ==} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -1566,50 +2974,84 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} - glob@10.4.5: - resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} - hasBin: true + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} + global-directory@4.0.1: + resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} + engines: {node: '>=18'} + + global-modules@2.0.0: + resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==} + engines: {node: '>=6'} + + global-prefix@3.0.0: + resolution: {integrity: sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==} + engines: {node: '>=6'} globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} - globals@15.14.0: - resolution: {integrity: sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==} + globals@17.5.0: + resolution: {integrity: sha512-qoV+HK2yFl/366t2/Cb3+xxPUo5BuMynomoDmiaZBIdbs+0pYbjfZU+twLhGKp4uCZ/+NbtpVepH5bGCxRyy2g==} engines: {node: '>=18'} globalthis@1.0.4: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} + globby@16.2.0: + resolution: {integrity: sha512-QrJia2qDf5BB/V6HYlDTs0I0lBahyjLzpGQg3KT7FnCdTonAyPy2RtY802m2k4ALx6Dp752f82WsOczEVr3l6Q==} + engines: {node: '>=20'} + + globjoin@0.1.4: + resolution: {integrity: sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==} + gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} + graceful-fs@4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + graceful-readlink@1.0.1: + resolution: {integrity: sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==} + + graphql@16.13.2: + resolution: {integrity: sha512-5bJ+nf/UCpAjHM8i06fl7eLyVC9iuNAjm9qzkiu2ZGhM0VscSvS6WDPfAwkdkBuoXGM9FJSbKl6wylMwP9Ktig==} + engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + + growly@1.3.0: + resolution: {integrity: sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==} + + handlebars@4.7.9: + resolution: {integrity: sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==} + engines: {node: '>=0.4.7'} + hasBin: true + + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} - has-bigints@1.0.2: - resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + has-flag@5.0.1: + resolution: {integrity: sha512-CsNUt5x9LUdx6hnk/E2SZLsDyvfqANZSUq4+D3D8RzDJ2M+HDTIkF60ibS1vHaK55vzgiZw1bEPFG9yH7l33wA==} + engines: {node: '>=12'} + has-property-descriptors@1.0.2: resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - has-proto@1.0.3: - resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} - engines: {node: '>= 0.4'} - has-proto@1.2.0: resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} engines: {node: '>= 0.4'} @@ -1622,45 +3064,163 @@ packages: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + hashery@1.5.1: + resolution: {integrity: sha512-iZyKG96/JwPz1N55vj2Ie2vXbhu440zfUfJvSwEqEbeLluk7NnapfGqa7LH0mOsnDxTF85Mx8/dyR6HfqcbmbQ==} + engines: {node: '>=20'} + + hasown@2.0.3: + resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} engines: {node: '>= 0.4'} - hoist-non-react-statics@3.3.2: - resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + headers-polyfill@5.0.1: + resolution: {integrity: sha512-1TJ6Fih/b8h5TIcv+1+Hw0PDQWJTKDKzFZzcKOiW1wJza3XoAQlkCuXLbymPYB8+ZQyw8mHvdw560e8zVFIWyA==} + + hermes-estree@0.25.1: + resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==} + + hermes-parser@0.25.1: + resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==} + + highlight.js@10.7.3: + resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} + + hono@4.12.14: + resolution: {integrity: sha512-am5zfg3yu6sqn5yjKBNqhnTX7Cv+m00ox+7jbaKkrLMRJ4rAdldd1xPd/JzbBWspqaQv6RSTrgFN95EsfhC+7w==} + engines: {node: '>=16.9.0'} + + hook-std@4.0.0: + resolution: {integrity: sha512-IHI4bEVOt3vRUDJ+bFA9VUJlo7SzvFARPNLw75pqSmAOP2HmTWfFJtPvLBrDrlgjEYXY9zs7SFdHPQaJShkSCQ==} + engines: {node: '>=20'} + + hookable@6.1.1: + resolution: {integrity: sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==} + + hookified@1.15.1: + resolution: {integrity: sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg==} + + hookified@2.1.1: + resolution: {integrity: sha512-AHb76R16GB5EsPBE2J7Ko5kiEyXwviB9P5SMrAKcuAu4vJPZttViAbj9+tZeaQE5zjDme+1vcHP78Yj/WoAveA==} + + hosted-git-info@7.0.2: + resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} + engines: {node: ^16.14.0 || >=18.0.0} + + hosted-git-info@9.0.2: + resolution: {integrity: sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==} + engines: {node: ^20.17.0 || >=22.9.0} + + html-escaper@3.0.3: + resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} + + html-tags@5.1.0: + resolution: {integrity: sha512-n6l5uca7/y5joxZ3LUePhzmBFUJ+U2YWzhMa8XUTecSeSlQiZdF5XAd/Q3/WUl0VsXgUwWi8I7CNIwdI5WN1SQ==} + engines: {node: '>=20.10'} + + htmlparser2@10.1.0: + resolution: {integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + + human-signals@8.0.1: + resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==} + engines: {node: '>=18.18.0'} + + iconv-lite@0.7.2: + resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} + engines: {node: '>=0.10.0'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} - ignore@5.3.1: - resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} engines: {node: '>= 4'} immediate@3.0.6: resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} - import-fresh@3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} + import-from-esm@2.0.0: + resolution: {integrity: sha512-YVt14UZCgsX1vZQ3gKjkWVdBdHQ6eu3MPU1TBgL1H5orXe2+jWD006WCPPtOuwlQm10NuzOW5WawiF1Q9veW8g==} + engines: {node: '>=18.20'} + + import-meta-resolve@4.2.0: + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} + imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + indent-string@5.0.0: + resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} + engines: {node: '>=12'} + + index-to-position@1.2.0: + resolution: {integrity: sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==} + engines: {node: '>=18'} + inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - internal-slot@1.0.7: - resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} - engines: {node: '>= 0.4'} + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + ini@4.1.1: + resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + ini@4.1.3: + resolution: {integrity: sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} internal-slot@1.1.0: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} - intl-messageformat@10.7.14: - resolution: {integrity: sha512-mMGnE4E1otdEutV5vLUdCxRJygHB5ozUBxsPB5qhitewssrS/qGruq9bmvIRkkGsNeK5ZWLfYRld18UHGTIifQ==} + intl-messageformat@11.2.1: + resolution: {integrity: sha512-1gAVEUt3wEPvTqML4Fsw9klZV5j0vszQxayP/fi6gUroAc8AUHiNaisBKLWxybL1AdWq1mP07YV1q8v4N92ilQ==} - is-array-buffer@3.0.4: - resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} - engines: {node: '>= 0.4'} + into-stream@7.0.0: + resolution: {integrity: sha512-2dYz766i9HprMBasCMvHMuazJ7u4WzhJwo5kb3iPSiW/iRYV6uPari3zHoqZlnuaR7V1bEiNMxikhp37rdBXbw==} + engines: {node: '>=12'} + + ip-address@10.1.0: + resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==} + engines: {node: '>= 12'} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + is-absolute@0.1.7: + resolution: {integrity: sha512-Xi9/ZSn4NFapG8RP98iNPMOeaV3mXPisxKxzKtHVqr3g56j/fBn+yZmnxSVAA8lmZbl2J9b/a4kJvfU3hqQYgA==} + engines: {node: '>=0.10.0'} is-array-buffer@3.0.5: resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} @@ -1669,16 +3229,10 @@ packages: is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - is-arrayish@0.3.2: - resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} - - is-async-function@2.0.0: - resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} engines: {node: '>= 0.4'} - is-bigint@1.0.4: - resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} - is-bigint@1.1.0: resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} engines: {node: '>= 0.4'} @@ -1687,10 +3241,6 @@ packages: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} - is-boolean-object@1.1.2: - resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} - engines: {node: '>= 0.4'} - is-boolean-object@1.2.2: resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} engines: {node: '>= 0.4'} @@ -1699,25 +3249,28 @@ packages: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} - is-core-module@2.13.1: - resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} - - is-data-view@1.0.1: - resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} engines: {node: '>= 0.4'} is-data-view@1.0.2: resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} engines: {node: '>= 0.4'} - is-date-object@1.0.5: - resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} - engines: {node: '>= 0.4'} - is-date-object@1.1.0: resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} engines: {node: '>= 0.4'} + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -1730,14 +3283,40 @@ packages: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} - is-generator-function@1.0.10: - resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + is-fullwidth-code-point@5.1.0: + resolution: {integrity: sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==} + engines: {node: '>=18'} + + is-generator-function@1.1.2: + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} engines: {node: '>= 0.4'} is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-in-ci@1.0.0: + resolution: {integrity: sha512-eUuAjybVTHMYWm/U+vBO1sY/JOCgoPCXRxzdju0K+K0BiGW0SChEL1MLC0PoCIR1OlPo5YAp8HuQoUlsWEICwg==} + engines: {node: '>=18'} + hasBin: true + + is-in-ssh@1.0.0: + resolution: {integrity: sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==} + engines: {node: '>=20'} + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + + is-installed-globally@1.0.0: + resolution: {integrity: sha512-K55T22lfpQ63N4KEN57jZUAaAYqYHEe8veb/TycJRk9DdSCLLcovXz/mL6mOnhQaZsQGwPhuFopdQIlqGSEjiQ==} + engines: {node: '>=18'} + + is-interactive@2.0.0: + resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} + engines: {node: '>=12'} + is-map@2.0.3: resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} engines: {node: '>= 0.4'} @@ -1746,9 +3325,12 @@ packages: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} - is-number-object@1.0.7: - resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} - engines: {node: '>= 0.4'} + is-node-process@1.2.0: + resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} + + is-npm@6.1.0: + resolution: {integrity: sha512-O2z4/kNgyjhQwVR1Wpkbfc19JIhggF97NZNCpWTnjH7kVcZMUrnut9XSN7txI7VdyIYk5ZatOq3zvSuWpU8hoA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} is-number-object@1.1.1: resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} @@ -1758,57 +3340,96 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - is-regex@1.1.4: - resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} - engines: {node: '>= 0.4'} + is-obj@2.0.0: + resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} + engines: {node: '>=8'} + + is-obj@3.0.0: + resolution: {integrity: sha512-IlsXEHOjtKhpN8r/tRFj2nDyTmHvcfNeu/nrRIcXE17ROeatXchkojffa1SpdqW4cr/Fj6QkEf/Gn4zf6KKvEQ==} + engines: {node: '>=12'} + + is-path-inside@4.0.0: + resolution: {integrity: sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==} + engines: {node: '>=12'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + + is-plain-object@5.0.0: + resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} + engines: {node: '>=0.10.0'} + + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + + is-primitive@3.0.1: + resolution: {integrity: sha512-GljRxhWvlCNRfZyORiH77FwdFwGcMO620o37EOYC0ORWdq+WYNVqW0w2Juzew4M+L81l6/QS3t5gkkihyRqv9w==} + engines: {node: '>=0.10.0'} + + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} is-regex@1.2.1: resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} engines: {node: '>= 0.4'} + is-regexp@3.1.0: + resolution: {integrity: sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA==} + engines: {node: '>=12'} + + is-relative@0.1.3: + resolution: {integrity: sha512-wBOr+rNM4gkAZqoLRJI4myw5WzzIdQosFAAbnvfXP5z1LyzgAI3ivOKehC5KfqlQJZoihVhirgtCBj378Eg8GA==} + engines: {node: '>=0.10.0'} + is-set@2.0.3: resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} engines: {node: '>= 0.4'} - is-shared-array-buffer@1.0.3: - resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} - engines: {node: '>= 0.4'} - is-shared-array-buffer@1.0.4: resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} engines: {node: '>= 0.4'} - is-string@1.0.7: - resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} - engines: {node: '>= 0.4'} + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-stream@4.0.1: + resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} + engines: {node: '>=18'} is-string@1.1.1: resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} engines: {node: '>= 0.4'} - is-symbol@1.0.4: - resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} - engines: {node: '>= 0.4'} - is-symbol@1.1.1: resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} engines: {node: '>= 0.4'} - is-typed-array@1.1.13: - resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} - engines: {node: '>= 0.4'} - is-typed-array@1.1.15: resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} engines: {node: '>= 0.4'} + is-unicode-supported@1.3.0: + resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} + engines: {node: '>=12'} + + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} + is-weakmap@2.0.2: resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} engines: {node: '>= 0.4'} - is-weakref@1.0.2: - resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} - is-weakref@1.1.1: resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} engines: {node: '>= 0.4'} @@ -1817,68 +3438,151 @@ packages: resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} engines: {node: '>= 0.4'} + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + + is-wsl@3.1.1: + resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} + engines: {node: '>=16'} + isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + isbot@5.1.39: + resolution: {integrity: sha512-obH0yYahGXdzNxo+djmHhBYThUKDkz565cxkIlt2L9hXfv1NlaLKoDBHo6KxXsYrIXx2RK3x5vY36CfZcobxEw==} + engines: {node: '>=18'} + + isexe@1.1.2: + resolution: {integrity: sha512-d2eJzK691yZwPHcv1LbeAOa91yMJ9QmfTgSO1oXB65ezVhXQsxBac2vEB4bMVms9cGzaA99n6V2viHMq82VLDw==} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isexe@3.1.5: + resolution: {integrity: sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==} + engines: {node: '>=18'} + + isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + + issue-parser@7.0.1: + resolution: {integrity: sha512-3YZcUUR2Wt1WsapF+S/WiA2WmlW0cWAoPccMqne7AxEBhCdFeTPjfv/Axb8V2gyCgY3nRw+ksZ3xSUX+R47iAg==} + engines: {node: ^18.17 || >=20.6.1} + iterator.prototype@1.1.5: resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} engines: {node: '>= 0.4'} - jackspeak@3.4.3: - resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + java-properties@1.0.2: + resolution: {integrity: sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==} + engines: {node: '>= 0.6.0'} - jiti@1.21.6: - resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true + jose@6.2.2: + resolution: {integrity: sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + js-tokens@9.0.1: + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true - jsesc@3.0.2: - resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} hasBin: true json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + json-parse-better-errors@1.0.2: + resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} + json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + json-parse-even-better-errors@3.0.2: + resolution: {integrity: sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-schema-typed@8.0.2: + resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} + json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + json-with-bigint@3.5.8: + resolution: {integrity: sha512-eq/4KP6K34kwa7TcFdtvnftvHCD9KvHOGGICWwMFc4dOOKF5t4iYqnfLK8otCRCRv06FXOzGGyqE8h8ElMvvdw==} + json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} hasBin: true - jsonfile@6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} - jsx-ast-utils@3.3.4: - resolution: {integrity: sha512-fX2TVdCViod6HwKEtSWGHs57oFhVfCMwieb9PuRDgjDPh5XeqJiHFFFJCHxU5cnTc3Bu/GRL+kPiFmw8XWOfKw==} + jsonwebtoken@9.0.3: + resolution: {integrity: sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==} + engines: {node: '>=12', npm: '>=6'} + + jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} jszip@3.10.1: resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} + jwa@2.0.1: + resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} + + jws@4.0.1: + resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + keyv@5.6.0: + resolution: {integrity: sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + + ky@1.14.3: + resolution: {integrity: sha512-9zy9lkjac+TR1c2tG+mkNSVlyOpInnWdSMiue4F+kq8TwJSgv6o8jhLRg8Ho6SnZ9wOYUq/yozts9qQCfk7bIw==} + engines: {node: '>=18'} + + latest-version@9.0.0: + resolution: {integrity: sha512-7W0vV3rqv5tokqkBAFV1LbR7HPOWzXQDpDgEuib/aJ1jsZZx6x3c2mBI+TJhJzOhkGeaLbCKEHXEXLfirtG2JA==} + engines: {node: '>=18'} + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -1886,25 +3590,171 @@ packages: lie@3.3.0: resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} - lilconfig@3.1.3: - resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} - engines: {node: '>=14'} + lighthouse-logger@2.0.2: + resolution: {integrity: sha512-vWl2+u5jgOQuZR55Z1WM0XDdrJT6mzMP8zHUct7xTlWhuQs+eV0g+QL0RQdFjT54zVmbhLCP8vIVpy1wGn/gCg==} + + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + lines-and-columns@2.0.4: + resolution: {integrity: sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + linkedom@0.18.12: + resolution: {integrity: sha512-jalJsOwIKuQJSeTvsgzPe9iJzyfVaEJiEXl+25EkKevsULHvMJzpNqwvj1jOESWdmgKDiXObyjOYwlUqG7wo1Q==} + engines: {node: '>=16'} + peerDependencies: + canvas: '>= 2' + peerDependenciesMeta: + canvas: + optional: true + + listr2@10.2.1: + resolution: {integrity: sha512-7I5knELsJKTUjXG+A6BkKAiGkW1i25fNa/xlUl9hFtk15WbE9jndA89xu5FzQKrY5llajE1hfZZFMILXkDHk/Q==} + engines: {node: '>=22.13.0'} + + load-json-file@4.0.0: + resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} + engines: {node: '>=4'} + + local-pkg@1.1.2: + resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==} + engines: {node: '>=14'} + + locate-path@2.0.0: + resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} + engines: {node: '>=4'} + locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} - lodash-es@4.17.21: - resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + lodash-es@4.18.1: + resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==} + + lodash.capitalize@4.2.1: + resolution: {integrity: sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw==} + + lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + + lodash.escaperegexp@4.1.2: + resolution: {integrity: sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==} + + lodash.includes@4.3.0: + resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} + + lodash.isboolean@3.0.3: + resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} + + lodash.isinteger@4.0.4: + resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} + + lodash.isnumber@3.0.3: + resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} + + lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + + lodash.isstring@4.0.1: + resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + lodash.once@4.1.1: + resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} + + lodash.truncate@4.4.2: + resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} + + lodash.uniqby@4.7.0: + resolution: {integrity: sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==} + + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} + + log-symbols@6.0.0: + resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==} + engines: {node: '>=18'} + + log-update@6.1.0: + resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} + engines: {node: '>=18'} loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} @@ -1913,15 +3763,77 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@11.3.5: + resolution: {integrity: sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==} + engines: {node: 20 || >=22} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lucide-react@1.8.0: + resolution: {integrity: sha512-WuvlsjngSk7TnTBJ1hsCy3ql9V9VOdcPkd3PKcSmM34vJD8KG6molxz7m7zbYFgICwsanQWmJ13JlYs4Zp7Arw==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + magicast@0.5.2: + resolution: {integrity: sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ==} + + make-asynchronous@1.1.0: + resolution: {integrity: sha512-ayF7iT+44LXdxJLTrTd3TLQpFDDvPCBxXxbv+pMUSuHA5Q8zyAfwkRP6aHHwNVFBUFWtxAHqwNJxF8vMZLAbVg==} + engines: {node: '>=18'} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + many-keys-map@3.0.3: + resolution: {integrity: sha512-1DiZmDHPXMBgMRjeUtHy1q1VYmeJscHxhIAexX9z/zjRMP80+0ETuPfssi8z+kMY4DwUgsKuHqpjxgmeA9gBNA==} + engines: {node: '>=18'} + + marked-terminal@7.3.0: + resolution: {integrity: sha512-t4rBvPsHc57uE/2nJOLmMbZCQ4tgAccAED3ngXQqW6g+TxA488JzJ+FK3lQkzBQOI1mRV/r/Kq+1ZlJ4D0owQw==} + engines: {node: '>=16.0.0'} + peerDependencies: + marked: '>=1 <16' + + marked@15.0.12: + resolution: {integrity: sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==} + engines: {node: '>= 18'} + hasBin: true + + marky@1.3.0: + resolution: {integrity: sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ==} + math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} - memoize-one@6.0.0: - resolution: {integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==} + mathml-tag-names@4.0.0: + resolution: {integrity: sha512-aa6AU2Pcx0VP/XWnh8IGL0SYSgQHDT6Ucror2j2mXeFAlN3ahaNs8EZtG1YiticMkSLj3Gt6VPFfZogt7G5iFQ==} + + mdn-data@2.27.1: + resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} + + media-typer@1.1.0: + resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} + engines: {node: '>= 0.8'} + + meow@13.2.0: + resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==} + engines: {node: '>=18'} + + meow@14.1.0: + resolution: {integrity: sha512-EDYo6VlmtnumlcBCbh1gLJ//9jvM/ndXHfVXIFrZVr6fGcwTUyCTFNTLCKuY3ffbK8L/+3Mzqnd58RojiZqHVw==} + engines: {node: '>=20'} + + merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} + engines: {node: '>=18'} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} @@ -1935,54 +3847,238 @@ packages: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + mime-types@2.1.35: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + + mime@4.1.0: + resolution: {integrity: sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw==} + engines: {node: '>=16'} + hasBin: true + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + + mimic-function@5.0.1: + resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} + engines: {node: '>=18'} + + minimatch@10.2.5: + resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} + engines: {node: 18 || 20 || >=22} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minimatch@9.0.4: - resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} - engines: {node: '>=16 || 14 >=14.17'} + mlly@1.8.2: + resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + msw@2.13.4: + resolution: {integrity: sha512-fPlKBeFe+8rpcyR3umUmmHuNwu6gc6T3STvkgEa9WDX/HEgal9wDeflpCUAIRtmvaLZM2igfI5y1bZ9G5J26KA==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + typescript: '>= 4.8.x' + peerDependenciesMeta: + typescript: + optional: true - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} + multimatch@6.0.0: + resolution: {integrity: sha512-I7tSVxHGPlmPN/enE3mS1aOSo6bWBfls+3HmuEeCUBCE7gWnm3cBXCBkpurzFjVRwC6Kld8lLaZ1Iv5vOcjvcQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + mute-stream@3.0.0: + resolution: {integrity: sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==} + engines: {node: ^20.17.0 || >=22.9.0} mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - nanoid@3.3.8: - resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} + nano-spawn@2.1.0: + resolution: {integrity: sha512-yTW+2okrElHiH4fsiz/+/zc0EDo9BDDoC3iKk8dpv1GeRc9nUWzUZHx6TofMWErchhUQR8hY9/Eu1Uja9x1nqA==} + engines: {node: '>=20.17'} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + nanospinner@1.2.2: + resolution: {integrity: sha512-Zt/AmG6qRU3e+WnzGGLuMCEAO/dAu45stNbHY223tUxldaDAeE+FxSPsd9Q+j+paejmm0ZbrNVs5Sraqy3dRxA==} + natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - node-releases@2.0.18: - resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} - normalize-path@3.0.0: + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + nerf-dart@1.0.0: + resolution: {integrity: sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g==} + + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + deprecated: Use your platform's native DOMException instead + + node-emoji@2.2.0: + resolution: {integrity: sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==} + engines: {node: '>=18'} + + node-exports-info@1.6.0: + resolution: {integrity: sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==} + engines: {node: '>= 0.4'} + + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + + node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + node-forge@1.4.0: + resolution: {integrity: sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==} + engines: {node: '>= 6.13.0'} + + node-notifier@10.0.1: + resolution: {integrity: sha512-YX7TSyDukOZ0g+gmzjB6abKu+hTGvO8+8+gIFDsRCU2t8fLV/P2unmt+LGFaIa4y64aX98Qksa97rgz4vMNeLQ==} + + node-releases@2.0.37: + resolution: {integrity: sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==} + + normalize-package-data@6.0.2: + resolution: {integrity: sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==} + engines: {node: ^16.14.0 || >=18.0.0} + + normalize-package-data@8.0.0: + resolution: {integrity: sha512-RWk+PI433eESQ7ounYxIp67CYuVsS1uYSonX3kA6ps/3LWfjVQa/ptEg6Y3T6uAMq1mWpX9PQ+qx+QaHpsc7gQ==} + engines: {node: ^20.17.0 || >=22.9.0} + + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} - normalize-range@0.1.2: - resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} - engines: {node: '>=0.10.0'} + normalize-url@9.0.0: + resolution: {integrity: sha512-z9nC87iaZXXySbWWtTHfCFJyFvKaUAW6lODhikG7ILSbVgmwuFjUqkgnheHvAUcGedO29e2QGBRXMUD64aurqQ==} + engines: {node: '>=20'} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + npm-run-path@6.0.0: + resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} + engines: {node: '>=18'} + + npm@11.12.1: + resolution: {integrity: sha512-zcoUuF1kezGSAo0CqtvoLXX3mkRqzuqYdL6Y5tdo8g69NVV3CkjQ6ZBhBgB4d7vGkPcV6TcvLi3GRKPDFX+xTA==} + engines: {node: ^20.17.0 || >=22.9.0} + hasBin: true + bundledDependencies: + - '@isaacs/string-locale-compare' + - '@npmcli/arborist' + - '@npmcli/config' + - '@npmcli/fs' + - '@npmcli/map-workspaces' + - '@npmcli/metavuln-calculator' + - '@npmcli/package-json' + - '@npmcli/promise-spawn' + - '@npmcli/redact' + - '@npmcli/run-script' + - '@sigstore/tuf' + - abbrev + - archy + - cacache + - chalk + - ci-info + - fastest-levenshtein + - fs-minipass + - glob + - graceful-fs + - hosted-git-info + - ini + - init-package-json + - is-cidr + - json-parse-even-better-errors + - libnpmaccess + - libnpmdiff + - libnpmexec + - libnpmfund + - libnpmorg + - libnpmpack + - libnpmpublish + - libnpmsearch + - libnpmteam + - libnpmversion + - make-fetch-happen + - minimatch + - minipass + - minipass-pipeline + - ms + - node-gyp + - nopt + - npm-audit-report + - npm-install-checks + - npm-package-arg + - npm-pick-manifest + - npm-profile + - npm-registry-fetch + - npm-user-validate + - p-map + - pacote + - parse-conflict-json + - proc-log + - qrcode-terminal + - read + - semver + - spdx-expression-parse + - ssri + - supports-color + - tar + - text-table + - tiny-relative-date + - treeverse + - validate-npm-package-name + - which + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + nypm@0.6.5: + resolution: {integrity: sha512-K6AJy1GMVyfyMXRVB88700BJqNUkByijGJM8kEHpLdcAt+vSQAVfkWWHYzuRXHSY6xA2sNc5RjTj0p9rE2izVQ==} + engines: {node: '>=18'} + hasBin: true object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} - object-hash@3.0.0: - resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} - engines: {node: '>= 6'} - object-inspect@1.13.4: resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} engines: {node: '>= 0.4'} @@ -1991,16 +4087,16 @@ packages: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} - object.assign@4.1.5: - resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} - engines: {node: '>= 0.4'} + object-treeify@1.1.33: + resolution: {integrity: sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==} + engines: {node: '>= 10'} object.assign@4.1.7: resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} engines: {node: '>= 0.4'} - object.entries@1.1.8: - resolution: {integrity: sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==} + object.entries@1.1.9: + resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} engines: {node: '>= 0.4'} object.fromentries@2.0.8: @@ -2011,24 +4107,120 @@ packages: resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} engines: {node: '>= 0.4'} - optionator@0.9.3: - resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + obug@2.1.1: + resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + + ofetch@1.5.1: + resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} + + ohash@2.0.11: + resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} + + on-exit-leak-free@2.1.2: + resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} + engines: {node: '>=14.0.0'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + + onetime@7.0.0: + resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} + engines: {node: '>=18'} + + open@11.0.0: + resolution: {integrity: sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw==} + engines: {node: '>=20'} + + open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} + ora@8.2.0: + resolution: {integrity: sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==} + engines: {node: '>=18'} + + os-shim@0.1.3: + resolution: {integrity: sha512-jd0cvB8qQ5uVt0lvCIexBaROw1KyKm5sbulg2fWOHjETisuCzWyt+eTZKEMs8v6HwzoGs8xik26jg7eCM6pS+A==} + engines: {node: '>= 0.4.0'} + + outvariant@1.4.3: + resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} + own-keys@1.0.1: resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} engines: {node: '>= 0.4'} + p-each-series@3.0.0: + resolution: {integrity: sha512-lastgtAdoH9YaLyDa5i5z64q+kzOcQHsQ5SsZJD3q0VEyI8mq872S3geuNbRUQLVAE9siMfgKrpj7MloKFHruw==} + engines: {node: '>=12'} + + p-event@6.0.1: + resolution: {integrity: sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w==} + engines: {node: '>=16.17'} + + p-filter@4.1.0: + resolution: {integrity: sha512-37/tPdZ3oJwHaS3gNJdenCDB3Tz26i9sjhnguBtvN0vYlRIiDNnvTWkuh+0hETV9rLPdJ3rlL3yVOYPIAnM8rw==} + engines: {node: '>=18'} + + p-is-promise@3.0.0: + resolution: {integrity: sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==} + engines: {node: '>=8'} + + p-limit@1.3.0: + resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} + engines: {node: '>=4'} + p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} + p-locate@2.0.0: + resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} + engines: {node: '>=4'} + p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} - package-json-from-dist@1.0.1: - resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + p-map@7.0.4: + resolution: {integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==} + engines: {node: '>=18'} + + p-reduce@2.1.0: + resolution: {integrity: sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==} + engines: {node: '>=8'} + + p-reduce@3.0.0: + resolution: {integrity: sha512-xsrIUgI0Kn6iyDYm9StOpOeK29XM1aboGji26+QEortiFST1hGZaUQOLhtEbqHErPpGW/aSz6allwK2qcptp0Q==} + engines: {node: '>=12'} + + p-timeout@6.1.4: + resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} + engines: {node: '>=14.16'} + + p-try@1.0.0: + resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} + engines: {node: '>=4'} + + package-json@10.0.1: + resolution: {integrity: sha512-ua1L4OgXSBdsu1FPb7F3tYH0F48a6kxvod4pLUlGY9COeJAJQNX/sNH2IiEmsxw7lqYiAwrdHMjz1FctOsyDQg==} + engines: {node: '>=18'} pako@1.0.11: resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} @@ -2037,10 +4229,46 @@ packages: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} + parse-json@4.0.0: + resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} + engines: {node: '>=4'} + parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} + parse-json@7.1.1: + resolution: {integrity: sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==} + engines: {node: '>=16'} + + parse-json@8.3.0: + resolution: {integrity: sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==} + engines: {node: '>=18'} + + parse-ms@4.0.0: + resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} + engines: {node: '>=18'} + + parse5-htmlparser2-tree-adapter@6.0.1: + resolution: {integrity: sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==} + + parse5@5.1.1: + resolution: {integrity: sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==} + + parse5@6.0.1: + resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + + path-exists@3.0.0: + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} + engines: {node: '>=4'} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -2049,99 +4277,114 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-scurry@1.11.1: - resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} - engines: {node: '>=16 || 14 >=14.18'} + path-to-regexp@6.3.0: + resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + + path-to-regexp@8.4.2: + resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==} path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} - picocolors@1.0.1: - resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + perfect-debounce@2.1.0: + resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==} picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} engines: {node: '>=8.6'} - pify@2.3.0: - resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} - engines: {node: '>=0.10.0'} + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} - pirates@4.0.5: - resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} - engines: {node: '>= 6'} + pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + + pino-abstract-transport@2.0.0: + resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} - playwright-core@1.50.1: - resolution: {integrity: sha512-ra9fsNWayuYumt+NiM069M6OkcRb1FZSK8bgi66AtpFoWkg2+y0bJSNmkFrWhMbEBbVKC/EruAHH3g0zmtwGmQ==} + pino-std-serializers@7.1.0: + resolution: {integrity: sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==} + + pino@9.7.0: + resolution: {integrity: sha512-vnMCM6xZTb1WDmLvtG2lE/2p+t9hDEIvTWJsu6FejkE62vB7gDhvzrpFR4Cw2to+9JNQxVnkAKVPA1KPB98vWg==} + hasBin: true + + pkce-challenge@5.0.1: + resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} + engines: {node: '>=16.20.0'} + + pkg-conf@2.1.0: + resolution: {integrity: sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==} + engines: {node: '>=4'} + + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + pkg-types@2.3.0: + resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} + + playwright-core@1.59.1: + resolution: {integrity: sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==} engines: {node: '>=18'} hasBin: true - playwright@1.50.1: - resolution: {integrity: sha512-G8rwsOQJ63XG6BbKj2w5rHeavFjy5zynBA9zsJMMtBoe/Uf757oG12NXz6e6OirF7RCrTVAKFXbLmn1RbL7Qaw==} + playwright@1.59.1: + resolution: {integrity: sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==} engines: {node: '>=18'} hasBin: true - possible-typed-array-names@1.0.0: - resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} - postcss-import@15.1.0: - resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} - engines: {node: '>=14.0.0'} - peerDependencies: - postcss: ^8.0.0 - - postcss-js@4.0.1: - resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} - engines: {node: ^12 || ^14 || >= 16} - peerDependencies: - postcss: ^8.4.21 - - postcss-load-config@4.0.2: - resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} - engines: {node: '>= 14'} - peerDependencies: - postcss: '>=8.0.9' - ts-node: '>=9.0.0' - peerDependenciesMeta: - postcss: - optional: true - ts-node: - optional: true - - postcss-nested@6.2.0: - resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} - engines: {node: '>=12.0'} + postcss-safe-parser@7.0.1: + resolution: {integrity: sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==} + engines: {node: '>=18.0'} peerDependencies: - postcss: ^8.2.14 + postcss: ^8.4.31 - postcss-selector-parser@6.1.2: - resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + postcss-selector-parser@7.1.1: + resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} engines: {node: '>=4'} postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - postcss@8.5.1: - resolution: {integrity: sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==} + postcss@8.5.10: + resolution: {integrity: sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==} engines: {node: ^10 || ^12 || >=14} + powershell-utils@0.1.0: + resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==} + engines: {node: '>=20'} + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier-plugin-tailwindcss@0.6.11: - resolution: {integrity: sha512-YxaYSIvZPAqhrrEpRtonnrXdghZg1irNg4qrjboCXrpybLWVs55cW2N3juhspVJiO0JBvYJT8SYsJpc8OQSnsA==} - engines: {node: '>=14.21.3'} + prettier-plugin-tailwindcss@0.7.2: + resolution: {integrity: sha512-LkphyK3Fw+q2HdMOoiEHWf93fNtYJwfamoKPl7UwtjFQdei/iIBoX11G6j706FzN3ymX9mPVi97qIY8328vdnA==} + engines: {node: '>=20.19'} peerDependencies: '@ianvs/prettier-plugin-sort-imports': '*' + '@prettier/plugin-hermes': '*' + '@prettier/plugin-oxc': '*' '@prettier/plugin-pug': '*' '@shopify/prettier-plugin-liquid': '*' '@trivago/prettier-plugin-sort-imports': '*' @@ -2149,18 +4392,20 @@ packages: prettier: ^3.0 prettier-plugin-astro: '*' prettier-plugin-css-order: '*' - prettier-plugin-import-sort: '*' prettier-plugin-jsdoc: '*' prettier-plugin-marko: '*' prettier-plugin-multiline-arrays: '*' prettier-plugin-organize-attributes: '*' prettier-plugin-organize-imports: '*' prettier-plugin-sort-imports: '*' - prettier-plugin-style-order: '*' prettier-plugin-svelte: '*' peerDependenciesMeta: '@ianvs/prettier-plugin-sort-imports': optional: true + '@prettier/plugin-hermes': + optional: true + '@prettier/plugin-oxc': + optional: true '@prettier/plugin-pug': optional: true '@shopify/prettier-plugin-liquid': @@ -2173,8 +4418,6 @@ packages: optional: true prettier-plugin-css-order: optional: true - prettier-plugin-import-sort: - optional: true prettier-plugin-jsdoc: optional: true prettier-plugin-marko: @@ -2187,109 +4430,130 @@ packages: optional: true prettier-plugin-sort-imports: optional: true - prettier-plugin-style-order: - optional: true prettier-plugin-svelte: optional: true - prettier@3.4.2: - resolution: {integrity: sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==} + prettier@3.8.3: + resolution: {integrity: sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==} engines: {node: '>=14'} hasBin: true + pretty-ms@9.3.0: + resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==} + engines: {node: '>=18'} + process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + process-warning@5.0.0: + resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} + + promise-toolbox@0.21.0: + resolution: {integrity: sha512-NV8aTmpwrZv+Iys54sSFOBx3tuVaOBvvrft5PNppnxy9xpU/akHbaWIril22AB22zaPgrgwKdD0KsrM0ptUtpg==} + engines: {node: '>=6'} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} - property-expr@2.0.5: - resolution: {integrity: sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA==} + proto-list@1.2.4: + resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} - proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} - punycode@2.3.0: - resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} + proxy-from-env@2.1.0: + resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} + engines: {node: '>=10'} + + publish-browser-extension@4.0.5: + resolution: {integrity: sha512-EePAn3VIHJS/jqCuvs1NgPgoecCT8+RsES76hbgYe2Ze1dyvB0tX60C1PCrV8Z8fv56mW3E59s9Gd/GwWiw7dw==} + engines: {node: '>=18.0.0'} + hasBin: true + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - qs@6.14.0: - resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} + pupa@3.3.0: + resolution: {integrity: sha512-LjgDO2zPtoXP2wJpDjZrGdojii1uqO0cnwKoIoUzkfS98HDmbeiGmYiXo3lXeFlq2xvne1QFQhwYXSUCLKtEuA==} + engines: {node: '>=12.20'} + + qified@0.9.1: + resolution: {integrity: sha512-n7mar4T0xQ+39dE2vGTAlbxUEpndwPANH0kDef1/MYsB8Bba9wshkybIRx74qgcvKQPEWErf9AqAdYjhzY2Ilg==} + engines: {node: '>=20'} + + qs@6.15.1: + resolution: {integrity: sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==} engines: {node: '>=0.6'} + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - react-dom@19.0.0: - resolution: {integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==} - peerDependencies: - react: ^19.0.0 - - react-fast-compare@2.0.4: - resolution: {integrity: sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==} - - react-flatpickr@3.10.13: - resolution: {integrity: sha512-4m+K1K8jhvRFI8J/AHmQfA5hLALzhebEtEK8mLevXjX24MV3u502crzBn+EGFIBOfNUtrL5PId9FsGwgtuz/og==} - peerDependencies: - react: '>=16, <=18' + quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} - react-intl@7.1.5: - resolution: {integrity: sha512-cVvsVdaOnZ85XBXU0Lc2PVGNhGlzl4UBV+aWAGe/zrV5Xr+CEW7izUsAp/fIuwvCsJl9R+aokppm+P7cdhnpUA==} - peerDependencies: - react: ^16.6.0 || 17 || 18 || 19 - typescript: '5' - peerDependenciesMeta: - typescript: - optional: true + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} - react-is@16.13.1: - resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} + engines: {node: '>= 0.10'} - react-refresh@0.14.2: - resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} - engines: {node: '>=0.10.0'} + rc9@3.0.1: + resolution: {integrity: sha512-gMDyleLWVE+i6Sgtc0QbbY6pEKqYs97NGi6isHQPqYlLemPoO8dxQ3uGi0f4NiP98c+jMW6cG1Kx9dDwfvqARQ==} - react-router-dom@7.1.5: - resolution: {integrity: sha512-/4f9+up0Qv92D3bB8iN5P1s3oHAepSGa9h5k6tpTFlixTTskJZwKGhJ6vRJ277tLD1zuaZTt95hyGWV1Z37csQ==} - engines: {node: '>=20.0.0'} - peerDependencies: - react: '>=18' - react-dom: '>=18' + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true - react-router@7.1.5: - resolution: {integrity: sha512-8BUF+hZEU4/z/JD201yK6S+UYhsf58bzYIDq2NS1iGpwxSXDu7F+DeGSkIXMFBuHZB21FSiCzEcUb18cQNdRkA==} - engines: {node: '>=20.0.0'} + react-day-picker@9.14.0: + resolution: {integrity: sha512-tBaoDWjPwe0M5pGrum4H0SR6Lyk+BO9oHnp9JbKpGKW2mlraNPgP9BMfsg5pWpwrssARmeqk7YBl2oXutZTaHA==} + engines: {node: '>=18'} peerDependencies: - react: '>=18' - react-dom: '>=18' - peerDependenciesMeta: - react-dom: - optional: true + react: '>=16.8.0' - react-select@5.10.0: - resolution: {integrity: sha512-k96gw+i6N3ExgDwPIg0lUPmexl1ygPe6u5BdQFNBhkpbwroIgCNXdubtIzHfThYXYYTubwOBafoMnn7ruEP1xA==} + react-dom@19.2.5: + resolution: {integrity: sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag==} peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^19.2.5 - react-tooltip@5.28.0: - resolution: {integrity: sha512-R5cO3JPPXk6FRbBHMO0rI9nkUG/JKfalBSQfZedZYzmqaZQgq7GLzF8vcCWx6IhUCKg0yPqJhXIzmIO5ff15xg==} + react-intl@10.1.2: + resolution: {integrity: sha512-53iYLo+Sl6Qw1+/7VJ2v7mB2A8XHYeVFRujmoo8qVvvym4/WL9COKCcXKUyCYBwKgZNghKrgyQILx7qbrsdZ/w==} peerDependencies: - react: '>=16.14.0' - react-dom: '>=16.14.0' + '@types/react': '19' + react: '19' - react-transition-group@4.4.5: - resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} - peerDependencies: - react: '>=16.6.0' - react-dom: '>=16.6.0' + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - react@19.0.0: - resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==} + react@19.2.5: + resolution: {integrity: sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==} engines: {node: '>=0.10.0'} - read-cache@1.0.0: - resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + read-package-up@11.0.0: + resolution: {integrity: sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==} + engines: {node: '>=18'} + + read-package-up@12.0.0: + resolution: {integrity: sha512-Q5hMVBYur/eQNWDdbF4/Wqqr9Bjvtrw2kjGxxBbKLbx8bVCL8gcArjTy8zDUuLGQicftpMuU0riQNcAsbtOVsw==} + engines: {node: '>=20'} + + read-pkg@10.1.0: + resolution: {integrity: sha512-I8g2lArQiP78ll51UeMZojewtYgIRCKCWqZEgOO8c/uefTI+XDXvCSXu3+YNUaTNvZzobrL5+SqHjBrByRRTdg==} + engines: {node: '>=20'} + + read-pkg@9.0.1: + resolution: {integrity: sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==} + engines: {node: '>=18'} readable-stream@2.3.8: resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} @@ -2298,49 +4562,96 @@ packages: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} - reflect.getprototypeof@1.0.10: - resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} - engines: {node: '>= 0.4'} + readdirp@5.0.0: + resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} + engines: {node: '>= 20.19.0'} - regenerator-runtime@0.14.0: - resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==} + real-require@0.2.0: + resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} + engines: {node: '>= 12.13.0'} - regexp.prototype.flags@1.5.2: - resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} + recast@0.23.11: + resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==} + engines: {node: '>= 4'} + + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} regexp.prototype.flags@1.5.4: resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} + registry-auth-token@5.1.1: + resolution: {integrity: sha512-P7B4+jq8DeD2nMsAcdfaqHbssgHtZ7Z5+++a5ask90fvmJ8p5je4mOa+wzu+DB4vQ5tdJV/xywY+UnVFeQLV5Q==} + engines: {node: '>=14'} + + registry-url@6.0.1: + resolution: {integrity: sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==} + engines: {node: '>=12'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + reselect@5.1.1: + resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} - resolve@1.22.8: - resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} - hasBin: true + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - resolve@2.0.0-next.5: - resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + resolve@2.0.0-next.6: + resolution: {integrity: sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==} + engines: {node: '>= 0.4'} hasBin: true - reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + restore-cursor@5.1.0: + resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} + engines: {node: '>=18'} + + rettime@0.11.7: + resolution: {integrity: sha512-DoAm1WjR1eH7z8sHPtvvUMIZh4/CSKkGCz6CxPqOrEAnOGtOuHSnSE9OC+razqxKuf4ub7pAYyl/vZV0vGs5tg==} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rollup@4.34.3: - resolution: {integrity: sha512-ORCtU0UBJyiAIn9m0llUXJXAswG/68pZptCrqxHG7//Z2DDzAUeyyY5hqf4XrsGlUxscMr9GkQ2QI7KTLqeyPw==} + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + + rolldown@1.0.0-rc.15: + resolution: {integrity: sha512-Ff31guA5zT6WjnGp0SXw76X6hzGRk/OQq2hE+1lcDe+lJdHSgnSX6nK3erbONHyCbpSj9a9E+uX/OvytZoWp2g==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + rollup@4.59.0: + resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + router@2.2.0: + resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} + engines: {node: '>= 18'} + + run-applescript@7.1.0: + resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} + engines: {node: '>=18'} + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - safe-array-concat@1.1.2: - resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} - engines: {node: '>=0.4'} - safe-array-concat@1.1.3: resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} engines: {node: '>=0.4'} @@ -2348,32 +4659,72 @@ packages: safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + safe-push-apply@1.0.0: resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} engines: {node: '>= 0.4'} - safe-regex-test@1.0.3: - resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} - engines: {node: '>= 0.4'} - safe-regex-test@1.1.0: resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} engines: {node: '>= 0.4'} - scheduler@0.25.0: - resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==} + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sax@1.6.0: + resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} + engines: {node: '>=11.0.0'} + + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + + scule@1.3.0: + resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} + + semantic-release@25.0.3: + resolution: {integrity: sha512-WRgl5GcypwramYX4HV+eQGzUbD7UUbljVmS+5G1uMwX/wLgYuJAxGeerXJDMO2xshng4+FXqCgyB5QfClV6WjA==} + engines: {node: ^22.14.0 || >= 24.10.0} + hasBin: true + + semver-regex@4.0.5: + resolution: {integrity: sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==} + engines: {node: '>=12'} semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.6.3: - resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} engines: {node: '>=10'} hasBin: true - set-cookie-parser@2.7.1: - resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} + send@1.2.1: + resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} + engines: {node: '>= 18'} + + seroval-plugins@1.5.2: + resolution: {integrity: sha512-qpY0Cl+fKYFn4GOf3cMiq6l72CpuVaawb6ILjubOQ+diJ54LfOWaSSPsaswN8DRPIPW4Yq+tE1k5aKd7ILyaFg==} + engines: {node: '>=10'} + peerDependencies: + seroval: ^1.0 + + seroval@1.5.2: + resolution: {integrity: sha512-xcRN39BdsnO9Tf+VzsE7b3JyTJASItIV1FVFewJKCFcW4s4haIKS3e6vj8PGB9qBwC7tnuOywQMdv5N4qkzi7Q==} + engines: {node: '>=10'} + + serve-static@2.2.1: + resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} + engines: {node: '>= 18'} + + set-cookie-parser@3.1.0: + resolution: {integrity: sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw==} set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} @@ -2387,11 +4738,22 @@ packages: resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} engines: {node: '>= 0.4'} + set-value@4.1.0: + resolution: {integrity: sha512-zTEg4HL0RwVrqcWs3ztF+x1vkxfm0lP+MQQFPiMJTKVceBwEV0A569Ou8l9IYQG8jOZdMVI1hGsc0tmeD2o/Lw==} + engines: {node: '>=11.0'} + setimmediate@1.0.5: resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} - sharp@0.33.5: - resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + shadcn@4.3.0: + resolution: {integrity: sha512-7vhnBh2LVLyxOd1ZQWwXv7OATCnQcxdqc8FbZdNigZriNOwDsHklQmPpvPt1jcrFK5mzMI+cyuAYv8WzERx2Og==} + hasBin: true + + sharp@0.34.5: + resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} shebang-command@2.0.0: @@ -2402,8 +4764,14 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - side-channel-list@1.0.0: - resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + shell-quote@1.7.3: + resolution: {integrity: sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==} + + shellwords@0.1.1: + resolution: {integrity: sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==} + + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} engines: {node: '>= 0.4'} side-channel-map@1.0.1: @@ -2418,108 +4786,285 @@ packages: resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} engines: {node: '>= 0.4'} + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - simple-swizzle@0.2.2: - resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + signale@1.4.0: + resolution: {integrity: sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==} + engines: {node: '>=6'} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + skin-tone@2.0.0: + resolution: {integrity: sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==} + engines: {node: '>=8'} + + slash@5.1.0: + resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} + engines: {node: '>=14.16'} + + slice-ansi@4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + + slice-ansi@7.1.2: + resolution: {integrity: sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==} + engines: {node: '>=18'} + + slice-ansi@8.0.0: + resolution: {integrity: sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==} + engines: {node: '>=20'} + + sonic-boom@4.2.1: + resolution: {integrity: sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==} + + sonner@2.0.7: + resolution: {integrity: sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==} + peerDependencies: + react: ^18.0.0 || ^19.0.0 || ^19.0.0-rc + react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-rc source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} - source-map@0.5.7: - resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} + spawn-error-forwarder@1.0.0: + resolution: {integrity: sha512-gRjMgK5uFjbCvdibeGJuy3I5OYz6VLoVdsOJdA6wV0WlfQVLFueoqMxwwYD9RODdgb6oUIvlRlsyFSiQkMKu0g==} - string.prototype.matchall@4.0.12: - resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} - engines: {node: '>= 0.4'} + spawn-sync@1.0.15: + resolution: {integrity: sha512-9DWBgrgYZzNghseho0JOuh+5fg9u6QWhAWa51QC7+U5rCheZ/j1DrEZnyE0RBBRqZ9uEXGPgSSM0nky6burpVw==} - string.prototype.repeat@1.0.0: - resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} - string.prototype.trim@1.2.10: - resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} - engines: {node: '>= 0.4'} + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} - string.prototype.trim@1.2.9: - resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} - engines: {node: '>= 0.4'} + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} - string.prototype.trimend@1.0.8: - resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} + spdx-license-ids@3.0.23: + resolution: {integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==} - string.prototype.trimend@1.0.9: - resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} - engines: {node: '>= 0.4'} + split2@1.0.0: + resolution: {integrity: sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg==} - string.prototype.trimstart@1.0.8: - resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} - engines: {node: '>= 0.4'} + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} - string_decoder@1.1.1: + split@1.0.1: + resolution: {integrity: sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + stdin-discarder@0.2.2: + resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} + engines: {node: '>=18'} + + stop-iteration-iterator@1.1.0: + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} + engines: {node: '>= 0.4'} + + stream-combiner2@1.1.1: + resolution: {integrity: sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==} + + strict-event-emitter@0.5.1: + resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + + string-width@8.2.0: + resolution: {integrity: sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==} + engines: {node: '>=20'} + + string.prototype.matchall@4.0.12: + resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} + engines: {node: '>= 0.4'} + + string.prototype.repeat@1.0.0: + resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} + + string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + string_decoder@1.1.1: resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + stringify-object@5.0.0: + resolution: {integrity: sha512-zaJYxz2FtcMb4f+g60KsRNFOpVMUyuJgA51Zi5Z1DOTC3S59+OQiVOzE9GZt0x72uBGWKsQIuBKeF9iusmKFsg==} + engines: {node: '>=14.16'} + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-bom@5.0.0: + resolution: {integrity: sha512-p+byADHF7SzEcVnLvc/r3uognM1hUhObuHXxJcgLCfD194XAkaLbjq3Wzb0N5G2tgIjH0dgT708Z51QxMeu60A==} + engines: {node: '>=12'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} engines: {node: '>=12'} + strip-final-newline@4.0.0: + resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} + engines: {node: '>=18'} + + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - stylis@4.2.0: - resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==} + strip-json-comments@5.0.2: + resolution: {integrity: sha512-4X2FR3UwhNUE9G49aIsJW5hRRR3GXGTBTZRMfv568O60ojM8HcWjV/VxAxCDW3SUND33O6ZY66ZuRcdkj73q2g==} + engines: {node: '>=14.16'} + + strip-literal@3.1.0: + resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} + + stubborn-fs@2.0.0: + resolution: {integrity: sha512-Y0AvSwDw8y+nlSNFXMm2g6L51rBGdAQT20J3YSOqxC53Lo3bjWRtr2BKcfYoAf352WYpsZSTURrA0tqhfgudPA==} + + stubborn-utils@1.0.2: + resolution: {integrity: sha512-zOh9jPYI+xrNOyisSelgym4tolKTJCQd5GBhK0+0xJvcYDcwlOoxF/rnFKQ2KRZknXSG9jWAp66fwP6AxN9STg==} + + stylelint-config-recommended@18.0.0: + resolution: {integrity: sha512-mxgT2XY6YZ3HWWe3Di8umG6aBmWmHTblTgu/f10rqFXnyWxjKWwNdjSWkgkwCtxIKnqjSJzvFmPT5yabVIRxZg==} + engines: {node: '>=20.19.0'} + peerDependencies: + stylelint: ^17.0.0 + + stylelint-config-standard@40.0.0: + resolution: {integrity: sha512-EznGJxOUhtWck2r6dJpbgAdPATIzvpLdK9+i5qPd4Lx70es66TkBPljSg4wN3Qnc6c4h2n+WbUrUynQ3fanjHw==} + engines: {node: '>=20.19.0'} + peerDependencies: + stylelint: ^17.0.0 + + stylelint-config-tailwindcss@1.0.1: + resolution: {integrity: sha512-IeIMivgaB1kxPBgllMzBqyv0g61IwFxxZKo/fDDelfZ/JtPPlSBT04VuOCslk6PIaq5GQvdRnHOP1K3HpxSkeg==} + peerDependencies: + stylelint: '>=13.13.1' + tailwindcss: '>=2.2.16' - sucrase@3.35.0: - resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} - engines: {node: '>=16 || 14 >=14.17'} + stylelint@17.8.0: + resolution: {integrity: sha512-oHkld9T60LDSaUQ4CSVc+tlt9eUoDlxhaGWShsUCKyIL14boZfmK5bSphZqx64aiC5tCqX+BsQMTMoSz8D1zIg==} + engines: {node: '>=20.19.0'} hasBin: true + super-regex@1.1.0: + resolution: {integrity: sha512-WHkws2ZflZe41zj6AolvvmaTrWds/VuyeYr9iPVv/oQeaIoVxMKaushfFWpOGDT+GuBrM/sVqF8KUCYQlSSTdQ==} + engines: {node: '>=18'} + + supports-color@10.2.2: + resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} + engines: {node: '>=18'} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} + supports-hyperlinks@3.2.0: + resolution: {integrity: sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==} + engines: {node: '>=14.18'} + + supports-hyperlinks@4.4.0: + resolution: {integrity: sha512-UKbpT93hN5Nr9go5UY7bopIB9YQlMz9nm/ct4IXt/irb5YRkn9WaqrOBJGZ5Pwvsd5FQzSVeYlGdXoCAPQZrPg==} + engines: {node: '>=20'} + supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - tailwind-merge@2.6.0: - resolution: {integrity: sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==} + svg-tags@1.0.0: + resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} - tailwindcss-animate@1.0.7: - resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==} - peerDependencies: - tailwindcss: '>=3.0.0 || insiders' + synckit@0.11.12: + resolution: {integrity: sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==} + engines: {node: ^14.18.0 || >=16.0.0} - tailwindcss-shadow-fill@1.0.1: - resolution: {integrity: sha512-GvPU6IEXFprcvz/qz7SbAdlciWHg5CFg427nmrCPN1BYaDxTKxcxmFy/vh35i2/4RW3AHIRBp/h6VADMpYryww==} - peerDependencies: - tailwindcss: '>=2.0.0' + table@6.9.0: + resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} + engines: {node: '>=10.0.0'} + + tagged-tag@1.0.0: + resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} + engines: {node: '>=20'} - tailwindcss-text-fill@0.2.0: - resolution: {integrity: sha512-3lo6a/9jXSx4+24onFv7xnHO/1DZCk6qM+LoCsEUxn79sAeoc/ts74LSH0vRhLvWe4Yn+YglFfT+lxDv6wn2sQ==} + tailwind-api-utils@1.0.3: + resolution: {integrity: sha512-KpzUHkH1ug1sq4394SLJX38ZtpeTiqQ1RVyFTTSY2XuHsNSTWUkRo108KmyyrMWdDbQrLYkSHaNKj/a3bmA4sQ==} peerDependencies: - tailwindcss: '>=2.0.0' + tailwindcss: ^3.3.0 || ^4.0.0 || ^4.0.0-beta - tailwindcss@3.4.17: - resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==} - engines: {node: '>=14.0.0'} - hasBin: true + tailwind-merge@3.5.0: + resolution: {integrity: sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==} + + tailwindcss@4.2.2: + resolution: {integrity: sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==} + + tapable@2.3.2: + resolution: {integrity: sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==} + engines: {node: '>=6'} + + temp-dir@3.0.0: + resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==} + engines: {node: '>=14.16'} + + tempy@3.2.0: + resolution: {integrity: sha512-d79HhZya5Djd7am0q+W4RTsSU+D/aJzM+4Y4AGJGuGlgM2L6sx5ZvOYTmZjqPhrDrV6xJTtRSm1JCLj6V6LHLQ==} + engines: {node: '>=14.16'} thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} @@ -2528,163 +5073,299 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - tiny-case@1.0.3: - resolution: {integrity: sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==} + thread-stream@3.1.0: + resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} + + through2@2.0.5: + resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} + + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + + time-span@5.1.0: + resolution: {integrity: sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==} + engines: {node: '>=12'} + + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + + tinyexec@1.1.1: + resolution: {integrity: sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg==} + engines: {node: '>=18'} + + tinyglobby@0.2.16: + resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} + engines: {node: '>=12.0.0'} + + tldts-core@7.0.28: + resolution: {integrity: sha512-7W5Efjhsc3chVdFhqtaU0KtK32J37Zcr9RKtID54nG+tIpcY79CQK/veYPODxtD/LJ4Lue66jvrQzIX2Z2/pUQ==} + + tldts@7.0.28: + resolution: {integrity: sha512-+Zg3vWhRUv8B1maGSTFdev9mjoo8Etn2Ayfs4cnjlD3CsGkxXX4QyW3j2WJ0wdjYcYmy7Lx2RDsZMhgCWafKIw==} + hasBin: true - tiny-warning@1.0.3: - resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==} + tmp@0.2.5: + resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} + engines: {node: '>=14.14'} to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} - toposort@2.0.2: - resolution: {integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==} + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + tough-cookie@6.0.1: + resolution: {integrity: sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==} + engines: {node: '>=16'} + + traverse@0.6.8: + resolution: {integrity: sha512-aXJDbk6SnumuaZSANd21XAo15ucCDE38H4fkqiGsc3MhCK+wOlZvLP9cB/TvpHT0mOyWgC4Z8EwRlzqYSUzdsA==} + engines: {node: '>= 0.4'} - ts-api-utils@2.0.1: - resolution: {integrity: sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==} + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} engines: {node: '>=18.12'} peerDependencies: typescript: '>=4.8.4' - ts-interface-checker@0.1.13: - resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + ts-morph@26.0.0: + resolution: {integrity: sha512-ztMO++owQnz8c/gIENcM9XfCEzgoGphTv+nKpYNM1bgsdOVC/jRZuEBf6N+mLLDNg68Kl+GgUZfOySaRiG1/Ug==} + + tsconfig-paths@4.2.0: + resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} + engines: {node: '>=6'} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tsx@4.21.0: + resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} + engines: {node: '>=18.0.0'} + hasBin: true - tslib@2.5.3: - resolution: {integrity: sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==} + tunnel@0.0.6: + resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} + engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} - turbo-stream@2.4.0: - resolution: {integrity: sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==} + tw-animate-css@1.4.0: + resolution: {integrity: sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==} type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} + type-fest@1.4.0: + resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} + engines: {node: '>=10'} + type-fest@2.19.0: resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} engines: {node: '>=12.20'} - typed-array-buffer@1.0.2: - resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} - engines: {node: '>= 0.4'} + type-fest@3.13.1: + resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==} + engines: {node: '>=14.16'} + + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + + type-fest@5.6.0: + resolution: {integrity: sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA==} + engines: {node: '>=20'} + + type-is@2.0.1: + resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} + engines: {node: '>= 0.6'} typed-array-buffer@1.0.3: resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} engines: {node: '>= 0.4'} - typed-array-byte-length@1.0.1: - resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} - engines: {node: '>= 0.4'} - typed-array-byte-length@1.0.3: resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} engines: {node: '>= 0.4'} - typed-array-byte-offset@1.0.2: - resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} - engines: {node: '>= 0.4'} - typed-array-byte-offset@1.0.4: resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} engines: {node: '>= 0.4'} - typed-array-length@1.0.6: - resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} - engines: {node: '>= 0.4'} - typed-array-length@1.0.7: resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} - typescript-eslint@8.23.0: - resolution: {integrity: sha512-/LBRo3HrXr5LxmrdYSOCvoAMm7p2jNizNfbIpCgvG4HMsnoprRUOce/+8VJ9BDYWW68rqIENE/haVLWPeFZBVQ==} + typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + + typescript-eslint@8.58.2: + resolution: {integrity: sha512-V8iSng9mRbdZjl54VJ9NKr6ZB+dW0J3TzRXRGcSbLIej9jV86ZRtlYeTKDR/QLxXykocJ5icNzbsl2+5TzIvcQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.8.0' + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' - typescript@5.7.3: - resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} + typescript@6.0.3: + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} engines: {node: '>=14.17'} hasBin: true - unbox-primitive@1.0.2: - resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + ufo@1.6.3: + resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} + + uglify-js@3.19.3: + resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} + engines: {node: '>=0.8.0'} + hasBin: true + + uhyphen@0.2.0: + resolution: {integrity: sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA==} unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} - undici-types@6.20.0: - resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + + undici@6.25.0: + resolution: {integrity: sha512-ZgpWDC5gmNiuY9CnLVXEH8rl50xhRCuLNA97fAUnKi8RRuV4E6KG31pDTsLVUKnohJE0I3XDrTeEydAXRw47xg==} + engines: {node: '>=18.17'} + + undici@7.25.0: + resolution: {integrity: sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==} + engines: {node: '>=20.18.1'} + + unicode-emoji-modifier-base@1.0.0: + resolution: {integrity: sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==} + engines: {node: '>=4'} + + unicorn-magic@0.1.0: + resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} + engines: {node: '>=18'} + + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + + unicorn-magic@0.4.0: + resolution: {integrity: sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==} + engines: {node: '>=20'} + + unimport@6.1.0: + resolution: {integrity: sha512-ocgNKyiqj7Hw7oHt7A7D3za3fq28eShe1EloL6hsoQgn7CF51Y4CqFT9ISG3rEy0JpA8CCz/sY5h5OovOn62VQ==} + engines: {node: '>=18.12.0'} + + unique-string@3.0.0: + resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==} + engines: {node: '>=12'} + + universal-user-agent@7.0.3: + resolution: {integrity: sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==} universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} - update-browserslist-db@1.1.0: - resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + unplugin-utils@0.3.1: + resolution: {integrity: sha512-5lWVjgi6vuHhJ526bI4nlCOmkCIF3nnfXkCMDeMJrtdvxTs6ZFCM8oNufGTsDbKv/tJ/xj8RpvXjRuPBZJuJog==} + engines: {node: '>=20.19.0'} - update-browserslist-db@1.1.1: - resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} + unplugin@2.3.11: + resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} + engines: {node: '>=18.12.0'} + + unplugin@3.0.0: + resolution: {integrity: sha512-0Mqk3AT2TZCXWKdcoaufeXNukv2mTrEZExeXlHIOZXdqYoHHr4n51pymnwV8x2BOVxwXbK2HLlI7usrqMpycdg==} + engines: {node: ^20.19.0 || >=22.12.0} + + until-async@3.0.2: + resolution: {integrity: sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw==} + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' + update-notifier@7.3.1: + resolution: {integrity: sha512-+dwUY4L35XFYEzE+OAL3sarJdUioVovq+8f7lcIJ7wnmnYQV5UD1Y/lcwaMSyaQ6Bj3JMj1XSTjZbNLHn/19yA==} + engines: {node: '>=18'} + uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - use-isomorphic-layout-effect@1.2.0: - resolution: {integrity: sha512-q6ayo8DWoPZT0VdG4u3D3uxcgONP3Mevx2i2b0434cwWBoL+aelL1DzkXI6w3PhTZzUeR2kaVlZn70iCiseP6w==} + url-join@5.0.0: + resolution: {integrity: sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + use-sync-external-store@1.6.0: + resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} peerDependencies: - '@types/react': '*' react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@types/react': - optional: true + + usehooks-ts@3.1.1: + resolution: {integrity: sha512-I4diPp9Cq6ieSUH2wu+fDAVQO43xwtulo+fKEidHUwZPnYImbtkTjzIJYcDcJqxgmX31GVqNFURodvcgHcW0pA==} + engines: {node: '>=16.15.0'} + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^19 || ^19.0.0-rc util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - vite-plugin-static-copy@2.2.0: - resolution: {integrity: sha512-ytMrKdR9iWEYHbUxs6x53m+MRl4SJsOSoMu1U1+Pfg0DjPeMlsRVx3RR5jvoonineDquIue83Oq69JvNsFSU5w==} - engines: {node: ^18.0.0 || >=20.0.0} - peerDependencies: - vite: ^5.0.0 || ^6.0.0 + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true - vite-plugin-zip-pack@1.2.4: - resolution: {integrity: sha512-QgZEeiWayE2ZvMbkvcqWf94p/Z5YeNHZlkwXWIkkoISjePiWVXKRX2xCGmsURe9acGVdkobZ31dFJuCp3j1hMg==} - peerDependencies: - vite: '>=2.x' + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + + validate-npm-package-name@7.0.2: + resolution: {integrity: sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A==} + engines: {node: ^20.17.0 || >=22.9.0} - vite@6.1.0: - resolution: {integrity: sha512-RjjMipCKVoR4hVfPY6GQTgveinjNuyLw+qruksLDvA5ktI1150VmcMBKmQaEWJhg/j6Uaf6dNCNA0AfdzUb/hQ==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + vite-node@6.0.0: + resolution: {integrity: sha512-oj4PVrT+pDh6GYf5wfUXkcZyekYS8kKPfLPXVl8qe324Ec6l4K2DUKNadRbZ3LQl0qGcDz+PyOo7ZAh00Y+JjQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + vite@8.0.8: + resolution: {integrity: sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw==} + engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.1.0 + esbuild: ^0.27.0 || ^0.28.0 jiti: '>=1.21.0' - less: '*' - lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 terser: ^5.16.0 tsx: ^4.8.1 yaml: ^2.4.2 peerDependenciesMeta: '@types/node': optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true jiti: optional: true less: optional: true - lightningcss: - optional: true sass: optional: true sass-embedded: @@ -2700,8 +5381,29 @@ packages: yaml: optional: true - which-boxed-primitive@1.0.2: - resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + watchpack@2.4.4: + resolution: {integrity: sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==} + engines: {node: '>=10.13.0'} + + web-ext-run@0.2.4: + resolution: {integrity: sha512-rQicL7OwuqWdQWI33JkSXKcp7cuv1mJG8u3jRQwx/8aDsmhbTHs9ZRmNYOL+LX0wX8edIEQX8jj4bB60GoXtKA==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + + web-worker@1.5.0: + resolution: {integrity: sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw==} + + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + + when-exit@2.1.5: + resolution: {integrity: sha512-VGkKJ564kzt6Ms1dbgPP/yuIoQCrsFAnRbptpC5wOEsDaNsbCB2bnfnaA8i/vRs5tjUSEOtIuvl9/MyVsvQZCg==} + + when@3.7.7: + resolution: {integrity: sha512-9lFZp/KHoqH6bPKjbWqa+3Dg/K/r2v0X/3/G2x4DBGchVS2QX2VXL3cZV994WQVnTM1/PD71Az25nAzryEUugw==} which-boxed-primitive@1.1.1: resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} @@ -2715,539 +5417,879 @@ packages: resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} engines: {node: '>= 0.4'} - which-typed-array@1.1.15: - resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + which-typed-array@1.1.20: + resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} engines: {node: '>= 0.4'} - which-typed-array@1.1.18: - resolution: {integrity: sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==} - engines: {node: '>= 0.4'} + which@1.2.4: + resolution: {integrity: sha512-zDRAqDSBudazdfM9zpiI30Fu9ve47htYXcGi3ln0wfKu2a7SmrT6F3VDoYONu//48V8Vz4TdCRNPjtvyRO3yBA==} + hasBin: true + + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} hasBin: true + which@4.0.0: + resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==} + engines: {node: ^16.13.0 || >=18.0.0} + hasBin: true + + widest-line@5.0.0: + resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==} + engines: {node: '>=18'} + + winreg@0.0.12: + resolution: {integrity: sha512-typ/+JRmi7RqP1NanzFULK36vczznSNN8kWVA9vIqXyv8GhghUlwhGp1Xj3Nms1FsPcNnsQrJOR10N58/nQ9hQ==} + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + + wrap-ansi@10.0.0: + resolution: {integrity: sha512-SGcvg80f0wUy2/fXES19feHMz8E0JoXv2uNgHOu4Dgi2OrCy1lqwFYEJz1BLbDI0exjPMe/ZdzZ/YpGECBG/aQ==} + engines: {node: '>=20'} + wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + wrap-ansi@9.0.2: + resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} + engines: {node: '>=18'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + write-file-atomic@7.0.1: + resolution: {integrity: sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg==} + engines: {node: ^20.17.0 || >=22.9.0} + + wsl-utils@0.3.1: + resolution: {integrity: sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==} + engines: {node: '>=20'} + + wxt@0.20.25: + resolution: {integrity: sha512-ca+8Yt0Auzn9tX0ZW2Kzocb9yM8F/RoOjcYQ0fHkwcSc7/IUkqV2+1JUNn1SMSNAS4Gr3YQHAn/pi3q+jIGRqw==} + engines: {bun: '>=1.2.0', node: '>=20.12.0'} + hasBin: true + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + eslint: + optional: true + + xdg-basedir@5.1.0: + resolution: {integrity: sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==} engines: {node: '>=12'} + xml2js@0.6.2: + resolution: {integrity: sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==} + engines: {node: '>=4.0.0'} + + xmlbuilder@11.0.1: + resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} + engines: {node: '>=4.0'} + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yaml@1.10.2: - resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} - engines: {node: '>= 6'} - - yaml@2.6.1: - resolution: {integrity: sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==} + yaml@2.7.1: + resolution: {integrity: sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==} engines: {node: '>= 14'} hasBin: true + yargs-parser@20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs-parser@22.0.0: + resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + + yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yargs@18.0.0: + resolution: {integrity: sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - yup@1.6.1: - resolution: {integrity: sha512-JED8pB50qbA4FOkDol0bYF/p60qSEDQqBD0/qeIrUCG1KbPBIQ776fCUNb9ldbPcSTxA69g/47XTo4TqWiuXOA==} + yocto-spinner@1.1.0: + resolution: {integrity: sha512-/BY0AUXnS7IKO354uLLA2eRcWiqDifEbd6unXCsOxkFDAkhgUL3PH9X2bFoaU0YchnDXsF+iKleeTLJGckbXfA==} + engines: {node: '>=18.19'} + + yoctocolors@2.1.2: + resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} + engines: {node: '>=18'} + + zip-dir@2.0.0: + resolution: {integrity: sha512-uhlsJZWz26FLYXOD6WVuq+fIcZ3aBPGo/cFdiLlv3KNwpa52IF3ISV8fLhQLiqVu5No3VhlqlgthN6gehil1Dg==} + + zod-to-json-schema@3.25.2: + resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==} + peerDependencies: + zod: ^3.25.28 || ^4 + + zod-validation-error@4.0.2: + resolution: {integrity: sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + + zod@4.3.6: + resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} snapshots: - '@aashutoshrathi/word-wrap@1.2.6': {} + '@1natsu/wait-element@4.2.0': + dependencies: + defu: 6.1.7 + many-keys-map: 3.0.3 + + '@actions/core@3.0.0': + dependencies: + '@actions/exec': 3.0.0 + '@actions/http-client': 4.0.0 + + '@actions/exec@3.0.0': + dependencies: + '@actions/io': 3.0.2 + + '@actions/http-client@4.0.0': + dependencies: + tunnel: 0.0.6 + undici: 6.25.0 - '@alloc/quick-lru@5.2.0': {} + '@actions/io@3.0.2': {} - '@ampproject/remapping@2.2.1': + '@aklinker1/rollup-plugin-visualizer@5.12.0(rollup@4.59.0)': dependencies: - '@jridgewell/gen-mapping': 0.3.5 - '@jridgewell/trace-mapping': 0.3.25 + open: 8.4.2 + picomatch: 2.3.2 + source-map: 0.7.6 + yargs: 17.7.2 + optionalDependencies: + rollup: 4.59.0 - '@babel/code-frame@7.26.2': + '@babel/code-frame@7.29.0': dependencies: - '@babel/helper-validator-identifier': 7.25.9 + '@babel/helper-validator-identifier': 7.28.5 js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.26.2': {} + '@babel/compat-data@7.29.0': {} - '@babel/core@7.26.0': + '@babel/core@7.29.0': dependencies: - '@ampproject/remapping': 2.2.1 - '@babel/code-frame': 7.26.2 - '@babel/generator': 7.26.2 - '@babel/helper-compilation-targets': 7.25.9 - '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) - '@babel/helpers': 7.26.0 - '@babel/parser': 7.26.2 - '@babel/template': 7.25.9 - '@babel/traverse': 7.25.9 - '@babel/types': 7.26.0 + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.29.2 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 - debug: 4.3.4 + debug: 4.4.3 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/generator@7.26.2': + '@babel/generator@7.29.1': dependencies: - '@babel/parser': 7.26.2 - '@babel/types': 7.26.0 - '@jridgewell/gen-mapping': 0.3.5 - '@jridgewell/trace-mapping': 0.3.25 - jsesc: 3.0.2 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 - '@babel/helper-compilation-targets@7.25.9': + '@babel/helper-annotate-as-pure@7.27.3': dependencies: - '@babel/compat-data': 7.26.2 - '@babel/helper-validator-option': 7.25.9 - browserslist: 4.24.2 + '@babel/types': 7.29.0 + + '@babel/helper-compilation-targets@7.28.6': + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.2 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-module-imports@7.25.9': + '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/traverse': 7.25.9 - '@babel/types': 7.26.0 + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.29.0 + semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.0)': + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-member-expression-to-functions@7.28.5': dependencies: - '@babel/core': 7.26.0 - '@babel/helper-module-imports': 7.25.9 - '@babel/helper-validator-identifier': 7.25.9 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/helper-plugin-utils@7.25.9': {} + '@babel/helper-module-imports@7.28.6': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color - '@babel/helper-string-parser@7.25.9': {} + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color - '@babel/helper-validator-identifier@7.25.9': {} + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.29.0 - '@babel/helper-validator-option@7.25.9': {} + '@babel/helper-plugin-utils@7.28.6': {} - '@babel/helpers@7.26.0': + '@babel/helper-replace-supers@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/template': 7.25.9 - '@babel/types': 7.26.0 + '@babel/core': 7.29.0 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color - '@babel/parser@7.26.2': + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': dependencies: - '@babel/types': 7.26.0 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.27.1': {} - '@babel/plugin-transform-react-jsx-self@7.25.9(@babel/core@7.26.0)': + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.29.2': dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 - '@babel/plugin-transform-react-jsx-source@7.25.9(@babel/core@7.26.0)': + '@babel/parser@7.29.2': dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/types': 7.29.0 - '@babel/runtime@7.24.0': + '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)': dependencies: - regenerator-runtime: 0.14.0 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/template@7.25.9': + '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/code-frame': 7.26.2 - '@babel/parser': 7.26.2 - '@babel/types': 7.26.0 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse@7.25.9': + '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/code-frame': 7.26.2 - '@babel/generator': 7.26.2 - '@babel/parser': 7.26.2 - '@babel/template': 7.25.9 - '@babel/types': 7.26.0 - debug: 4.3.4 - globals: 11.12.0 + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/types@7.26.0': - dependencies: - '@babel/helper-string-parser': 7.25.9 - '@babel/helper-validator-identifier': 7.25.9 - - '@emnapi/runtime@1.2.0': + '@babel/plugin-transform-typescript@7.28.6(@babel/core@7.29.0)': dependencies: - tslib: 2.5.3 - optional: true + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color - '@emotion/babel-plugin@11.11.0': + '@babel/preset-typescript@7.28.5(@babel/core@7.29.0)': dependencies: - '@babel/helper-module-imports': 7.25.9 - '@babel/runtime': 7.24.0 - '@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.9.0 - escape-string-regexp: 4.0.0 - find-root: 1.1.0 - source-map: 0.5.7 - stylis: 4.2.0 + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) transitivePeerDependencies: - supports-color - '@emotion/cache@11.11.0': - 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 + '@babel/runtime@7.28.2': {} - '@emotion/hash@0.9.1': {} + '@babel/runtime@7.29.2': {} - '@emotion/memoize@0.8.1': {} + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 - '@emotion/react@11.11.1(@types/react@19.0.8)(react@19.0.0)': + '@babel/traverse@7.29.0': dependencies: - '@babel/runtime': 7.24.0 - '@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(react@19.0.0) - '@emotion/utils': 1.2.1 - '@emotion/weak-memoize': 0.3.1 - hoist-non-react-statics: 3.3.2 - react: 19.0.0 - optionalDependencies: - '@types/react': 19.0.8 + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3 transitivePeerDependencies: - supports-color - '@emotion/serialize@1.1.2': + '@babel/types@7.29.0': dependencies: - '@emotion/hash': 0.9.1 - '@emotion/memoize': 0.8.1 - '@emotion/unitless': 0.8.1 - '@emotion/utils': 1.2.1 - csstype: 3.1.2 - - '@emotion/sheet@1.2.2': {} + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 - '@emotion/unitless@0.8.1': {} + '@base-ui/react@1.4.0(@date-fns/tz@1.4.1)(@types/react@19.2.14)(date-fns@4.1.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@babel/runtime': 7.29.2 + '@base-ui/utils': 0.2.7(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@date-fns/tz': 1.4.1 + '@floating-ui/react-dom': 2.1.8(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@floating-ui/utils': 0.2.11 + date-fns: 4.1.0 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + use-sync-external-store: 1.6.0(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + + '@base-ui/utils@0.2.7(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@babel/runtime': 7.29.2 + '@floating-ui/utils': 0.2.11 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + reselect: 5.1.1 + use-sync-external-store: 1.6.0(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + + '@cacheable/memory@2.0.8': + dependencies: + '@cacheable/utils': 2.4.1 + '@keyv/bigmap': 1.3.1(keyv@5.6.0) + hookified: 1.15.1 + keyv: 5.6.0 + + '@cacheable/utils@2.4.1': + dependencies: + hashery: 1.5.1 + keyv: 5.6.0 + + '@colors/colors@1.5.0': + optional: true + + '@csstools/css-calc@3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + dependencies: + '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) + '@csstools/css-tokenizer': 4.0.0 + + '@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0)': + dependencies: + '@csstools/css-tokenizer': 4.0.0 + + '@csstools/css-syntax-patches-for-csstree@1.1.3(css-tree@3.2.1)': + optionalDependencies: + css-tree: 3.2.1 + + '@csstools/css-tokenizer@4.0.0': {} + + '@csstools/media-query-list-parser@5.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + dependencies: + '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) + '@csstools/css-tokenizer': 4.0.0 + + '@csstools/selector-resolve-nested@4.0.0(postcss-selector-parser@7.1.1)': + dependencies: + postcss-selector-parser: 7.1.1 + + '@csstools/selector-specificity@6.0.0(postcss-selector-parser@7.1.1)': + dependencies: + postcss-selector-parser: 7.1.1 + + '@date-fns/tz@1.4.1': {} + + '@devicefarmer/adbkit-logcat@2.1.3': {} + + '@devicefarmer/adbkit-monkey@1.2.1': {} + + '@devicefarmer/adbkit@3.3.8': + dependencies: + '@devicefarmer/adbkit-logcat': 2.1.3 + '@devicefarmer/adbkit-monkey': 1.2.1 + bluebird: 3.7.2 + commander: 9.5.0 + debug: 4.3.7 + node-forge: 1.4.0 + split: 1.0.1 + transitivePeerDependencies: + - supports-color + + '@dotenvx/dotenvx@1.61.1': + dependencies: + commander: 11.1.0 + dotenv: 17.4.2 + eciesjs: 0.4.18 + execa: 5.1.1 + fdir: 6.5.0(picomatch@4.0.4) + ignore: 5.3.2 + object-treeify: 1.1.33 + picomatch: 4.0.4 + which: 4.0.0 + yocto-spinner: 1.1.0 + + '@ecies/ciphers@0.2.6(@noble/ciphers@1.3.0)': + dependencies: + '@noble/ciphers': 1.3.0 + + '@emnapi/core@1.9.2': + dependencies: + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.10.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.9.2': + dependencies: + tslib: 2.8.1 + optional: true - '@emotion/use-insertion-effect-with-fallbacks@1.0.1(react@19.0.0)': + '@emnapi/wasi-threads@1.2.1': dependencies: - react: 19.0.0 + tslib: 2.8.1 + optional: true - '@emotion/utils@1.2.1': {} + '@epic-web/invariant@1.0.0': {} - '@emotion/weak-memoize@0.3.1': {} + '@esbuild/aix-ppc64@0.27.7': + optional: true - '@esbuild/aix-ppc64@0.24.2': + '@esbuild/android-arm64@0.27.7': optional: true - '@esbuild/android-arm64@0.24.2': + '@esbuild/android-arm@0.27.7': optional: true - '@esbuild/android-arm@0.24.2': + '@esbuild/android-x64@0.27.7': optional: true - '@esbuild/android-x64@0.24.2': + '@esbuild/darwin-arm64@0.27.7': optional: true - '@esbuild/darwin-arm64@0.24.2': + '@esbuild/darwin-x64@0.27.7': optional: true - '@esbuild/darwin-x64@0.24.2': + '@esbuild/freebsd-arm64@0.27.7': optional: true - '@esbuild/freebsd-arm64@0.24.2': + '@esbuild/freebsd-x64@0.27.7': optional: true - '@esbuild/freebsd-x64@0.24.2': + '@esbuild/linux-arm64@0.27.7': optional: true - '@esbuild/linux-arm64@0.24.2': + '@esbuild/linux-arm@0.27.7': optional: true - '@esbuild/linux-arm@0.24.2': + '@esbuild/linux-ia32@0.27.7': optional: true - '@esbuild/linux-ia32@0.24.2': + '@esbuild/linux-loong64@0.27.7': optional: true - '@esbuild/linux-loong64@0.24.2': + '@esbuild/linux-mips64el@0.27.7': optional: true - '@esbuild/linux-mips64el@0.24.2': + '@esbuild/linux-ppc64@0.27.7': optional: true - '@esbuild/linux-ppc64@0.24.2': + '@esbuild/linux-riscv64@0.27.7': optional: true - '@esbuild/linux-riscv64@0.24.2': + '@esbuild/linux-s390x@0.27.7': optional: true - '@esbuild/linux-s390x@0.24.2': + '@esbuild/linux-x64@0.27.7': optional: true - '@esbuild/linux-x64@0.24.2': + '@esbuild/netbsd-arm64@0.27.7': optional: true - '@esbuild/netbsd-arm64@0.24.2': + '@esbuild/netbsd-x64@0.27.7': optional: true - '@esbuild/netbsd-x64@0.24.2': + '@esbuild/openbsd-arm64@0.27.7': optional: true - '@esbuild/openbsd-arm64@0.24.2': + '@esbuild/openbsd-x64@0.27.7': optional: true - '@esbuild/openbsd-x64@0.24.2': + '@esbuild/openharmony-arm64@0.27.7': optional: true - '@esbuild/sunos-x64@0.24.2': + '@esbuild/sunos-x64@0.27.7': optional: true - '@esbuild/win32-arm64@0.24.2': + '@esbuild/win32-arm64@0.27.7': optional: true - '@esbuild/win32-ia32@0.24.2': + '@esbuild/win32-ia32@0.27.7': optional: true - '@esbuild/win32-x64@0.24.2': + '@esbuild/win32-x64@0.27.7': optional: true - '@eslint-community/eslint-utils@4.4.0(eslint@9.19.0(jiti@1.21.6))': + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4(jiti@2.6.1))': dependencies: - eslint: 9.19.0(jiti@1.21.6) + eslint: 9.39.4(jiti@2.6.1) eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.12.1': {} + '@eslint-community/regexpp@4.12.2': {} - '@eslint/config-array@0.19.2': + '@eslint/config-array@0.21.2': dependencies: - '@eslint/object-schema': 2.1.6 - debug: 4.3.4 - minimatch: 3.1.2 + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 + minimatch: 3.1.5 transitivePeerDependencies: - supports-color - '@eslint/core@0.10.0': + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 + + '@eslint/core@0.17.0': dependencies: '@types/json-schema': 7.0.15 - '@eslint/eslintrc@3.2.0': + '@eslint/eslintrc@3.3.5': dependencies: - ajv: 6.12.6 - debug: 4.3.4 - espree: 10.3.0 + ajv: 6.14.0 + debug: 4.4.3 + espree: 10.4.0 globals: 14.0.0 - ignore: 5.3.1 - import-fresh: 3.3.0 - js-yaml: 4.1.0 - minimatch: 3.1.2 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + minimatch: 3.1.5 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color - '@eslint/js@9.19.0': {} + '@eslint/js@9.39.4': {} - '@eslint/object-schema@2.1.6': {} + '@eslint/object-schema@2.1.7': {} - '@eslint/plugin-kit@0.2.5': + '@eslint/plugin-kit@0.4.1': dependencies: - '@eslint/core': 0.10.0 + '@eslint/core': 0.17.0 levn: 0.4.1 - '@floating-ui/core@1.2.6': {} - - '@floating-ui/dom@1.6.3': + '@floating-ui/core@1.7.5': dependencies: - '@floating-ui/core': 1.2.6 - '@floating-ui/utils': 0.2.1 - - '@floating-ui/utils@0.2.1': {} + '@floating-ui/utils': 0.2.11 - '@formatjs/ecma402-abstract@2.3.2': + '@floating-ui/dom@1.7.6': dependencies: - '@formatjs/fast-memoize': 2.2.6 - '@formatjs/intl-localematcher': 0.5.10 - decimal.js: 10.4.3 - tslib: 2.5.3 + '@floating-ui/core': 1.7.5 + '@floating-ui/utils': 0.2.11 - '@formatjs/fast-memoize@2.2.6': + '@floating-ui/react-dom@2.1.8(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': dependencies: - tslib: 2.5.3 + '@floating-ui/dom': 1.7.6 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) - '@formatjs/icu-messageformat-parser@2.11.0': - dependencies: - '@formatjs/ecma402-abstract': 2.3.2 - '@formatjs/icu-skeleton-parser': 1.8.12 - tslib: 2.5.3 + '@floating-ui/utils@0.2.11': {} - '@formatjs/icu-skeleton-parser@1.8.12': - dependencies: - '@formatjs/ecma402-abstract': 2.3.2 - tslib: 2.5.3 + '@formatjs/cli@6.14.2': {} - '@formatjs/intl-localematcher@0.5.10': - dependencies: - tslib: 2.5.3 + '@formatjs/fast-memoize@3.1.2': {} - '@formatjs/intl@3.1.3(typescript@5.7.3)': + '@formatjs/icu-messageformat-parser@3.5.4': dependencies: - '@formatjs/ecma402-abstract': 2.3.2 - '@formatjs/fast-memoize': 2.2.6 - '@formatjs/icu-messageformat-parser': 2.11.0 - intl-messageformat: 10.7.14 - tslib: 2.5.3 - optionalDependencies: - typescript: 5.7.3 + '@formatjs/icu-skeleton-parser': 2.1.4 - '@fortawesome/fontawesome-common-types@6.7.2': {} - - '@fortawesome/fontawesome-svg-core@6.7.2': - dependencies: - '@fortawesome/fontawesome-common-types': 6.7.2 + '@formatjs/icu-skeleton-parser@2.1.4': {} - '@fortawesome/free-brands-svg-icons@6.7.2': + '@formatjs/intl@4.1.6': dependencies: - '@fortawesome/fontawesome-common-types': 6.7.2 + '@formatjs/fast-memoize': 3.1.2 + '@formatjs/icu-messageformat-parser': 3.5.4 + intl-messageformat: 11.2.1 - '@fortawesome/free-regular-svg-icons@6.7.2': + '@hono/node-server@1.19.14(hono@4.12.14)': dependencies: - '@fortawesome/fontawesome-common-types': 6.7.2 + hono: 4.12.14 - '@fortawesome/free-solid-svg-icons@6.7.2': + '@humanfs/core@0.19.2': dependencies: - '@fortawesome/fontawesome-common-types': 6.7.2 + '@humanfs/types': 0.15.0 - '@fortawesome/react-fontawesome@0.2.2(@fortawesome/fontawesome-svg-core@6.7.2)(react@19.0.0)': + '@humanfs/node@0.16.8': dependencies: - '@fortawesome/fontawesome-svg-core': 6.7.2 - prop-types: 15.8.1 - react: 19.0.0 - - '@humanfs/core@0.19.1': {} + '@humanfs/core': 0.19.2 + '@humanfs/types': 0.15.0 + '@humanwhocodes/retry': 0.4.3 - '@humanfs/node@0.16.6': - dependencies: - '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.3.1 + '@humanfs/types@0.15.0': {} '@humanwhocodes/module-importer@1.0.1': {} - '@humanwhocodes/retry@0.3.1': {} + '@humanwhocodes/retry@0.4.3': {} - '@humanwhocodes/retry@0.4.1': {} + '@img/colour@1.1.0': {} - '@img/sharp-darwin-arm64@0.33.5': + '@img/sharp-darwin-arm64@0.34.5': optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.0.4 + '@img/sharp-libvips-darwin-arm64': 1.2.4 optional: true - '@img/sharp-darwin-x64@0.33.5': + '@img/sharp-darwin-x64@0.34.5': optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.0.4 + '@img/sharp-libvips-darwin-x64': 1.2.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.2.4': optional: true - '@img/sharp-libvips-darwin-arm64@1.0.4': + '@img/sharp-libvips-linux-ppc64@1.2.4': optional: true - '@img/sharp-libvips-darwin-x64@1.0.4': + '@img/sharp-libvips-linux-riscv64@1.2.4': optional: true - '@img/sharp-libvips-linux-arm64@1.0.4': + '@img/sharp-libvips-linux-s390x@1.2.4': optional: true - '@img/sharp-libvips-linux-arm@1.0.5': + '@img/sharp-libvips-linux-x64@1.2.4': optional: true - '@img/sharp-libvips-linux-s390x@1.0.4': + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': optional: true - '@img/sharp-libvips-linux-x64@1.0.4': + '@img/sharp-libvips-linuxmusl-x64@1.2.4': optional: true - '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + '@img/sharp-linux-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.2.4 optional: true - '@img/sharp-libvips-linuxmusl-x64@1.0.4': + '@img/sharp-linux-arm@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.2.4 optional: true - '@img/sharp-linux-arm64@0.33.5': + '@img/sharp-linux-ppc64@0.34.5': optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.0.4 + '@img/sharp-libvips-linux-ppc64': 1.2.4 optional: true - '@img/sharp-linux-arm@0.33.5': + '@img/sharp-linux-riscv64@0.34.5': optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.0.5 + '@img/sharp-libvips-linux-riscv64': 1.2.4 optional: true - '@img/sharp-linux-s390x@0.33.5': + '@img/sharp-linux-s390x@0.34.5': optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.0.4 + '@img/sharp-libvips-linux-s390x': 1.2.4 optional: true - '@img/sharp-linux-x64@0.33.5': + '@img/sharp-linux-x64@0.34.5': optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.0.4 + '@img/sharp-libvips-linux-x64': 1.2.4 optional: true - '@img/sharp-linuxmusl-arm64@0.33.5': + '@img/sharp-linuxmusl-arm64@0.34.5': optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 optional: true - '@img/sharp-linuxmusl-x64@0.33.5': + '@img/sharp-linuxmusl-x64@0.34.5': optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 optional: true - '@img/sharp-wasm32@0.33.5': + '@img/sharp-wasm32@0.34.5': dependencies: - '@emnapi/runtime': 1.2.0 + '@emnapi/runtime': 1.10.0 + optional: true + + '@img/sharp-win32-arm64@0.34.5': optional: true - '@img/sharp-win32-ia32@0.33.5': + '@img/sharp-win32-ia32@0.34.5': optional: true - '@img/sharp-win32-x64@0.33.5': + '@img/sharp-win32-x64@0.34.5': optional: true - '@isaacs/cliui@8.0.2': + '@inquirer/ansi@2.0.5': {} + + '@inquirer/confirm@6.0.11(@types/node@24.12.2)': + dependencies: + '@inquirer/core': 11.1.8(@types/node@24.12.2) + '@inquirer/type': 4.0.5(@types/node@24.12.2) + optionalDependencies: + '@types/node': 24.12.2 + + '@inquirer/core@11.1.8(@types/node@24.12.2)': + dependencies: + '@inquirer/ansi': 2.0.5 + '@inquirer/figures': 2.0.5 + '@inquirer/type': 4.0.5(@types/node@24.12.2) + cli-width: 4.1.0 + fast-wrap-ansi: 0.2.0 + mute-stream: 3.0.0 + signal-exit: 4.1.0 + optionalDependencies: + '@types/node': 24.12.2 + + '@inquirer/figures@2.0.5': {} + + '@inquirer/type@4.0.5(@types/node@24.12.2)': + optionalDependencies: + '@types/node': 24.12.2 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/gen-mapping@0.3.5': + '@keyv/bigmap@1.3.1(keyv@5.6.0)': dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.25 + hashery: 1.5.1 + hookified: 1.15.1 + keyv: 5.6.0 - '@jridgewell/resolve-uri@3.1.0': {} + '@keyv/serialize@1.1.1': {} - '@jridgewell/set-array@1.2.1': {} + '@modelcontextprotocol/sdk@1.29.0(zod@3.25.76)': + dependencies: + '@hono/node-server': 1.19.14(hono@4.12.14) + ajv: 8.18.0 + ajv-formats: 3.0.1(ajv@8.18.0) + content-type: 1.0.5 + cors: 2.8.6 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + eventsource-parser: 3.0.7 + express: 5.2.1 + express-rate-limit: 8.3.2(express@5.2.1) + hono: 4.12.14 + jose: 6.2.2 + json-schema-typed: 8.0.2 + pkce-challenge: 5.0.1 + raw-body: 3.0.2 + zod: 3.25.76 + zod-to-json-schema: 3.25.2(zod@3.25.76) + transitivePeerDependencies: + - supports-color + + '@mswjs/interceptors@0.41.3': + dependencies: + '@open-draft/deferred-promise': 2.2.0 + '@open-draft/logger': 0.3.0 + '@open-draft/until': 2.1.0 + is-node-process: 1.2.0 + outvariant: 1.4.3 + strict-event-emitter: 0.5.1 + + '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)': + dependencies: + '@emnapi/core': 1.9.2 + '@emnapi/runtime': 1.9.2 + '@tybys/wasm-util': 0.10.1 + optional: true - '@jridgewell/sourcemap-codec@1.4.15': {} + '@noble/ciphers@1.3.0': {} - '@jridgewell/trace-mapping@0.3.25': + '@noble/curves@1.9.7': dependencies: - '@jridgewell/resolve-uri': 3.1.0 - '@jridgewell/sourcemap-codec': 1.4.15 + '@noble/hashes': 1.8.0 + + '@noble/hashes@1.8.0': {} '@nodelib/fs.scandir@2.1.5': dependencies: @@ -3259,1548 +6301,3182 @@ snapshots: '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.15.0 + fastq: 1.20.1 - '@pkgjs/parseargs@0.11.0': - optional: true + '@octokit/auth-token@6.0.0': {} + + '@octokit/core@7.0.6': + dependencies: + '@octokit/auth-token': 6.0.0 + '@octokit/graphql': 9.0.3 + '@octokit/request': 10.0.8 + '@octokit/request-error': 7.1.0 + '@octokit/types': 16.0.0 + before-after-hook: 4.0.0 + universal-user-agent: 7.0.3 + + '@octokit/endpoint@11.0.3': + dependencies: + '@octokit/types': 16.0.0 + universal-user-agent: 7.0.3 + + '@octokit/graphql@9.0.3': + dependencies: + '@octokit/request': 10.0.8 + '@octokit/types': 16.0.0 + universal-user-agent: 7.0.3 + + '@octokit/openapi-types@27.0.0': {} + + '@octokit/plugin-paginate-rest@14.0.0(@octokit/core@7.0.6)': + dependencies: + '@octokit/core': 7.0.6 + '@octokit/types': 16.0.0 + + '@octokit/plugin-retry@8.1.0(@octokit/core@7.0.6)': + dependencies: + '@octokit/core': 7.0.6 + '@octokit/request-error': 7.1.0 + '@octokit/types': 16.0.0 + bottleneck: 2.19.5 + + '@octokit/plugin-throttling@11.0.3(@octokit/core@7.0.6)': + dependencies: + '@octokit/core': 7.0.6 + '@octokit/types': 16.0.0 + bottleneck: 2.19.5 + + '@octokit/request-error@7.1.0': + dependencies: + '@octokit/types': 16.0.0 + + '@octokit/request@10.0.8': + dependencies: + '@octokit/endpoint': 11.0.3 + '@octokit/request-error': 7.1.0 + '@octokit/types': 16.0.0 + fast-content-type-parse: 3.0.0 + json-with-bigint: 3.5.8 + universal-user-agent: 7.0.3 + + '@octokit/types@16.0.0': + dependencies: + '@octokit/openapi-types': 27.0.0 + + '@open-draft/deferred-promise@2.2.0': {} + + '@open-draft/deferred-promise@3.0.0': {} + + '@open-draft/logger@0.3.0': + dependencies: + is-node-process: 1.2.0 + outvariant: 1.4.3 + + '@open-draft/until@2.1.0': {} + + '@oxc-project/types@0.124.0': {} + + '@pkgr/core@0.2.9': {} + + '@playwright/test@1.59.1': + dependencies: + playwright: 1.59.1 + + '@pnpm/config.env-replace@1.1.0': {} - '@playwright/test@1.50.1': + '@pnpm/network.ca-file@1.0.2': dependencies: - playwright: 1.50.1 + graceful-fs: 4.2.10 - '@rollup/rollup-android-arm-eabi@4.34.3': + '@pnpm/npm-conf@3.0.2': + dependencies: + '@pnpm/config.env-replace': 1.1.0 + '@pnpm/network.ca-file': 1.0.2 + config-chain: 1.1.13 + + '@rolldown/binding-android-arm64@1.0.0-rc.15': optional: true - '@rollup/rollup-android-arm64@4.34.3': + '@rolldown/binding-darwin-arm64@1.0.0-rc.15': optional: true - '@rollup/rollup-darwin-arm64@4.34.3': + '@rolldown/binding-darwin-x64@1.0.0-rc.15': optional: true - '@rollup/rollup-darwin-x64@4.34.3': + '@rolldown/binding-freebsd-x64@1.0.0-rc.15': optional: true - '@rollup/rollup-freebsd-arm64@4.34.3': + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15': optional: true - '@rollup/rollup-freebsd-x64@4.34.3': + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.34.3': + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.15': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.34.3': + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.15': optional: true - '@rollup/rollup-linux-arm64-gnu@4.34.3': + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.15': optional: true - '@rollup/rollup-linux-arm64-musl@4.34.3': + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.15': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.34.3': + '@rolldown/binding-linux-x64-musl@1.0.0-rc.15': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.34.3': + '@rolldown/binding-openharmony-arm64@1.0.0-rc.15': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.34.3': + '@rolldown/binding-wasm32-wasi@1.0.0-rc.15': + dependencies: + '@emnapi/core': 1.9.2 + '@emnapi/runtime': 1.9.2 + '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) optional: true - '@rollup/rollup-linux-s390x-gnu@4.34.3': + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15': optional: true - '@rollup/rollup-linux-x64-gnu@4.34.3': + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.15': optional: true - '@rollup/rollup-linux-x64-musl@4.34.3': + '@rolldown/plugin-babel@0.2.3(@babel/core@7.29.0)(@babel/runtime@7.29.2)(rolldown@1.0.0-rc.15)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.7.1))': + dependencies: + '@babel/core': 7.29.0 + picomatch: 4.0.4 + rolldown: 1.0.0-rc.15 + optionalDependencies: + '@babel/runtime': 7.29.2 + vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.7.1) + + '@rolldown/pluginutils@1.0.0-rc.15': {} + + '@rolldown/pluginutils@1.0.0-rc.7': {} + + '@rollup/rollup-android-arm-eabi@4.59.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.34.3': + '@rollup/rollup-android-arm64@4.59.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.34.3': + '@rollup/rollup-darwin-arm64@4.59.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.34.3': + '@rollup/rollup-darwin-x64@4.59.0': optional: true - '@tanstack/query-async-storage-persister@5.66.0': - dependencies: - '@tanstack/query-persist-client-core': 5.66.0 + '@rollup/rollup-freebsd-arm64@4.59.0': + optional: true - '@tanstack/query-core@5.66.0': {} + '@rollup/rollup-freebsd-x64@4.59.0': + optional: true - '@tanstack/query-devtools@5.65.0': {} + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + optional: true - '@tanstack/query-persist-client-core@5.66.0': - dependencies: - '@tanstack/query-core': 5.66.0 + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + optional: true - '@tanstack/react-query-devtools@5.66.0(@tanstack/react-query@5.66.0(react@19.0.0))(react@19.0.0)': - dependencies: - '@tanstack/query-devtools': 5.65.0 - '@tanstack/react-query': 5.66.0(react@19.0.0) - react: 19.0.0 + '@rollup/rollup-linux-arm64-gnu@4.59.0': + optional: true - '@tanstack/react-query-persist-client@5.66.0(@tanstack/react-query@5.66.0(react@19.0.0))(react@19.0.0)': - dependencies: - '@tanstack/query-persist-client-core': 5.66.0 - '@tanstack/react-query': 5.66.0(react@19.0.0) - react: 19.0.0 + '@rollup/rollup-linux-arm64-musl@4.59.0': + optional: true - '@tanstack/react-query@5.66.0(react@19.0.0)': - dependencies: - '@tanstack/query-core': 5.66.0 - react: 19.0.0 + '@rollup/rollup-linux-loong64-gnu@4.59.0': + optional: true - '@types/babel__core@7.20.5': - dependencies: - '@babel/parser': 7.26.2 - '@babel/types': 7.26.0 - '@types/babel__generator': 7.6.5 - '@types/babel__template': 7.4.2 - '@types/babel__traverse': 7.20.2 + '@rollup/rollup-linux-loong64-musl@4.59.0': + optional: true - '@types/babel__generator@7.6.5': - dependencies: - '@babel/types': 7.26.0 + '@rollup/rollup-linux-ppc64-gnu@4.59.0': + optional: true - '@types/babel__template@7.4.2': - dependencies: - '@babel/parser': 7.26.2 - '@babel/types': 7.26.0 + '@rollup/rollup-linux-ppc64-musl@4.59.0': + optional: true - '@types/babel__traverse@7.20.2': - dependencies: - '@babel/types': 7.26.0 + '@rollup/rollup-linux-riscv64-gnu@4.59.0': + optional: true - '@types/chrome@0.0.301': - dependencies: - '@types/filesystem': 0.0.32 - '@types/har-format': 1.2.10 + '@rollup/rollup-linux-riscv64-musl@4.59.0': + optional: true - '@types/cookie@0.6.0': {} + '@rollup/rollup-linux-s390x-gnu@4.59.0': + optional: true - '@types/estree@1.0.6': {} + '@rollup/rollup-linux-x64-gnu@4.59.0': + optional: true - '@types/filesystem@0.0.32': - dependencies: - '@types/filewriter': 0.0.29 + '@rollup/rollup-linux-x64-musl@4.59.0': + optional: true - '@types/filewriter@0.0.29': {} + '@rollup/rollup-openbsd-x64@4.59.0': + optional: true - '@types/har-format@1.2.10': {} + '@rollup/rollup-openharmony-arm64@4.59.0': + optional: true - '@types/hoist-non-react-statics@3.3.1': - dependencies: - '@types/react': 19.0.8 - hoist-non-react-statics: 3.3.2 + '@rollup/rollup-win32-arm64-msvc@4.59.0': + optional: true - '@types/json-schema@7.0.15': {} + '@rollup/rollup-win32-ia32-msvc@4.59.0': + optional: true - '@types/node@22.13.1': - dependencies: - undici-types: 6.20.0 + '@rollup/rollup-win32-x64-gnu@4.59.0': + optional: true - '@types/parse-json@4.0.0': {} + '@rollup/rollup-win32-x64-msvc@4.59.0': + optional: true - '@types/qs@6.9.18': {} + '@sec-ant/readable-stream@0.4.1': {} - '@types/react-dom@19.0.3(@types/react@19.0.8)': + '@semantic-release/changelog@6.0.3(semantic-release@25.0.3(typescript@6.0.3))': dependencies: - '@types/react': 19.0.8 + '@semantic-release/error': 3.0.0 + aggregate-error: 3.1.0 + fs-extra: 11.3.4 + lodash: 4.18.1 + semantic-release: 25.0.3(typescript@6.0.3) - '@types/react-flatpickr@3.8.11': + '@semantic-release/commit-analyzer@13.0.1(semantic-release@25.0.3(typescript@6.0.3))': dependencies: - '@types/react': 19.0.8 - flatpickr: 4.6.13 + conventional-changelog-angular: 8.3.1 + conventional-changelog-writer: 8.4.0 + conventional-commits-filter: 5.0.0 + conventional-commits-parser: 6.4.0 + debug: 4.4.3 + import-from-esm: 2.0.0 + lodash-es: 4.18.1 + micromatch: 4.0.8 + semantic-release: 25.0.3(typescript@6.0.3) + transitivePeerDependencies: + - supports-color - '@types/react-transition-group@4.4.6': - dependencies: - '@types/react': 19.0.8 + '@semantic-release/error@3.0.0': {} - '@types/react@19.0.8': - dependencies: - csstype: 3.1.2 + '@semantic-release/error@4.0.0': {} - '@typescript-eslint/eslint-plugin@8.23.0(@typescript-eslint/parser@8.23.0(eslint@9.19.0(jiti@1.21.6))(typescript@5.7.3))(eslint@9.19.0(jiti@1.21.6))(typescript@5.7.3)': + '@semantic-release/git@10.0.1(semantic-release@25.0.3(typescript@6.0.3))': dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.23.0(eslint@9.19.0(jiti@1.21.6))(typescript@5.7.3) - '@typescript-eslint/scope-manager': 8.23.0 - '@typescript-eslint/type-utils': 8.23.0(eslint@9.19.0(jiti@1.21.6))(typescript@5.7.3) - '@typescript-eslint/utils': 8.23.0(eslint@9.19.0(jiti@1.21.6))(typescript@5.7.3) - '@typescript-eslint/visitor-keys': 8.23.0 - eslint: 9.19.0(jiti@1.21.6) - graphemer: 1.4.0 - ignore: 5.3.1 - natural-compare: 1.4.0 - ts-api-utils: 2.0.1(typescript@5.7.3) - typescript: 5.7.3 + '@semantic-release/error': 3.0.0 + aggregate-error: 3.1.0 + debug: 4.4.3 + dir-glob: 3.0.1 + execa: 5.1.1 + lodash: 4.18.1 + micromatch: 4.0.8 + p-reduce: 2.1.0 + semantic-release: 25.0.3(typescript@6.0.3) transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.23.0(eslint@9.19.0(jiti@1.21.6))(typescript@5.7.3)': - dependencies: - '@typescript-eslint/scope-manager': 8.23.0 - '@typescript-eslint/types': 8.23.0 - '@typescript-eslint/typescript-estree': 8.23.0(typescript@5.7.3) - '@typescript-eslint/visitor-keys': 8.23.0 - debug: 4.3.4 - eslint: 9.19.0(jiti@1.21.6) - typescript: 5.7.3 + '@semantic-release/github@12.0.6(semantic-release@25.0.3(typescript@6.0.3))': + dependencies: + '@octokit/core': 7.0.6 + '@octokit/plugin-paginate-rest': 14.0.0(@octokit/core@7.0.6) + '@octokit/plugin-retry': 8.1.0(@octokit/core@7.0.6) + '@octokit/plugin-throttling': 11.0.3(@octokit/core@7.0.6) + '@semantic-release/error': 4.0.0 + aggregate-error: 5.0.0 + debug: 4.4.3 + dir-glob: 3.0.1 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + issue-parser: 7.0.1 + lodash-es: 4.18.1 + mime: 4.1.0 + p-filter: 4.1.0 + semantic-release: 25.0.3(typescript@6.0.3) + tinyglobby: 0.2.16 + undici: 7.25.0 + url-join: 5.0.0 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.23.0': - dependencies: - '@typescript-eslint/types': 8.23.0 - '@typescript-eslint/visitor-keys': 8.23.0 - - '@typescript-eslint/type-utils@8.23.0(eslint@9.19.0(jiti@1.21.6))(typescript@5.7.3)': - dependencies: - '@typescript-eslint/typescript-estree': 8.23.0(typescript@5.7.3) - '@typescript-eslint/utils': 8.23.0(eslint@9.19.0(jiti@1.21.6))(typescript@5.7.3) - debug: 4.3.4 - eslint: 9.19.0(jiti@1.21.6) - ts-api-utils: 2.0.1(typescript@5.7.3) - typescript: 5.7.3 + '@semantic-release/npm@13.1.5(semantic-release@25.0.3(typescript@6.0.3))': + dependencies: + '@actions/core': 3.0.0 + '@semantic-release/error': 4.0.0 + aggregate-error: 5.0.0 + env-ci: 11.2.0 + execa: 9.6.1 + fs-extra: 11.3.4 + lodash-es: 4.18.1 + nerf-dart: 1.0.0 + normalize-url: 9.0.0 + npm: 11.12.1 + rc: 1.2.8 + read-pkg: 10.1.0 + registry-auth-token: 5.1.1 + semantic-release: 25.0.3(typescript@6.0.3) + semver: 7.7.4 + tempy: 3.2.0 + + '@semantic-release/release-notes-generator@14.1.0(semantic-release@25.0.3(typescript@6.0.3))': + dependencies: + conventional-changelog-angular: 8.3.1 + conventional-changelog-writer: 8.4.0 + conventional-commits-filter: 5.0.0 + conventional-commits-parser: 6.4.0 + debug: 4.4.3 + get-stream: 7.0.1 + import-from-esm: 2.0.0 + into-stream: 7.0.0 + lodash-es: 4.18.1 + read-package-up: 11.0.0 + semantic-release: 25.0.3(typescript@6.0.3) transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.23.0': {} + '@simple-libs/stream-utils@1.2.0': {} - '@typescript-eslint/typescript-estree@8.23.0(typescript@5.7.3)': - dependencies: - '@typescript-eslint/types': 8.23.0 - '@typescript-eslint/visitor-keys': 8.23.0 - debug: 4.3.4 - fast-glob: 3.3.2 - is-glob: 4.0.3 - minimatch: 9.0.4 - semver: 7.6.3 - ts-api-utils: 2.0.1(typescript@5.7.3) - typescript: 5.7.3 - transitivePeerDependencies: - - supports-color + '@sindresorhus/is@4.6.0': {} - '@typescript-eslint/utils@8.23.0(eslint@9.19.0(jiti@1.21.6))(typescript@5.7.3)': - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.19.0(jiti@1.21.6)) - '@typescript-eslint/scope-manager': 8.23.0 - '@typescript-eslint/types': 8.23.0 - '@typescript-eslint/typescript-estree': 8.23.0(typescript@5.7.3) - eslint: 9.19.0(jiti@1.21.6) - typescript: 5.7.3 - transitivePeerDependencies: - - supports-color + '@sindresorhus/merge-streams@4.0.0': {} - '@typescript-eslint/visitor-keys@8.23.0': - dependencies: - '@typescript-eslint/types': 8.23.0 - eslint-visitor-keys: 4.2.0 + '@tabby_ai/hijri-converter@1.0.5': {} - '@vitejs/plugin-react@4.3.4(vite@6.1.0(@types/node@22.13.1)(jiti@1.21.6)(yaml@2.6.1))': + '@tailwindcss/node@4.2.2': dependencies: - '@babel/core': 7.26.0 - '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.0) - '@types/babel__core': 7.20.5 - react-refresh: 0.14.2 - vite: 6.1.0(@types/node@22.13.1)(jiti@1.21.6)(yaml@2.6.1) - transitivePeerDependencies: - - supports-color + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.20.1 + jiti: 2.6.1 + lightningcss: 1.32.0 + magic-string: 0.30.21 + source-map-js: 1.2.1 + tailwindcss: 4.2.2 - acorn-jsx@5.3.2(acorn@8.14.0): - dependencies: - acorn: 8.14.0 + '@tailwindcss/oxide-android-arm64@4.2.2': + optional: true - acorn@8.14.0: {} + '@tailwindcss/oxide-darwin-arm64@4.2.2': + optional: true - ajv@6.12.6: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 + '@tailwindcss/oxide-darwin-x64@4.2.2': + optional: true - ansi-regex@5.0.1: {} + '@tailwindcss/oxide-freebsd-x64@4.2.2': + optional: true - ansi-regex@6.1.0: {} + '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2': + optional: true - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 + '@tailwindcss/oxide-linux-arm64-gnu@4.2.2': + optional: true - ansi-styles@6.2.1: {} + '@tailwindcss/oxide-linux-arm64-musl@4.2.2': + optional: true - any-promise@1.3.0: {} + '@tailwindcss/oxide-linux-x64-gnu@4.2.2': + optional: true - anymatch@3.1.3: - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 + '@tailwindcss/oxide-linux-x64-musl@4.2.2': + optional: true - arg@5.0.2: {} + '@tailwindcss/oxide-wasm32-wasi@4.2.2': + optional: true - argparse@2.0.1: {} + '@tailwindcss/oxide-win32-arm64-msvc@4.2.2': + optional: true - array-buffer-byte-length@1.0.1: - dependencies: - call-bind: 1.0.7 - is-array-buffer: 3.0.4 + '@tailwindcss/oxide-win32-x64-msvc@4.2.2': + optional: true - array-buffer-byte-length@1.0.2: + '@tailwindcss/oxide@4.2.2': + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.2.2 + '@tailwindcss/oxide-darwin-arm64': 4.2.2 + '@tailwindcss/oxide-darwin-x64': 4.2.2 + '@tailwindcss/oxide-freebsd-x64': 4.2.2 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.2 + '@tailwindcss/oxide-linux-arm64-gnu': 4.2.2 + '@tailwindcss/oxide-linux-arm64-musl': 4.2.2 + '@tailwindcss/oxide-linux-x64-gnu': 4.2.2 + '@tailwindcss/oxide-linux-x64-musl': 4.2.2 + '@tailwindcss/oxide-wasm32-wasi': 4.2.2 + '@tailwindcss/oxide-win32-arm64-msvc': 4.2.2 + '@tailwindcss/oxide-win32-x64-msvc': 4.2.2 + + '@tailwindcss/vite@4.2.2(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.7.1))': + dependencies: + '@tailwindcss/node': 4.2.2 + '@tailwindcss/oxide': 4.2.2 + tailwindcss: 4.2.2 + vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.7.1) + + '@tanstack/devtools-event-client@0.4.3': {} + + '@tanstack/eslint-plugin-query@5.99.0(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3)': + dependencies: + '@typescript-eslint/utils': 8.58.2(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3) + eslint: 9.39.4(jiti@2.6.1) + optionalDependencies: + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@tanstack/eslint-plugin-router@1.161.6(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3)': dependencies: - call-bound: 1.0.3 - is-array-buffer: 3.0.5 + '@typescript-eslint/utils': 8.58.2(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3) + eslint: 9.39.4(jiti@2.6.1) + transitivePeerDependencies: + - supports-color + - typescript - array-includes@3.1.8: + '@tanstack/form-core@1.29.0': dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.23.3 - es-object-atoms: 1.0.0 - get-intrinsic: 1.2.7 - is-string: 1.0.7 + '@tanstack/devtools-event-client': 0.4.3 + '@tanstack/pacer-lite': 0.1.1 + '@tanstack/store': 0.9.3 - array.prototype.findlast@1.2.5: + '@tanstack/history@1.161.6': {} + + '@tanstack/pacer-lite@0.1.1': {} + + '@tanstack/query-async-storage-persister@5.99.0': dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.23.3 - es-errors: 1.3.0 - es-object-atoms: 1.0.0 - es-shim-unscopables: 1.0.2 + '@tanstack/query-core': 5.99.0 + '@tanstack/query-persist-client-core': 5.99.0 - array.prototype.flat@1.3.1: + '@tanstack/query-core@5.99.0': {} + + '@tanstack/query-devtools@5.99.0': {} + + '@tanstack/query-persist-client-core@5.99.0': dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.23.3 - es-shim-unscopables: 1.0.2 + '@tanstack/query-core': 5.99.0 - array.prototype.flatmap@1.3.3: + '@tanstack/react-form@1.29.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.23.9 - es-shim-unscopables: 1.0.2 + '@tanstack/form-core': 1.29.0 + '@tanstack/react-store': 0.9.3(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + react: 19.2.5 + transitivePeerDependencies: + - react-dom - array.prototype.tosorted@1.1.4: + '@tanstack/react-query-devtools@5.99.0(@tanstack/react-query@5.99.0(react@19.2.5))(react@19.2.5)': dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.23.3 - es-errors: 1.3.0 - es-shim-unscopables: 1.0.2 + '@tanstack/query-devtools': 5.99.0 + '@tanstack/react-query': 5.99.0(react@19.2.5) + react: 19.2.5 - arraybuffer.prototype.slice@1.0.3: + '@tanstack/react-query-persist-client@5.99.0(@tanstack/react-query@5.99.0(react@19.2.5))(react@19.2.5)': dependencies: - array-buffer-byte-length: 1.0.1 - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.23.3 - es-errors: 1.3.0 - get-intrinsic: 1.2.7 - is-array-buffer: 3.0.4 - is-shared-array-buffer: 1.0.3 + '@tanstack/query-persist-client-core': 5.99.0 + '@tanstack/react-query': 5.99.0(react@19.2.5) + react: 19.2.5 - arraybuffer.prototype.slice@1.0.4: + '@tanstack/react-query@5.99.0(react@19.2.5)': dependencies: - array-buffer-byte-length: 1.0.2 - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.23.9 - es-errors: 1.3.0 - get-intrinsic: 1.2.7 - is-array-buffer: 3.0.5 + '@tanstack/query-core': 5.99.0 + react: 19.2.5 - asynckit@0.4.0: {} + '@tanstack/react-router@1.168.22(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@tanstack/history': 1.161.6 + '@tanstack/react-store': 0.9.3(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@tanstack/router-core': 1.168.15 + isbot: 5.1.39 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) - autoprefixer@10.4.20(postcss@8.5.1): + '@tanstack/react-store@0.9.3(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': dependencies: - browserslist: 4.23.3 - caniuse-lite: 1.0.30001659 - fraction.js: 4.3.7 - normalize-range: 0.1.2 - picocolors: 1.0.1 - postcss: 8.5.1 - postcss-value-parser: 4.2.0 + '@tanstack/store': 0.9.3 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + use-sync-external-store: 1.6.0(react@19.2.5) - available-typed-arrays@1.0.7: + '@tanstack/router-core@1.168.15': dependencies: - possible-typed-array-names: 1.0.0 + '@tanstack/history': 1.161.6 + cookie-es: 3.1.1 + seroval: 1.5.2 + seroval-plugins: 1.5.2(seroval@1.5.2) - axios@1.7.9: + '@tanstack/router-generator@1.166.32': dependencies: - follow-redirects: 1.15.6 - form-data: 4.0.0 - proxy-from-env: 1.1.0 + '@babel/types': 7.29.0 + '@tanstack/router-core': 1.168.15 + '@tanstack/router-utils': 1.161.6 + '@tanstack/virtual-file-routes': 1.161.7 + magic-string: 0.30.21 + prettier: 3.8.3 + tsx: 4.21.0 + zod: 3.25.76 transitivePeerDependencies: - - debug + - supports-color - babel-plugin-macros@3.1.0: - dependencies: - '@babel/runtime': 7.24.0 - cosmiconfig: 7.1.0 - resolve: 1.22.8 + '@tanstack/router-plugin@1.167.22(@tanstack/react-router@1.168.22(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.7.1))': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@tanstack/router-core': 1.168.15 + '@tanstack/router-generator': 1.166.32 + '@tanstack/router-utils': 1.161.6 + '@tanstack/virtual-file-routes': 1.161.7 + chokidar: 3.6.0 + unplugin: 2.3.11 + zod: 3.25.76 + optionalDependencies: + '@tanstack/react-router': 1.168.22(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.7.1) + transitivePeerDependencies: + - supports-color - balanced-match@1.0.2: {} + '@tanstack/router-utils@1.161.6': + dependencies: + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + ansis: 4.2.0 + babel-dead-code-elimination: 1.0.12 + diff: 8.0.4 + pathe: 2.0.3 + tinyglobby: 0.2.16 + transitivePeerDependencies: + - supports-color - binary-extensions@2.2.0: {} + '@tanstack/store@0.9.3': {} - brace-expansion@1.1.11: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 + '@tanstack/virtual-file-routes@1.161.7': {} - brace-expansion@2.0.1: + '@ts-morph/common@0.27.0': dependencies: - balanced-match: 1.0.2 + fast-glob: 3.3.3 + minimatch: 10.2.5 + path-browserify: 1.0.1 - braces@3.0.3: + '@tybys/wasm-util@0.10.1': dependencies: - fill-range: 7.1.1 + tslib: 2.8.1 + optional: true - browserslist@4.23.3: + '@types/chrome@0.1.40': dependencies: - caniuse-lite: 1.0.30001659 - electron-to-chromium: 1.5.18 - node-releases: 2.0.18 - update-browserslist-db: 1.1.0(browserslist@4.23.3) + '@types/filesystem': 0.0.36 + '@types/har-format': 1.2.16 - browserslist@4.24.2: - dependencies: - caniuse-lite: 1.0.30001675 - electron-to-chromium: 1.5.49 - node-releases: 2.0.18 - update-browserslist-db: 1.1.1(browserslist@4.24.2) + '@types/estree@1.0.8': {} - call-bind-apply-helpers@1.0.1: + '@types/filesystem@0.0.36': dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 + '@types/filewriter': 0.0.33 - call-bind@1.0.7: - dependencies: - es-define-property: 1.0.1 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.2.7 - set-function-length: 1.2.2 + '@types/filewriter@0.0.33': {} - call-bind@1.0.8: - dependencies: - call-bind-apply-helpers: 1.0.1 - es-define-property: 1.0.1 - get-intrinsic: 1.2.7 - set-function-length: 1.2.2 + '@types/har-format@1.2.16': {} - call-bound@1.0.3: - dependencies: - call-bind-apply-helpers: 1.0.1 - get-intrinsic: 1.2.7 + '@types/json-schema@7.0.15': {} - callsites@3.1.0: {} + '@types/minimatch@3.0.5': {} - camelcase-css@2.0.1: {} + '@types/node@24.12.2': + dependencies: + undici-types: 7.16.0 - caniuse-lite@1.0.30001659: {} + '@types/normalize-package-data@2.4.4': {} - caniuse-lite@1.0.30001675: {} + '@types/qs@6.15.0': {} - chalk@4.1.2: + '@types/react-dom@19.2.3(@types/react@19.2.14)': dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 + '@types/react': 19.2.14 - chokidar@3.5.3: + '@types/react@19.2.14': dependencies: - anymatch: 3.1.3 - braces: 3.0.3 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 + csstype: 3.2.3 - chokidar@3.6.0: + '@types/set-cookie-parser@2.4.10': dependencies: - anymatch: 3.1.3 - braces: 3.0.3 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 + '@types/node': 24.12.2 - classnames@2.3.2: {} + '@types/statuses@2.0.6': {} - clsx@2.1.1: {} + '@types/validate-npm-package-name@4.0.2': {} - color-convert@2.0.1: + '@typescript-eslint/eslint-plugin@8.58.2(@typescript-eslint/parser@8.58.2(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3))(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3)': dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.58.2(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.58.2 + '@typescript-eslint/type-utils': 8.58.2(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3) + '@typescript-eslint/utils': 8.58.2(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.58.2 + eslint: 9.39.4(jiti@2.6.1) + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color - color-string@1.9.1: + '@typescript-eslint/parser@8.58.2(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3)': dependencies: - color-name: 1.1.4 - simple-swizzle: 0.2.2 + '@typescript-eslint/scope-manager': 8.58.2 + '@typescript-eslint/types': 8.58.2 + '@typescript-eslint/typescript-estree': 8.58.2(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.58.2 + debug: 4.4.3 + eslint: 9.39.4(jiti@2.6.1) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color - color@4.2.3: + '@typescript-eslint/project-service@8.58.2(typescript@6.0.3)': dependencies: - color-convert: 2.0.1 - color-string: 1.9.1 + '@typescript-eslint/tsconfig-utils': 8.58.2(typescript@6.0.3) + '@typescript-eslint/types': 8.58.2 + debug: 4.4.3 + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color - combined-stream@1.0.8: + '@typescript-eslint/scope-manager@8.58.2': dependencies: - delayed-stream: 1.0.0 - - commander@4.1.1: {} - - concat-map@0.0.1: {} - - convert-source-map@1.9.0: {} - - convert-source-map@2.0.0: {} + '@typescript-eslint/types': 8.58.2 + '@typescript-eslint/visitor-keys': 8.58.2 - cookie@1.0.2: {} - - core-util-is@1.0.3: {} + '@typescript-eslint/tsconfig-utils@8.58.2(typescript@6.0.3)': + dependencies: + typescript: 6.0.3 - cosmiconfig@7.1.0: + '@typescript-eslint/type-utils@8.58.2(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3)': dependencies: - '@types/parse-json': 4.0.0 - import-fresh: 3.3.0 - parse-json: 5.2.0 - path-type: 4.0.0 - yaml: 1.10.2 + '@typescript-eslint/types': 8.58.2 + '@typescript-eslint/typescript-estree': 8.58.2(typescript@6.0.3) + '@typescript-eslint/utils': 8.58.2(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3) + debug: 4.4.3 + eslint: 9.39.4(jiti@2.6.1) + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color - country-flag-icons@1.5.14: {} + '@typescript-eslint/types@8.58.2': {} - cross-env@7.0.3: + '@typescript-eslint/typescript-estree@8.58.2(typescript@6.0.3)': dependencies: - cross-spawn: 7.0.6 + '@typescript-eslint/project-service': 8.58.2(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.58.2(typescript@6.0.3) + '@typescript-eslint/types': 8.58.2 + '@typescript-eslint/visitor-keys': 8.58.2 + debug: 4.4.3 + minimatch: 10.2.5 + semver: 7.7.4 + tinyglobby: 0.2.16 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color - cross-spawn@7.0.6: + '@typescript-eslint/utils@8.58.2(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3)': dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) + '@typescript-eslint/scope-manager': 8.58.2 + '@typescript-eslint/types': 8.58.2 + '@typescript-eslint/typescript-estree': 8.58.2(typescript@6.0.3) + eslint: 9.39.4(jiti@2.6.1) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color - cssesc@3.0.0: {} + '@typescript-eslint/visitor-keys@8.58.2': + dependencies: + '@typescript-eslint/types': 8.58.2 + eslint-visitor-keys: 5.0.1 - csstype@3.1.2: {} + '@vitejs/plugin-react@6.0.1(@rolldown/plugin-babel@0.2.3(@babel/core@7.29.0)(@babel/runtime@7.29.2)(rolldown@1.0.0-rc.15)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.7.1)))(babel-plugin-react-compiler@1.0.0)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.7.1))': + dependencies: + '@rolldown/pluginutils': 1.0.0-rc.7 + vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.7.1) + optionalDependencies: + '@rolldown/plugin-babel': 0.2.3(@babel/core@7.29.0)(@babel/runtime@7.29.2)(rolldown@1.0.0-rc.15)(vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.7.1)) + babel-plugin-react-compiler: 1.0.0 - data-view-buffer@1.0.1: + '@webext-core/fake-browser@1.3.4': dependencies: - call-bind: 1.0.7 - es-errors: 1.3.0 - is-data-view: 1.0.1 + lodash.merge: 4.6.2 - data-view-buffer@1.0.2: + '@webext-core/isolated-element@1.1.5': dependencies: - call-bound: 1.0.3 - es-errors: 1.3.0 - is-data-view: 1.0.2 + is-potential-custom-element-name: 1.0.1 + + '@webext-core/match-patterns@1.0.3': {} - data-view-byte-length@1.0.1: + '@wxt-dev/browser@0.1.40': dependencies: - call-bind: 1.0.7 - es-errors: 1.3.0 - is-data-view: 1.0.1 + '@types/filesystem': 0.0.36 + '@types/har-format': 1.2.16 - data-view-byte-length@1.0.2: + '@wxt-dev/storage@1.2.8': dependencies: - call-bound: 1.0.3 - es-errors: 1.3.0 - is-data-view: 1.0.2 + '@wxt-dev/browser': 0.1.40 + async-mutex: 0.5.0 + dequal: 2.0.3 - data-view-byte-offset@1.0.0: + accepts@2.0.0: dependencies: - call-bind: 1.0.7 - es-errors: 1.3.0 - is-data-view: 1.0.1 + mime-types: 3.0.2 + negotiator: 1.0.0 - data-view-byte-offset@1.0.1: + acorn-jsx@5.3.2(acorn@8.16.0): dependencies: - call-bound: 1.0.3 - es-errors: 1.3.0 - is-data-view: 1.0.2 + acorn: 8.16.0 - date-fns@3.6.0: {} + acorn@8.16.0: {} - debug@4.3.4: - dependencies: - ms: 2.1.2 + adm-zip@0.5.17: {} - decimal.js@10.4.3: {} + agent-base@7.1.4: {} - deep-is@0.1.4: {} + aggregate-error@3.1.0: + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 - deepmerge@2.2.1: {} + aggregate-error@5.0.0: + dependencies: + clean-stack: 5.3.0 + indent-string: 5.0.0 - deepmerge@4.3.1: {} + ajv-formats@3.0.1(ajv@8.18.0): + optionalDependencies: + ajv: 8.18.0 - define-data-property@1.1.4: + ajv@6.14.0: dependencies: - es-define-property: 1.0.1 - es-errors: 1.3.0 - gopd: 1.2.0 + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 - define-properties@1.2.1: + ajv@8.18.0: dependencies: - define-data-property: 1.1.4 - has-property-descriptors: 1.0.2 - object-keys: 1.1.1 + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 - delayed-stream@1.0.0: {} + ansi-align@3.0.1: + dependencies: + string-width: 4.2.3 - detect-libc@2.0.3: {} + ansi-escapes@7.3.0: + dependencies: + environment: 1.1.0 - didyoumean@1.2.2: {} + ansi-regex@5.0.1: {} - dlv@1.1.3: {} + ansi-regex@6.2.2: {} - doctrine@2.1.0: + ansi-styles@3.2.1: dependencies: - esutils: 2.0.3 + color-convert: 1.9.3 - dom-helpers@5.2.1: + ansi-styles@4.3.0: dependencies: - '@babel/runtime': 7.24.0 - csstype: 3.1.2 - - dotenv@16.4.7: {} + color-convert: 2.0.1 - dunder-proto@1.0.1: - dependencies: - call-bind-apply-helpers: 1.0.1 - es-errors: 1.3.0 - gopd: 1.2.0 + ansi-styles@6.2.3: {} - eastasianwidth@0.2.0: {} + ansis@4.2.0: {} - electron-to-chromium@1.5.18: {} + any-promise@1.3.0: {} - electron-to-chromium@1.5.49: {} + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.2 - emoji-regex@8.0.0: {} + argparse@2.0.1: {} - emoji-regex@9.2.2: {} + argv-formatter@1.0.0: {} - error-ex@1.3.2: + array-buffer-byte-length@1.0.2: dependencies: - is-arrayish: 0.2.1 + call-bound: 1.0.4 + is-array-buffer: 3.0.5 - es-abstract@1.23.3: - 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.1 - 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.7 - get-symbol-description: 1.0.2 - globalthis: 1.0.4 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - has-proto: 1.0.3 - has-symbols: 1.1.0 - 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.4 - 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 + array-differ@4.0.0: {} + + array-ify@1.0.0: {} - es-abstract@1.23.9: + array-includes@3.1.9: dependencies: - array-buffer-byte-length: 1.0.2 - arraybuffer.prototype.slice: 1.0.4 - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - call-bound: 1.0.3 - data-view-buffer: 1.0.2 - data-view-byte-length: 1.0.2 - data-view-byte-offset: 1.0.1 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.0.0 - es-set-tostringtag: 2.1.0 - es-to-primitive: 1.3.0 - function.prototype.name: 1.1.8 - get-intrinsic: 1.2.7 - get-proto: 1.0.1 - get-symbol-description: 1.1.0 - globalthis: 1.0.4 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - has-proto: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - internal-slot: 1.1.0 - is-array-buffer: 3.0.5 - is-callable: 1.2.7 - is-data-view: 1.0.2 - is-regex: 1.2.1 - is-shared-array-buffer: 1.0.4 + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 is-string: 1.1.1 - is-typed-array: 1.1.15 - is-weakref: 1.1.1 math-intrinsics: 1.1.0 - object-inspect: 1.13.4 - object-keys: 1.1.1 - object.assign: 4.1.7 - own-keys: 1.0.1 - regexp.prototype.flags: 1.5.4 - safe-array-concat: 1.1.3 - safe-push-apply: 1.0.0 - safe-regex-test: 1.1.0 - set-proto: 1.0.0 - string.prototype.trim: 1.2.10 - string.prototype.trimend: 1.0.9 - string.prototype.trimstart: 1.0.8 - typed-array-buffer: 1.0.3 - typed-array-byte-length: 1.0.3 - typed-array-byte-offset: 1.0.4 - typed-array-length: 1.0.7 - unbox-primitive: 1.1.0 - which-typed-array: 1.1.18 - - es-define-property@1.0.1: {} - es-errors@1.3.0: {} + array-union@3.0.1: {} - es-iterator-helpers@1.2.1: + array.prototype.findlast@1.2.5: dependencies: - call-bind: 1.0.8 - call-bound: 1.0.3 + call-bind: 1.0.9 define-properties: 1.2.1 - es-abstract: 1.23.9 + es-abstract: 1.24.2 es-errors: 1.3.0 - es-set-tostringtag: 2.0.3 - function-bind: 1.1.2 - get-intrinsic: 1.2.7 - globalthis: 1.0.4 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - has-proto: 1.2.0 - has-symbols: 1.1.0 - internal-slot: 1.1.0 - iterator.prototype: 1.1.5 - safe-array-concat: 1.1.3 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 - es-object-atoms@1.0.0: + array.prototype.flat@1.3.3: dependencies: - es-errors: 1.3.0 + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-shim-unscopables: 1.1.0 - es-set-tostringtag@2.0.3: + array.prototype.flatmap@1.3.3: dependencies: - get-intrinsic: 1.2.7 - has-tostringtag: 1.0.2 - hasown: 2.0.2 + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-shim-unscopables: 1.1.0 - es-set-tostringtag@2.1.0: + array.prototype.tosorted@1.1.4: dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 es-errors: 1.3.0 - get-intrinsic: 1.2.7 - has-tostringtag: 1.0.2 - hasown: 2.0.2 + es-shim-unscopables: 1.1.0 - es-shim-unscopables@1.0.2: + arraybuffer.prototype.slice@1.0.4: dependencies: - hasown: 2.0.2 + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 - es-to-primitive@1.2.1: + ast-types@0.16.1: dependencies: - is-callable: 1.2.7 - is-date-object: 1.0.5 - is-symbol: 1.0.4 + tslib: 2.8.1 - es-to-primitive@1.3.0: + astral-regex@2.0.0: {} + + async-function@1.0.0: {} + + async-mutex@0.5.0: dependencies: - is-callable: 1.2.7 - is-date-object: 1.0.5 - is-symbol: 1.0.4 + tslib: 2.8.1 - esbuild@0.24.2: - optionalDependencies: - '@esbuild/aix-ppc64': 0.24.2 - '@esbuild/android-arm': 0.24.2 - '@esbuild/android-arm64': 0.24.2 - '@esbuild/android-x64': 0.24.2 - '@esbuild/darwin-arm64': 0.24.2 - '@esbuild/darwin-x64': 0.24.2 - '@esbuild/freebsd-arm64': 0.24.2 - '@esbuild/freebsd-x64': 0.24.2 - '@esbuild/linux-arm': 0.24.2 - '@esbuild/linux-arm64': 0.24.2 - '@esbuild/linux-ia32': 0.24.2 - '@esbuild/linux-loong64': 0.24.2 - '@esbuild/linux-mips64el': 0.24.2 - '@esbuild/linux-ppc64': 0.24.2 - '@esbuild/linux-riscv64': 0.24.2 - '@esbuild/linux-s390x': 0.24.2 - '@esbuild/linux-x64': 0.24.2 - '@esbuild/netbsd-arm64': 0.24.2 - '@esbuild/netbsd-x64': 0.24.2 - '@esbuild/openbsd-arm64': 0.24.2 - '@esbuild/openbsd-x64': 0.24.2 - '@esbuild/sunos-x64': 0.24.2 - '@esbuild/win32-arm64': 0.24.2 - '@esbuild/win32-ia32': 0.24.2 - '@esbuild/win32-x64': 0.24.2 + async@3.2.6: {} - escalade@3.2.0: {} + asynckit@0.4.0: {} - escape-string-regexp@4.0.0: {} + atomic-sleep@1.0.0: {} - eslint-config-prettier@10.0.1(eslint@9.19.0(jiti@1.21.6)): + atomically@2.1.1: dependencies: - eslint: 9.19.0(jiti@1.21.6) + stubborn-fs: 2.0.0 + when-exit: 2.1.5 - eslint-plugin-react-hooks@5.1.0(eslint@9.19.0(jiti@1.21.6)): + available-typed-arrays@1.0.7: dependencies: - eslint: 9.19.0(jiti@1.21.6) + possible-typed-array-names: 1.1.0 - eslint-plugin-react@7.37.4(eslint@9.19.0(jiti@1.21.6)): + axios@1.15.0: dependencies: - array-includes: 3.1.8 - array.prototype.findlast: 1.2.5 - array.prototype.flatmap: 1.3.3 - array.prototype.tosorted: 1.1.4 - doctrine: 2.1.0 - es-iterator-helpers: 1.2.1 - eslint: 9.19.0(jiti@1.21.6) - estraverse: 5.3.0 - hasown: 2.0.2 - jsx-ast-utils: 3.3.4 - minimatch: 3.1.2 - object.entries: 1.1.8 - object.fromentries: 2.0.8 - object.values: 1.2.1 - prop-types: 15.8.1 - resolve: 2.0.0-next.5 - semver: 6.3.1 + follow-redirects: 1.16.0 + form-data: 4.0.5 + proxy-from-env: 2.1.0 + transitivePeerDependencies: + - debug + + babel-dead-code-elimination@1.0.12: + dependencies: + '@babel/core': 7.29.0 + '@babel/parser': 7.29.2 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-react-compiler@1.0.0: + dependencies: + '@babel/types': 7.29.0 + + balanced-match@1.0.2: {} + + balanced-match@4.0.4: {} + + baseline-browser-mapping@2.10.19: {} + + before-after-hook@4.0.0: {} + + binary-extensions@2.3.0: {} + + bluebird@3.7.2: {} + + body-parser@2.2.2: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 4.4.3 + http-errors: 2.0.1 + iconv-lite: 0.7.2 + on-finished: 2.4.1 + qs: 6.15.1 + raw-body: 3.0.2 + type-is: 2.0.1 + transitivePeerDependencies: + - supports-color + + boolbase@1.0.0: {} + + bottleneck@2.19.5: {} + + boxen@8.0.1: + dependencies: + ansi-align: 3.0.1 + camelcase: 8.0.0 + chalk: 5.6.2 + cli-boxes: 3.0.0 + string-width: 7.2.0 + type-fest: 4.41.0 + widest-line: 5.0.0 + wrap-ansi: 9.0.2 + + brace-expansion@1.1.14: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@5.0.5: + dependencies: + balanced-match: 4.0.4 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.28.2: + dependencies: + baseline-browser-mapping: 2.10.19 + caniuse-lite: 1.0.30001788 + electron-to-chromium: 1.5.340 + node-releases: 2.0.37 + update-browserslist-db: 1.2.3(browserslist@4.28.2) + + buffer-equal-constant-time@1.0.1: {} + + buffer-from@1.1.2: {} + + bundle-name@4.1.0: + dependencies: + run-applescript: 7.1.0 + + bytes@3.1.2: {} + + c12@3.3.4(magicast@0.5.2): + dependencies: + chokidar: 5.0.0 + confbox: 0.2.4 + defu: 6.1.7 + dotenv: 17.4.2 + exsolve: 1.0.8 + giget: 3.2.0 + jiti: 2.6.1 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 2.1.0 + pkg-types: 2.3.0 + rc9: 3.0.1 + optionalDependencies: + magicast: 0.5.2 + + cac@6.7.14: {} + + cac@7.0.0: {} + + cacheable@2.3.4: + dependencies: + '@cacheable/memory': 2.0.8 + '@cacheable/utils': 2.4.1 + hookified: 1.15.1 + keyv: 5.6.0 + qified: 0.9.1 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.9: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + callsites@3.1.0: {} + + camelcase@8.0.0: {} + + caniuse-lite@1.0.30001788: {} + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@5.6.2: {} + + char-regex@1.0.2: {} + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@5.0.0: + dependencies: + readdirp: 5.0.0 + + chrome-launcher@1.2.0: + dependencies: + '@types/node': 24.12.2 + escape-string-regexp: 4.0.0 + is-wsl: 2.2.0 + lighthouse-logger: 2.0.2 + transitivePeerDependencies: + - supports-color + + ci-info@4.4.0: {} + + citty@0.2.2: {} + + class-variance-authority@0.7.1: + dependencies: + clsx: 2.1.1 + + clean-stack@2.2.0: {} + + clean-stack@5.3.0: + dependencies: + escape-string-regexp: 5.0.0 + + cli-boxes@3.0.0: {} + + cli-cursor@5.0.0: + dependencies: + restore-cursor: 5.1.0 + + cli-highlight@2.1.11: + dependencies: + chalk: 4.1.2 + highlight.js: 10.7.3 + mz: 2.7.0 + parse5: 5.1.1 + parse5-htmlparser2-tree-adapter: 6.0.1 + yargs: 16.2.0 + + cli-spinners@2.9.2: {} + + cli-table3@0.6.5: + dependencies: + string-width: 4.2.3 + optionalDependencies: + '@colors/colors': 1.5.0 + + cli-truncate@5.2.0: + dependencies: + slice-ansi: 8.0.0 + string-width: 8.2.0 + + cli-width@4.1.0: {} + + cliui@7.0.4: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + cliui@9.0.1: + dependencies: + string-width: 7.2.0 + strip-ansi: 7.2.0 + wrap-ansi: 9.0.2 + + clsx@2.1.1: {} + + code-block-writer@13.0.3: {} + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + colord@2.9.3: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + commander@11.1.0: {} + + commander@14.0.3: {} + + commander@2.9.0: + dependencies: + graceful-readlink: 1.0.1 + + commander@9.5.0: {} + + compare-func@2.0.0: + dependencies: + array-ify: 1.0.0 + dot-prop: 5.3.0 + + concat-map@0.0.1: {} + + concat-stream@1.6.2: + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 2.3.8 + typedarray: 0.0.6 + + confbox@0.1.8: {} + + confbox@0.2.4: {} + + config-chain@1.1.13: + dependencies: + ini: 1.3.8 + proto-list: 1.2.4 + + configstore@7.1.0: + dependencies: + atomically: 2.1.1 + dot-prop: 9.0.0 + graceful-fs: 4.2.11 + xdg-basedir: 5.1.0 + + consola@3.4.2: {} + + content-disposition@1.1.0: {} + + content-type@1.0.5: {} + + conventional-changelog-angular@8.3.1: + dependencies: + compare-func: 2.0.0 + + conventional-changelog-conventionalcommits@9.3.1: + dependencies: + compare-func: 2.0.0 + + conventional-changelog-writer@8.4.0: + dependencies: + '@simple-libs/stream-utils': 1.2.0 + conventional-commits-filter: 5.0.0 + handlebars: 4.7.9 + meow: 13.2.0 + semver: 7.7.4 + + conventional-commits-filter@5.0.0: {} + + conventional-commits-parser@6.4.0: + dependencies: + '@simple-libs/stream-utils': 1.2.0 + meow: 13.2.0 + + convert-hrtime@5.0.0: {} + + convert-source-map@2.0.0: {} + + cookie-es@3.1.1: {} + + cookie-signature@1.2.2: {} + + cookie@0.7.2: {} + + cookie@1.1.1: {} + + core-util-is@1.0.3: {} + + cors@2.8.6: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + cosmiconfig@9.0.1(typescript@6.0.3): + dependencies: + env-paths: 2.2.1 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + parse-json: 5.2.0 + optionalDependencies: + typescript: 6.0.3 + + country-flag-icons@1.6.16: {} + + cross-env@10.1.0: + dependencies: + '@epic-web/invariant': 1.0.0 + cross-spawn: 7.0.6 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + crypto-random-string@4.0.0: + dependencies: + type-fest: 1.4.0 + + css-functions-list@3.3.3: {} + + css-select@5.2.2: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-tree@3.2.1: + dependencies: + mdn-data: 2.27.1 + source-map-js: 1.2.1 + + css-what@6.2.2: {} + + cssesc@3.0.0: {} + + cssom@0.5.0: {} + + csstype@3.2.3: {} + + data-uri-to-buffer@4.0.1: {} + + data-view-buffer@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-offset@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + date-fns-jalali@4.1.0-0: {} + + date-fns@4.1.0: {} + + debounce@1.2.1: {} + + debug@4.3.7: + dependencies: + ms: 2.1.3 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + dedent@1.7.2: {} + + deep-extend@0.6.0: {} + + deep-is@0.1.4: {} + + deepmerge@4.3.1: {} + + default-browser-id@5.0.1: {} + + default-browser@5.5.0: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.1 + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-lazy-prop@2.0.0: {} + + define-lazy-prop@3.0.0: {} + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + defu@6.1.7: {} + + delayed-stream@1.0.0: {} + + depd@2.0.0: {} + + dequal@2.0.3: {} + + destr@2.0.5: {} + + detect-libc@2.1.2: {} + + diff@8.0.4: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dot-prop@5.3.0: + dependencies: + is-obj: 2.0.0 + + dot-prop@9.0.0: + dependencies: + type-fest: 4.41.0 + + dotenv-expand@12.0.3: + dependencies: + dotenv: 16.6.1 + + dotenv@16.6.1: {} + + dotenv@17.4.2: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + duplexer2@0.1.4: + dependencies: + readable-stream: 2.3.8 + + ecdsa-sig-formatter@1.0.11: + dependencies: + safe-buffer: 5.2.1 + + eciesjs@0.4.18: + dependencies: + '@ecies/ciphers': 0.2.6(@noble/ciphers@1.3.0) + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + + ee-first@1.1.1: {} + + electron-to-chromium@1.5.340: {} + + emoji-regex@10.6.0: {} + + emoji-regex@8.0.0: {} + + emojilib@2.4.0: {} + + encodeurl@2.0.0: {} + + enhanced-resolve@5.20.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.2 + + entities@4.5.0: {} + + entities@7.0.1: {} + + env-ci@11.2.0: + dependencies: + execa: 8.0.1 + java-properties: 1.0.2 + + env-paths@2.2.1: {} + + environment@1.1.0: {} + + error-ex@1.3.4: + dependencies: + is-arrayish: 0.2.1 + + es-abstract@1.24.2: + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.3 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-negative-zero: 2.0.3 + is-regex: 1.2.1 + is-set: 2.0.3 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.3 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + stop-iteration-iterator: 1.1.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.20 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-iterator-helpers@1.3.2: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-set-tostringtag: 2.1.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + iterator.prototype: 1.1.5 + math-intrinsics: 1.1.0 + + es-module-lexer@2.0.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.3 + + es-shim-unscopables@1.1.0: + dependencies: + hasown: 2.0.3 + + es-to-primitive@1.3.0: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + + es6-error@4.1.1: {} + + esbuild@0.27.7: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.7 + '@esbuild/android-arm': 0.27.7 + '@esbuild/android-arm64': 0.27.7 + '@esbuild/android-x64': 0.27.7 + '@esbuild/darwin-arm64': 0.27.7 + '@esbuild/darwin-x64': 0.27.7 + '@esbuild/freebsd-arm64': 0.27.7 + '@esbuild/freebsd-x64': 0.27.7 + '@esbuild/linux-arm': 0.27.7 + '@esbuild/linux-arm64': 0.27.7 + '@esbuild/linux-ia32': 0.27.7 + '@esbuild/linux-loong64': 0.27.7 + '@esbuild/linux-mips64el': 0.27.7 + '@esbuild/linux-ppc64': 0.27.7 + '@esbuild/linux-riscv64': 0.27.7 + '@esbuild/linux-s390x': 0.27.7 + '@esbuild/linux-x64': 0.27.7 + '@esbuild/netbsd-arm64': 0.27.7 + '@esbuild/netbsd-x64': 0.27.7 + '@esbuild/openbsd-arm64': 0.27.7 + '@esbuild/openbsd-x64': 0.27.7 + '@esbuild/openharmony-arm64': 0.27.7 + '@esbuild/sunos-x64': 0.27.7 + '@esbuild/win32-arm64': 0.27.7 + '@esbuild/win32-ia32': 0.27.7 + '@esbuild/win32-x64': 0.27.7 + + escalade@3.2.0: {} + + escape-goat@4.0.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@4.0.0: {} + + escape-string-regexp@5.0.0: {} + + eslint-config-prettier@10.1.8(eslint@9.39.4(jiti@2.6.1)): + dependencies: + eslint: 9.39.4(jiti@2.6.1) + + eslint-plugin-react-hooks@7.1.1(eslint@9.39.4(jiti@2.6.1)): + dependencies: + '@babel/core': 7.29.0 + '@babel/parser': 7.29.2 + eslint: 9.39.4(jiti@2.6.1) + hermes-parser: 0.25.1 + zod: 4.3.6 + zod-validation-error: 4.0.2(zod@4.3.6) + transitivePeerDependencies: + - supports-color + + eslint-plugin-react@7.37.5(eslint@9.39.4(jiti@2.6.1)): + dependencies: + array-includes: 3.1.9 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.3 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.0 + es-iterator-helpers: 1.3.2 + eslint: 9.39.4(jiti@2.6.1) + estraverse: 5.3.0 + hasown: 2.0.3 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.5 + object.entries: 1.1.9 + object.fromentries: 2.0.8 + object.values: 1.2.1 + prop-types: 15.8.1 + resolve: 2.0.0-next.6 + semver: 6.3.1 string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - eslint-plugin-tailwindcss@3.18.0(tailwindcss@3.4.17): + eslint-plugin-tailwindcss@3.18.3(tailwindcss@4.2.2): + dependencies: + fast-glob: 3.3.3 + postcss: 8.5.10 + synckit: 0.11.12 + tailwind-api-utils: 1.0.3(tailwindcss@4.2.2) + tailwindcss: 4.2.2 + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint-visitor-keys@5.0.1: {} + + eslint@9.39.4(jiti@2.6.1): + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.2 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.5 + '@eslint/js': 9.39.4 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.8 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.8 + ajv: 6.14.0 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.6.1 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + eslint-visitor-keys: 4.2.1 + + esprima@4.0.1: {} + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + esutils@2.0.3: {} + + etag@1.8.1: {} + + eventemitter3@5.0.4: {} + + eventsource-parser@3.0.7: {} + + eventsource@3.0.7: + dependencies: + eventsource-parser: 3.0.7 + + execa@5.1.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + execa@8.0.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + + execa@9.6.1: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + cross-spawn: 7.0.6 + figures: 6.1.0 + get-stream: 9.0.1 + human-signals: 8.0.1 + is-plain-obj: 4.1.0 + is-stream: 4.0.1 + npm-run-path: 6.0.0 + pretty-ms: 9.3.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.1.2 + + express-rate-limit@8.3.2(express@5.2.1): + dependencies: + express: 5.2.1 + ip-address: 10.1.0 + + express@5.2.1: + dependencies: + accepts: 2.0.0 + body-parser: 2.2.2 + content-disposition: 1.1.0 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.3 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.1 + fresh: 2.0.0 + http-errors: 2.0.1 + merge-descriptors: 2.0.0 + mime-types: 3.0.2 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.7 + qs: 6.15.1 + range-parser: 1.2.1 + router: 2.2.0 + send: 1.2.1 + serve-static: 2.2.1 + statuses: 2.0.2 + type-is: 2.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + exsolve@1.0.8: {} + + fast-content-type-parse@3.0.0: {} + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fast-redact@3.5.0: {} + + fast-string-truncated-width@3.0.3: {} + + fast-string-width@3.0.2: + dependencies: + fast-string-truncated-width: 3.0.3 + + fast-uri@3.1.0: {} + + fast-wrap-ansi@0.2.0: + dependencies: + fast-string-width: 3.0.2 + + fastest-levenshtein@1.0.16: {} + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + fdir@6.5.0(picomatch@4.0.4): + optionalDependencies: + picomatch: 4.0.4 + + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + + figures@2.0.0: + dependencies: + escape-string-regexp: 1.0.5 + + figures@6.1.0: + dependencies: + is-unicode-supported: 2.1.0 + + file-entry-cache@11.1.2: + dependencies: + flat-cache: 6.1.22 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + filesize@11.0.15: {} + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + finalhandler@2.1.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + find-up-simple@1.0.1: {} + + find-up@2.1.0: + dependencies: + locate-path: 2.0.0 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + find-versions@6.0.0: + dependencies: + semver-regex: 4.0.5 + super-regex: 1.1.0 + + firefox-profile@4.7.0: + dependencies: + adm-zip: 0.5.17 + fs-extra: 11.3.4 + ini: 4.1.3 + minimist: 1.2.8 + xml2js: 0.6.2 + + flat-cache@4.0.1: + dependencies: + flatted: 3.4.2 + keyv: 4.5.4 + + flat-cache@6.1.22: + dependencies: + cacheable: 2.3.4 + flatted: 3.4.2 + hookified: 1.15.1 + + flatted@3.4.2: {} + + follow-redirects@1.16.0: {} + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + form-data-encoder@4.1.0: {} + + form-data@4.0.5: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.3 + mime-types: 2.1.35 + + formdata-node@6.0.3: {} + + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + + forwarded@0.2.0: {} + + fresh@2.0.0: {} + + from2@2.3.0: + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.8 + + fs-extra@11.3.4: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 + + fsevents@2.3.2: + optional: true + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + function-timeout@1.0.2: {} + + function.prototype.name@1.1.8: dependencies: - fast-glob: 3.3.2 - postcss: 8.5.1 - tailwindcss: 3.4.17 + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + hasown: 2.0.3 + is-callable: 1.2.7 - eslint-scope@8.2.0: + functions-have-names@1.2.3: {} + + fuzzysort@3.1.0: {} + + fx-runner@1.4.0: dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 + commander: 2.9.0 + shell-quote: 1.7.3 + spawn-sync: 1.0.15 + when: 3.7.7 + which: 1.2.4 + winreg: 0.0.12 - eslint-visitor-keys@3.4.3: {} + generator-function@2.0.1: {} + + gensync@1.0.0-beta.2: {} - eslint-visitor-keys@4.2.0: {} + get-caller-file@2.0.5: {} - eslint@9.19.0(jiti@1.21.6): + get-east-asian-width@1.5.0: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.3 + math-intrinsics: 1.1.0 + + get-own-enumerable-keys@1.0.0: {} + + get-port-please@3.2.0: {} + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-stream@6.0.1: {} + + get-stream@7.0.1: {} + + get-stream@8.0.1: {} + + get-stream@9.0.1: + dependencies: + '@sec-ant/readable-stream': 0.4.1 + is-stream: 4.0.1 + + get-symbol-description@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + + get-tsconfig@4.14.0: + dependencies: + resolve-pkg-maps: 1.0.0 + + giget@3.2.0: {} + + git-log-parser@1.2.1: + dependencies: + argv-formatter: 1.0.0 + spawn-error-forwarder: 1.0.0 + split2: 1.0.0 + stream-combiner2: 1.1.1 + through2: 2.0.5 + traverse: 0.6.8 + + glob-parent@5.1.2: dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.19.0(jiti@1.21.6)) - '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.19.2 - '@eslint/core': 0.10.0 - '@eslint/eslintrc': 3.2.0 - '@eslint/js': 9.19.0 - '@eslint/plugin-kit': 0.2.5 - '@humanfs/node': 0.16.6 - '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.4.1 - '@types/estree': 1.0.6 - '@types/json-schema': 7.0.15 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.6 - debug: 4.3.4 - escape-string-regexp: 4.0.0 - eslint-scope: 8.2.0 - eslint-visitor-keys: 4.2.0 - espree: 10.3.0 - esquery: 1.5.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 8.0.0 - find-up: 5.0.0 - glob-parent: 6.0.2 - ignore: 5.3.1 - imurmurhash: 0.1.4 is-glob: 4.0.3 - json-stable-stringify-without-jsonify: 1.0.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob-to-regexp@0.4.1: {} + + global-directory@4.0.1: + dependencies: + ini: 4.1.1 + + global-modules@2.0.0: + dependencies: + global-prefix: 3.0.0 + + global-prefix@3.0.0: + dependencies: + ini: 1.3.8 + kind-of: 6.0.3 + which: 1.3.1 + + globals@14.0.0: {} + + globals@17.5.0: {} + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + + globby@16.2.0: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + fast-glob: 3.3.3 + ignore: 7.0.5 + is-path-inside: 4.0.0 + slash: 5.1.0 + unicorn-magic: 0.4.0 + + globjoin@0.1.4: {} + + gopd@1.2.0: {} + + graceful-fs@4.2.10: {} + + graceful-fs@4.2.11: {} + + graceful-readlink@1.0.1: {} + + graphql@16.13.2: {} + + growly@1.3.0: {} + + handlebars@4.7.9: + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 optionalDependencies: - jiti: 1.21.6 + uglify-js: 3.19.3 + + has-bigints@1.1.0: {} + + has-flag@3.0.0: {} + + has-flag@4.0.0: {} + + has-flag@5.0.1: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-proto@1.2.0: + dependencies: + dunder-proto: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hashery@1.5.1: + dependencies: + hookified: 1.15.1 + + hasown@2.0.3: + dependencies: + function-bind: 1.1.2 + + headers-polyfill@5.0.1: + dependencies: + '@types/set-cookie-parser': 2.4.10 + set-cookie-parser: 3.1.0 + + hermes-estree@0.25.1: {} + + hermes-parser@0.25.1: + dependencies: + hermes-estree: 0.25.1 + + highlight.js@10.7.3: {} + + hono@4.12.14: {} + + hook-std@4.0.0: {} + + hookable@6.1.1: {} + + hookified@1.15.1: {} + + hookified@2.1.1: {} + + hosted-git-info@7.0.2: + dependencies: + lru-cache: 10.4.3 + + hosted-git-info@9.0.2: + dependencies: + lru-cache: 11.3.5 + + html-escaper@3.0.3: {} + + html-tags@5.1.0: {} + + htmlparser2@10.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 7.0.1 + + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + human-signals@2.1.0: {} + + human-signals@5.0.0: {} + + human-signals@8.0.1: {} + + iconv-lite@0.7.2: + dependencies: + safer-buffer: 2.1.2 + + ignore@5.3.2: {} + + ignore@7.0.5: {} + + immediate@3.0.6: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + import-from-esm@2.0.0: + dependencies: + debug: 4.4.3 + import-meta-resolve: 4.2.0 transitivePeerDependencies: - supports-color - espree@10.3.0: - dependencies: - acorn: 8.14.0 - acorn-jsx: 5.3.2(acorn@8.14.0) - eslint-visitor-keys: 4.2.0 + import-meta-resolve@4.2.0: {} + + imurmurhash@0.1.4: {} + + indent-string@4.0.0: {} + + indent-string@5.0.0: {} + + index-to-position@1.2.0: {} + + inherits@2.0.4: {} + + ini@1.3.8: {} + + ini@4.1.1: {} + + ini@4.1.3: {} + + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.3 + side-channel: 1.1.0 + + intl-messageformat@11.2.1: + dependencies: + '@formatjs/fast-memoize': 3.1.2 + '@formatjs/icu-messageformat-parser': 3.5.4 + + into-stream@7.0.0: + dependencies: + from2: 2.3.0 + p-is-promise: 3.0.0 + + ip-address@10.1.0: {} + + ipaddr.js@1.9.1: {} + + is-absolute@0.1.7: + dependencies: + is-relative: 0.1.3 + + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-arrayish@0.2.1: {} + + is-async-function@2.1.1: + dependencies: + async-function: 1.0.0 + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-bigint@1.1.0: + dependencies: + has-bigints: 1.1.0 + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-boolean-object@1.2.2: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-callable@1.2.7: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.3 + + is-data-view@1.0.2: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-docker@2.2.1: {} + + is-docker@3.0.0: {} + + is-extglob@2.1.1: {} + + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-fullwidth-code-point@3.0.0: {} + + is-fullwidth-code-point@5.1.0: + dependencies: + get-east-asian-width: 1.5.0 + + is-generator-function@1.1.2: + dependencies: + call-bound: 1.0.4 + generator-function: 2.0.1 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-in-ci@1.0.0: {} + + is-in-ssh@1.0.0: {} + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-installed-globally@1.0.0: + dependencies: + global-directory: 4.0.1 + is-path-inside: 4.0.0 + + is-interactive@2.0.0: {} + + is-map@2.0.3: {} + + is-negative-zero@2.0.3: {} - esquery@1.5.0: - dependencies: - estraverse: 5.3.0 + is-node-process@1.2.0: {} - esrecurse@4.3.0: + is-npm@6.1.0: {} + + is-number-object@1.1.1: dependencies: - estraverse: 5.3.0 + call-bound: 1.0.4 + has-tostringtag: 1.0.2 - estraverse@5.3.0: {} + is-number@7.0.0: {} - esutils@2.0.3: {} + is-obj@2.0.0: {} - fast-deep-equal@3.1.3: {} + is-obj@3.0.0: {} + + is-path-inside@4.0.0: {} - fast-glob@3.3.2: + is-plain-obj@4.1.0: {} + + is-plain-object@2.0.4: dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 + isobject: 3.0.1 - fast-json-stable-stringify@2.1.0: {} + is-plain-object@5.0.0: {} - fast-levenshtein@2.0.6: {} + is-potential-custom-element-name@1.0.1: {} - fastq@1.15.0: - dependencies: - reusify: 1.0.4 + is-primitive@3.0.1: {} - file-entry-cache@8.0.0: - dependencies: - flat-cache: 4.0.1 + is-promise@4.0.0: {} - fill-range@7.1.1: + is-regex@1.2.1: dependencies: - to-regex-range: 5.0.1 + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.3 - find-root@1.1.0: {} + is-regexp@3.1.0: {} - find-up@5.0.0: - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 + is-relative@0.1.3: {} - flat-cache@4.0.1: + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: dependencies: - flatted: 3.3.2 - keyv: 4.5.4 + call-bound: 1.0.4 - flatpickr@4.6.13: {} + is-stream@2.0.1: {} - flatted@3.3.2: {} + is-stream@3.0.0: {} - flatten-tailwindcss-theme@1.0.0: {} + is-stream@4.0.1: {} - follow-redirects@1.15.6: {} + is-string@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 - for-each@0.3.3: + is-symbol@1.1.1: dependencies: - is-callable: 1.2.7 + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 - foreground-child@3.3.0: + is-typed-array@1.1.15: dependencies: - cross-spawn: 7.0.6 - signal-exit: 4.1.0 + which-typed-array: 1.1.20 + + is-unicode-supported@1.3.0: {} + + is-unicode-supported@2.1.0: {} - form-data@4.0.0: + is-weakmap@2.0.2: {} + + is-weakref@1.1.1: dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 + call-bound: 1.0.4 - formik@2.4.6(react@19.0.0): + is-weakset@2.0.4: dependencies: - '@types/hoist-non-react-statics': 3.3.1 - deepmerge: 2.2.1 - hoist-non-react-statics: 3.3.2 - lodash: 4.17.21 - lodash-es: 4.17.21 - react: 19.0.0 - react-fast-compare: 2.0.4 - tiny-warning: 1.0.3 - tslib: 2.5.3 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 - fraction.js@4.3.7: {} + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 - fs-extra@11.2.0: + is-wsl@3.1.1: dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.1 + is-inside-container: 1.0.0 - fsevents@2.3.2: - optional: true + isarray@1.0.0: {} - fsevents@2.3.3: - optional: true + isarray@2.0.5: {} - function-bind@1.1.2: {} + isbot@5.1.39: {} - function.prototype.name@1.1.6: - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.23.3 - functions-have-names: 1.2.3 + isexe@1.1.2: {} - function.prototype.name@1.1.8: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.3 - define-properties: 1.2.1 - functions-have-names: 1.2.3 - hasown: 2.0.2 - is-callable: 1.2.7 + isexe@2.0.0: {} - functions-have-names@1.2.3: {} + isexe@3.1.5: {} - gensync@1.0.0-beta.2: {} + isobject@3.0.1: {} - get-intrinsic@1.2.7: + issue-parser@7.0.1: dependencies: - call-bind-apply-helpers: 1.0.1 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.0.0 - function-bind: 1.1.2 + lodash.capitalize: 4.2.1 + lodash.escaperegexp: 4.1.2 + lodash.isplainobject: 4.0.6 + lodash.isstring: 4.0.1 + lodash.uniqby: 4.7.0 + + iterator.prototype@1.1.5: + dependencies: + define-data-property: 1.1.4 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 get-proto: 1.0.1 - gopd: 1.2.0 has-symbols: 1.1.0 - hasown: 2.0.2 - math-intrinsics: 1.1.0 + set-function-name: 2.0.2 - get-proto@1.0.1: - dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.0.0 + java-properties@1.0.2: {} - get-symbol-description@1.0.2: - dependencies: - call-bind: 1.0.7 - es-errors: 1.3.0 - get-intrinsic: 1.2.7 + jiti@2.6.1: {} - get-symbol-description@1.1.0: - dependencies: - call-bound: 1.0.3 - es-errors: 1.3.0 - get-intrinsic: 1.2.7 + jose@6.2.2: {} - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 + js-tokens@4.0.0: {} - glob-parent@6.0.2: - dependencies: - is-glob: 4.0.3 + js-tokens@9.0.1: {} - glob@10.4.5: + js-yaml@4.1.1: dependencies: - foreground-child: 3.3.0 - jackspeak: 3.4.3 - minimatch: 9.0.4 - minipass: 7.1.2 - package-json-from-dist: 1.0.1 - path-scurry: 1.11.1 + argparse: 2.0.1 - globals@11.12.0: {} + jsesc@3.1.0: {} - globals@14.0.0: {} + json-buffer@3.0.1: {} - globals@15.14.0: {} + json-parse-better-errors@1.0.2: {} - globalthis@1.0.4: - dependencies: - define-properties: 1.2.1 - gopd: 1.2.0 + json-parse-even-better-errors@2.3.1: {} - gopd@1.2.0: {} + json-parse-even-better-errors@3.0.2: {} - graceful-fs@4.2.11: {} + json-schema-traverse@0.4.1: {} - graphemer@1.4.0: {} + json-schema-traverse@1.0.0: {} - has-bigints@1.0.2: {} + json-schema-typed@8.0.2: {} - has-flag@4.0.0: {} + json-stable-stringify-without-jsonify@1.0.1: {} - has-property-descriptors@1.0.2: - dependencies: - es-define-property: 1.0.1 + json-with-bigint@3.5.8: {} - has-proto@1.0.3: {} + json5@2.2.3: {} - has-proto@1.2.0: + jsonfile@6.2.0: dependencies: - dunder-proto: 1.0.1 + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 - has-symbols@1.1.0: {} + jsonwebtoken@9.0.3: + dependencies: + jws: 4.0.1 + lodash.includes: 4.3.0 + lodash.isboolean: 3.0.3 + lodash.isinteger: 4.0.4 + lodash.isnumber: 3.0.3 + lodash.isplainobject: 4.0.6 + lodash.isstring: 4.0.1 + lodash.once: 4.1.1 + ms: 2.1.3 + semver: 7.7.4 - has-tostringtag@1.0.2: + jsx-ast-utils@3.3.5: dependencies: - has-symbols: 1.1.0 + array-includes: 3.1.9 + array.prototype.flat: 1.3.3 + object.assign: 4.1.7 + object.values: 1.2.1 - hasown@2.0.2: + jszip@3.10.1: dependencies: - function-bind: 1.1.2 + lie: 3.3.0 + pako: 1.0.11 + readable-stream: 2.3.8 + setimmediate: 1.0.5 - hoist-non-react-statics@3.3.2: + jwa@2.0.1: dependencies: - react-is: 16.13.1 + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 - ignore@5.3.1: {} + jws@4.0.1: + dependencies: + jwa: 2.0.1 + safe-buffer: 5.2.1 - immediate@3.0.6: {} + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 - import-fresh@3.3.0: + keyv@5.6.0: dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 + '@keyv/serialize': 1.1.1 - imurmurhash@0.1.4: {} + kind-of@6.0.3: {} - inherits@2.0.4: {} + kleur@3.0.3: {} + + kleur@4.1.5: {} - internal-slot@1.0.7: + ky@1.14.3: {} + + latest-version@9.0.0: dependencies: - es-errors: 1.3.0 - hasown: 2.0.2 - side-channel: 1.1.0 + package-json: 10.0.1 - internal-slot@1.1.0: + levn@0.4.1: dependencies: - es-errors: 1.3.0 - hasown: 2.0.2 - side-channel: 1.1.0 + prelude-ls: 1.2.1 + type-check: 0.4.0 - intl-messageformat@10.7.14: + lie@3.3.0: dependencies: - '@formatjs/ecma402-abstract': 2.3.2 - '@formatjs/fast-memoize': 2.2.6 - '@formatjs/icu-messageformat-parser': 2.11.0 - tslib: 2.5.3 + immediate: 3.0.6 - is-array-buffer@3.0.4: + lighthouse-logger@2.0.2: dependencies: - call-bind: 1.0.7 - get-intrinsic: 1.2.7 + debug: 4.4.3 + marky: 1.3.0 + transitivePeerDependencies: + - supports-color - is-array-buffer@3.0.5: + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-darwin-arm64@1.32.0: + optional: true + + lightningcss-darwin-x64@1.32.0: + optional: true + + lightningcss-freebsd-x64@1.32.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true + + lightningcss-linux-arm64-gnu@1.32.0: + optional: true + + lightningcss-linux-arm64-musl@1.32.0: + optional: true + + lightningcss-linux-x64-gnu@1.32.0: + optional: true + + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + + lightningcss-win32-x64-msvc@1.32.0: + optional: true + + lightningcss@1.32.0: dependencies: - call-bind: 1.0.8 - call-bound: 1.0.3 - get-intrinsic: 1.2.7 + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 - is-arrayish@0.2.1: {} + lines-and-columns@1.2.4: {} - is-arrayish@0.3.2: {} + lines-and-columns@2.0.4: {} - is-async-function@2.0.0: + linkedom@0.18.12: dependencies: - has-tostringtag: 1.0.2 + css-select: 5.2.2 + cssom: 0.5.0 + html-escaper: 3.0.3 + htmlparser2: 10.1.0 + uhyphen: 0.2.0 - is-bigint@1.0.4: + listr2@10.2.1: dependencies: - has-bigints: 1.0.2 + cli-truncate: 5.2.0 + eventemitter3: 5.0.4 + log-update: 6.1.0 + rfdc: 1.4.1 + wrap-ansi: 10.0.0 - is-bigint@1.1.0: + load-json-file@4.0.0: dependencies: - has-bigints: 1.0.2 + graceful-fs: 4.2.11 + parse-json: 4.0.0 + pify: 3.0.0 + strip-bom: 3.0.0 - is-binary-path@2.1.0: + local-pkg@1.1.2: dependencies: - binary-extensions: 2.2.0 + mlly: 1.8.2 + pkg-types: 2.3.0 + quansync: 0.2.11 - is-boolean-object@1.1.2: + locate-path@2.0.0: dependencies: - call-bind: 1.0.7 - has-tostringtag: 1.0.2 + p-locate: 2.0.0 + path-exists: 3.0.0 - is-boolean-object@1.2.2: + locate-path@6.0.0: dependencies: - call-bound: 1.0.3 - has-tostringtag: 1.0.2 + p-locate: 5.0.0 - is-callable@1.2.7: {} + lodash-es@4.18.1: {} - is-core-module@2.13.1: - dependencies: - hasown: 2.0.2 + lodash.capitalize@4.2.1: {} - is-data-view@1.0.1: - dependencies: - is-typed-array: 1.1.13 + lodash.debounce@4.0.8: {} - is-data-view@1.0.2: - dependencies: - call-bound: 1.0.3 - get-intrinsic: 1.2.7 - is-typed-array: 1.1.15 + lodash.escaperegexp@4.1.2: {} - is-date-object@1.0.5: - dependencies: - has-tostringtag: 1.0.2 + lodash.includes@4.3.0: {} - is-date-object@1.1.0: - dependencies: - call-bound: 1.0.3 - has-tostringtag: 1.0.2 + lodash.isboolean@3.0.3: {} - is-extglob@2.1.1: {} + lodash.isinteger@4.0.4: {} - is-finalizationregistry@1.1.1: - dependencies: - call-bound: 1.0.3 + lodash.isnumber@3.0.3: {} - is-fullwidth-code-point@3.0.0: {} + lodash.isplainobject@4.0.6: {} - is-generator-function@1.0.10: - dependencies: - has-tostringtag: 1.0.2 + lodash.isstring@4.0.1: {} - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 + lodash.merge@4.6.2: {} - is-map@2.0.3: {} + lodash.once@4.1.1: {} - is-negative-zero@2.0.3: {} + lodash.truncate@4.4.2: {} - is-number-object@1.0.7: - dependencies: - has-tostringtag: 1.0.2 + lodash.uniqby@4.7.0: {} - is-number-object@1.1.1: - dependencies: - call-bound: 1.0.3 - has-tostringtag: 1.0.2 + lodash@4.18.1: {} - is-number@7.0.0: {} + log-symbols@6.0.0: + dependencies: + chalk: 5.6.2 + is-unicode-supported: 1.3.0 - is-regex@1.1.4: + log-update@6.1.0: dependencies: - call-bind: 1.0.7 - has-tostringtag: 1.0.2 + ansi-escapes: 7.3.0 + cli-cursor: 5.0.0 + slice-ansi: 7.1.2 + strip-ansi: 7.2.0 + wrap-ansi: 9.0.2 - is-regex@1.2.1: + loose-envify@1.4.0: dependencies: - call-bound: 1.0.3 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 + js-tokens: 4.0.0 - is-set@2.0.3: {} + lru-cache@10.4.3: {} - is-shared-array-buffer@1.0.3: - dependencies: - call-bind: 1.0.7 + lru-cache@11.3.5: {} - is-shared-array-buffer@1.0.4: + lru-cache@5.1.1: dependencies: - call-bound: 1.0.3 + yallist: 3.1.1 - is-string@1.0.7: + lucide-react@1.8.0(react@19.2.5): dependencies: - has-tostringtag: 1.0.2 + react: 19.2.5 - is-string@1.1.1: + magic-string@0.30.21: dependencies: - call-bound: 1.0.3 - has-tostringtag: 1.0.2 + '@jridgewell/sourcemap-codec': 1.5.5 - is-symbol@1.0.4: + magicast@0.5.2: dependencies: - has-symbols: 1.1.0 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + source-map-js: 1.2.1 - is-symbol@1.1.1: + make-asynchronous@1.1.0: dependencies: - call-bound: 1.0.3 - has-symbols: 1.1.0 - safe-regex-test: 1.1.0 + p-event: 6.0.1 + type-fest: 4.41.0 + web-worker: 1.5.0 - is-typed-array@1.1.13: - dependencies: - which-typed-array: 1.1.15 + make-error@1.3.6: {} - is-typed-array@1.1.15: + many-keys-map@3.0.3: {} + + marked-terminal@7.3.0(marked@15.0.12): dependencies: - which-typed-array: 1.1.18 + ansi-escapes: 7.3.0 + ansi-regex: 6.2.2 + chalk: 5.6.2 + cli-highlight: 2.1.11 + cli-table3: 0.6.5 + marked: 15.0.12 + node-emoji: 2.2.0 + supports-hyperlinks: 3.2.0 - is-weakmap@2.0.2: {} + marked@15.0.12: {} + + marky@1.3.0: {} + + math-intrinsics@1.1.0: {} + + mathml-tag-names@4.0.0: {} - is-weakref@1.0.2: - dependencies: - call-bind: 1.0.7 + mdn-data@2.27.1: {} - is-weakref@1.1.1: - dependencies: - call-bound: 1.0.3 + media-typer@1.1.0: {} - is-weakset@2.0.4: - dependencies: - call-bound: 1.0.3 - get-intrinsic: 1.2.7 + meow@13.2.0: {} - isarray@1.0.0: {} + meow@14.1.0: {} - isarray@2.0.5: {} + merge-descriptors@2.0.0: {} - isexe@2.0.0: {} + merge-stream@2.0.0: {} - iterator.prototype@1.1.5: - dependencies: - define-data-property: 1.1.4 - es-object-atoms: 1.0.0 - get-intrinsic: 1.2.7 - get-proto: 1.0.1 - has-symbols: 1.1.0 - set-function-name: 2.0.2 + merge2@1.4.1: {} - jackspeak@3.4.3: + micromatch@4.0.8: dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 + braces: 3.0.3 + picomatch: 2.3.2 - jiti@1.21.6: {} + mime-db@1.52.0: {} - js-tokens@4.0.0: {} + mime-db@1.54.0: {} - js-yaml@4.1.0: + mime-types@2.1.35: dependencies: - argparse: 2.0.1 - - jsesc@3.0.2: {} + mime-db: 1.52.0 - json-buffer@3.0.1: {} + mime-types@3.0.2: + dependencies: + mime-db: 1.54.0 - json-parse-even-better-errors@2.3.1: {} + mime@4.1.0: {} - json-schema-traverse@0.4.1: {} + mimic-fn@2.1.0: {} - json-stable-stringify-without-jsonify@1.0.1: {} + mimic-fn@4.0.0: {} - json5@2.2.3: {} + mimic-function@5.0.1: {} - jsonfile@6.1.0: + minimatch@10.2.5: dependencies: - universalify: 2.0.1 - optionalDependencies: - graceful-fs: 4.2.11 + brace-expansion: 5.0.5 - jsx-ast-utils@3.3.4: + minimatch@3.1.5: dependencies: - array-includes: 3.1.8 - array.prototype.flat: 1.3.1 - object.assign: 4.1.5 - object.values: 1.2.1 + brace-expansion: 1.1.14 - jszip@3.10.1: + minimist@1.2.8: {} + + mlly@1.8.2: dependencies: - lie: 3.3.0 - pako: 1.0.11 - readable-stream: 2.3.8 - setimmediate: 1.0.5 + acorn: 8.16.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.3 - keyv@4.5.4: + ms@2.1.3: {} + + msw@2.13.4(@types/node@24.12.2)(typescript@6.0.3): dependencies: - json-buffer: 3.0.1 + '@inquirer/confirm': 6.0.11(@types/node@24.12.2) + '@mswjs/interceptors': 0.41.3 + '@open-draft/deferred-promise': 3.0.0 + '@types/statuses': 2.0.6 + cookie: 1.1.1 + graphql: 16.13.2 + headers-polyfill: 5.0.1 + is-node-process: 1.2.0 + outvariant: 1.4.3 + path-to-regexp: 6.3.0 + picocolors: 1.1.1 + rettime: 0.11.7 + statuses: 2.0.2 + strict-event-emitter: 0.5.1 + tough-cookie: 6.0.1 + type-fest: 5.6.0 + until-async: 3.0.2 + yargs: 17.7.2 + optionalDependencies: + typescript: 6.0.3 + transitivePeerDependencies: + - '@types/node' - levn@0.4.1: + multimatch@6.0.0: dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 + '@types/minimatch': 3.0.5 + array-differ: 4.0.0 + array-union: 3.0.1 + minimatch: 3.1.5 - lie@3.3.0: + mute-stream@3.0.0: {} + + mz@2.7.0: dependencies: - immediate: 3.0.6 + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 - lilconfig@3.1.3: {} + nano-spawn@2.1.0: {} - lines-and-columns@1.2.4: {} + nanoid@3.3.11: {} - locate-path@6.0.0: + nanospinner@1.2.2: dependencies: - p-locate: 5.0.0 + picocolors: 1.1.1 - lodash-es@4.17.21: {} + natural-compare@1.4.0: {} - lodash.merge@4.6.2: {} + negotiator@1.0.0: {} - lodash@4.17.21: {} + neo-async@2.6.2: {} - loose-envify@1.4.0: - dependencies: - js-tokens: 4.0.0 + nerf-dart@1.0.0: {} - lru-cache@10.4.3: {} + node-domexception@1.0.0: {} - lru-cache@5.1.1: + node-emoji@2.2.0: dependencies: - yallist: 3.1.1 + '@sindresorhus/is': 4.6.0 + char-regex: 1.0.2 + emojilib: 2.4.0 + skin-tone: 2.0.0 - math-intrinsics@1.1.0: {} - - memoize-one@6.0.0: {} + node-exports-info@1.6.0: + dependencies: + array.prototype.flatmap: 1.3.3 + es-errors: 1.3.0 + object.entries: 1.1.9 + semver: 6.3.1 - merge2@1.4.1: {} + node-fetch-native@1.6.7: {} - micromatch@4.0.8: + node-fetch@3.3.2: dependencies: - braces: 3.0.3 - picomatch: 2.3.1 + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 - mime-db@1.52.0: {} + node-forge@1.4.0: {} - mime-types@2.1.35: + node-notifier@10.0.1: dependencies: - mime-db: 1.52.0 + growly: 1.3.0 + is-wsl: 2.2.0 + semver: 7.7.4 + shellwords: 0.1.1 + uuid: 8.3.2 + which: 2.0.2 + + node-releases@2.0.37: {} - minimatch@3.1.2: + normalize-package-data@6.0.2: dependencies: - brace-expansion: 1.1.11 + hosted-git-info: 7.0.2 + semver: 7.7.4 + validate-npm-package-license: 3.0.4 - minimatch@9.0.4: + normalize-package-data@8.0.0: dependencies: - brace-expansion: 2.0.1 + hosted-git-info: 9.0.2 + semver: 7.7.4 + validate-npm-package-license: 3.0.4 - minipass@7.1.2: {} + normalize-path@3.0.0: {} - ms@2.1.2: {} + normalize-url@9.0.0: {} - mz@2.7.0: + npm-run-path@4.0.1: dependencies: - any-promise: 1.3.0 - object-assign: 4.1.1 - thenify-all: 1.6.0 + path-key: 3.1.1 - nanoid@3.3.8: {} + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 - natural-compare@1.4.0: {} + npm-run-path@6.0.0: + dependencies: + path-key: 4.0.0 + unicorn-magic: 0.3.0 - node-releases@2.0.18: {} + npm@11.12.1: {} - normalize-path@3.0.0: {} + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 - normalize-range@0.1.2: {} + nypm@0.6.5: + dependencies: + citty: 0.2.2 + pathe: 2.0.3 + tinyexec: 1.1.1 object-assign@4.1.1: {} - object-hash@3.0.0: {} - object-inspect@1.13.4: {} object-keys@1.1.1: {} - object.assign@4.1.5: - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - has-symbols: 1.1.0 - object-keys: 1.1.1 + object-treeify@1.1.33: {} object.assign@4.1.7: dependencies: - call-bind: 1.0.8 - call-bound: 1.0.3 + call-bind: 1.0.9 + call-bound: 1.0.4 define-properties: 1.2.1 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 has-symbols: 1.1.0 object-keys: 1.1.1 - object.entries@1.1.8: + object.entries@1.1.9: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 define-properties: 1.2.1 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 object.fromentries@2.0.8: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.9 define-properties: 1.2.1 - es-abstract: 1.23.3 - es-object-atoms: 1.0.0 + es-abstract: 1.24.2 + es-object-atoms: 1.1.1 object.values@1.2.1: dependencies: - call-bind: 1.0.8 - call-bound: 1.0.3 + call-bind: 1.0.9 + call-bound: 1.0.4 define-properties: 1.2.1 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 + + obug@2.1.1: {} + + ofetch@1.5.1: + dependencies: + destr: 2.0.5 + node-fetch-native: 1.6.7 + ufo: 1.6.3 + + ohash@2.0.11: {} + + on-exit-leak-free@2.1.2: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 - optionator@0.9.3: + onetime@7.0.0: + dependencies: + mimic-function: 5.0.1 + + open@11.0.0: + dependencies: + default-browser: 5.5.0 + define-lazy-prop: 3.0.0 + is-in-ssh: 1.0.0 + is-inside-container: 1.0.0 + powershell-utils: 0.1.0 + wsl-utils: 0.3.1 + + open@8.4.2: + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + + optionator@0.9.4: dependencies: - '@aashutoshrathi/word-wrap': 1.2.6 deep-is: 0.1.4 fast-levenshtein: 2.0.6 levn: 0.4.1 prelude-ls: 1.2.1 type-check: 0.4.0 + word-wrap: 1.2.5 + + ora@8.2.0: + dependencies: + chalk: 5.6.2 + cli-cursor: 5.0.0 + cli-spinners: 2.9.2 + is-interactive: 2.0.0 + is-unicode-supported: 2.1.0 + log-symbols: 6.0.0 + stdin-discarder: 0.2.2 + string-width: 7.2.0 + strip-ansi: 7.2.0 + + os-shim@0.1.3: {} + + outvariant@1.4.3: {} own-keys@1.0.1: dependencies: - get-intrinsic: 1.2.7 + get-intrinsic: 1.3.0 object-keys: 1.1.1 safe-push-apply: 1.0.0 + p-each-series@3.0.0: {} + + p-event@6.0.1: + dependencies: + p-timeout: 6.1.4 + + p-filter@4.1.0: + dependencies: + p-map: 7.0.4 + + p-is-promise@3.0.0: {} + + p-limit@1.3.0: + dependencies: + p-try: 1.0.0 + p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 + p-locate@2.0.0: + dependencies: + p-limit: 1.3.0 + p-locate@5.0.0: dependencies: p-limit: 3.1.0 - package-json-from-dist@1.0.1: {} + p-map@7.0.4: {} + + p-reduce@2.1.0: {} + + p-reduce@3.0.0: {} + + p-timeout@6.1.4: {} + + p-try@1.0.0: {} + + package-json@10.0.1: + dependencies: + ky: 1.14.3 + registry-auth-token: 5.1.1 + registry-url: 6.0.1 + semver: 7.7.4 pako@1.0.11: {} @@ -4808,196 +9484,287 @@ snapshots: dependencies: callsites: 3.1.0 + parse-json@4.0.0: + dependencies: + error-ex: 1.3.4 + json-parse-better-errors: 1.0.2 + parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.26.2 - error-ex: 1.3.2 + '@babel/code-frame': 7.29.0 + error-ex: 1.3.4 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 + parse-json@7.1.1: + dependencies: + '@babel/code-frame': 7.29.0 + error-ex: 1.3.4 + json-parse-even-better-errors: 3.0.2 + lines-and-columns: 2.0.4 + type-fest: 3.13.1 + + parse-json@8.3.0: + dependencies: + '@babel/code-frame': 7.29.0 + index-to-position: 1.2.0 + type-fest: 4.41.0 + + parse-ms@4.0.0: {} + + parse5-htmlparser2-tree-adapter@6.0.1: + dependencies: + parse5: 6.0.1 + + parse5@5.1.1: {} + + parse5@6.0.1: {} + + parseurl@1.3.3: {} + + path-browserify@1.0.1: {} + + path-exists@3.0.0: {} + path-exists@4.0.0: {} path-key@3.1.1: {} + path-key@4.0.0: {} + path-parse@1.0.7: {} - path-scurry@1.11.1: - dependencies: - lru-cache: 10.4.3 - minipass: 7.1.2 + path-to-regexp@6.3.0: {} + + path-to-regexp@8.4.2: {} path-type@4.0.0: {} - picocolors@1.0.1: {} + pathe@2.0.3: {} + + perfect-debounce@2.1.0: {} picocolors@1.1.1: {} - picomatch@2.3.1: {} + picomatch@2.3.2: {} + + picomatch@4.0.4: {} - pify@2.3.0: {} + pify@3.0.0: {} - pirates@4.0.5: {} + pino-abstract-transport@2.0.0: + dependencies: + split2: 4.2.0 - playwright-core@1.50.1: {} + pino-std-serializers@7.1.0: {} - playwright@1.50.1: + pino@9.7.0: dependencies: - playwright-core: 1.50.1 - optionalDependencies: - fsevents: 2.3.2 + atomic-sleep: 1.0.0 + fast-redact: 3.5.0 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 2.0.0 + pino-std-serializers: 7.1.0 + process-warning: 5.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.2.0 + safe-stable-stringify: 2.5.0 + sonic-boom: 4.2.1 + thread-stream: 3.1.0 - possible-typed-array-names@1.0.0: {} + pkce-challenge@5.0.1: {} - postcss-import@15.1.0(postcss@8.5.1): + pkg-conf@2.1.0: dependencies: - postcss: 8.5.1 - postcss-value-parser: 4.2.0 - read-cache: 1.0.0 - resolve: 1.22.8 + find-up: 2.1.0 + load-json-file: 4.0.0 + + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.2 + pathe: 2.0.3 - postcss-js@4.0.1(postcss@8.5.1): + pkg-types@2.3.0: dependencies: - camelcase-css: 2.0.1 - postcss: 8.5.1 + confbox: 0.2.4 + exsolve: 1.0.8 + pathe: 2.0.3 - postcss-load-config@4.0.2(postcss@8.5.1): + playwright-core@1.59.1: {} + + playwright@1.59.1: dependencies: - lilconfig: 3.1.3 - yaml: 2.6.1 + playwright-core: 1.59.1 optionalDependencies: - postcss: 8.5.1 + fsevents: 2.3.2 - postcss-nested@6.2.0(postcss@8.5.1): + possible-typed-array-names@1.1.0: {} + + postcss-safe-parser@7.0.1(postcss@8.5.10): dependencies: - postcss: 8.5.1 - postcss-selector-parser: 6.1.2 + postcss: 8.5.10 - postcss-selector-parser@6.1.2: + postcss-selector-parser@7.1.1: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 postcss-value-parser@4.2.0: {} - postcss@8.5.1: + postcss@8.5.10: dependencies: - nanoid: 3.3.8 + nanoid: 3.3.11 picocolors: 1.1.1 source-map-js: 1.2.1 + powershell-utils@0.1.0: {} + prelude-ls@1.2.1: {} - prettier-plugin-tailwindcss@0.6.11(prettier@3.4.2): + prettier-plugin-tailwindcss@0.7.2(prettier@3.8.3): dependencies: - prettier: 3.4.2 + prettier: 3.8.3 - prettier@3.4.2: {} + prettier@3.8.3: {} + + pretty-ms@9.3.0: + dependencies: + parse-ms: 4.0.0 process-nextick-args@2.0.1: {} + process-warning@5.0.0: {} + + promise-toolbox@0.21.0: + dependencies: + make-error: 1.3.6 + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + prop-types@15.8.1: dependencies: loose-envify: 1.4.0 object-assign: 4.1.1 react-is: 16.13.1 - property-expr@2.0.5: {} + proto-list@1.2.4: {} + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + proxy-from-env@2.1.0: {} + + publish-browser-extension@4.0.5: + dependencies: + cac: 6.7.14 + consola: 3.4.2 + dotenv: 17.4.2 + form-data-encoder: 4.1.0 + formdata-node: 6.0.3 + jsonwebtoken: 9.0.3 + listr2: 10.2.1 + ofetch: 1.5.1 + zod: 4.3.6 - proxy-from-env@1.1.0: {} + punycode@2.3.1: {} - punycode@2.3.0: {} + pupa@3.3.0: + dependencies: + escape-goat: 4.0.0 + + qified@0.9.1: + dependencies: + hookified: 2.1.1 - qs@6.14.0: + qs@6.15.1: dependencies: side-channel: 1.1.0 + quansync@0.2.11: {} + queue-microtask@1.2.3: {} - react-dom@19.0.0(react@19.0.0): - dependencies: - react: 19.0.0 - scheduler: 0.25.0 + quick-format-unescaped@4.0.4: {} - react-fast-compare@2.0.4: {} + range-parser@1.2.1: {} - react-flatpickr@3.10.13(react@19.0.0): + raw-body@3.0.2: dependencies: - flatpickr: 4.6.13 - prop-types: 15.8.1 - react: 19.0.0 - - react-intl@7.1.5(react@19.0.0)(typescript@5.7.3): - dependencies: - '@formatjs/ecma402-abstract': 2.3.2 - '@formatjs/icu-messageformat-parser': 2.11.0 - '@formatjs/intl': 3.1.3(typescript@5.7.3) - '@types/hoist-non-react-statics': 3.3.1 - '@types/react': 19.0.8 - hoist-non-react-statics: 3.3.2 - intl-messageformat: 10.7.14 - react: 19.0.0 - tslib: 2.5.3 - optionalDependencies: - typescript: 5.7.3 + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.7.2 + unpipe: 1.0.0 - react-is@16.13.1: {} + rc9@3.0.1: + dependencies: + defu: 6.1.7 + destr: 2.0.5 - react-refresh@0.14.2: {} + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 - react-router-dom@7.1.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + react-day-picker@9.14.0(react@19.2.5): dependencies: - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - react-router: 7.1.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@date-fns/tz': 1.4.1 + '@tabby_ai/hijri-converter': 1.0.5 + date-fns: 4.1.0 + date-fns-jalali: 4.1.0-0 + react: 19.2.5 - react-router@7.1.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + react-dom@19.2.5(react@19.2.5): dependencies: - '@types/cookie': 0.6.0 - cookie: 1.0.2 - react: 19.0.0 - set-cookie-parser: 2.7.1 - turbo-stream: 2.4.0 - optionalDependencies: - react-dom: 19.0.0(react@19.0.0) + react: 19.2.5 + scheduler: 0.27.0 - react-select@5.10.0(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + react-intl@10.1.2(@types/react@19.2.14)(react@19.2.5): dependencies: - '@babel/runtime': 7.24.0 - '@emotion/cache': 11.11.0 - '@emotion/react': 11.11.1(@types/react@19.0.8)(react@19.0.0) - '@floating-ui/dom': 1.6.3 - '@types/react-transition-group': 4.4.6 - memoize-one: 6.0.0 - prop-types: 15.8.1 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - react-transition-group: 4.4.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - use-isomorphic-layout-effect: 1.2.0(@types/react@19.0.8)(react@19.0.0) - transitivePeerDependencies: - - '@types/react' - - supports-color + '@formatjs/icu-messageformat-parser': 3.5.4 + '@formatjs/intl': 4.1.6 + '@types/react': 19.2.14 + intl-messageformat: 11.2.1 + react: 19.2.5 + + react-is@16.13.1: {} - react-tooltip@5.28.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + react@19.2.5: {} + + read-package-up@11.0.0: dependencies: - '@floating-ui/dom': 1.6.3 - classnames: 2.3.2 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + find-up-simple: 1.0.1 + read-pkg: 9.0.1 + type-fest: 4.41.0 - react-transition-group@4.4.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + read-package-up@12.0.0: dependencies: - '@babel/runtime': 7.24.0 - dom-helpers: 5.2.1 - loose-envify: 1.4.0 - prop-types: 15.8.1 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + find-up-simple: 1.0.1 + read-pkg: 10.1.0 + type-fest: 5.6.0 - react@19.0.0: {} + read-pkg@10.1.0: + dependencies: + '@types/normalize-package-data': 2.4.4 + normalize-package-data: 8.0.0 + parse-json: 8.3.0 + type-fest: 5.6.0 + unicorn-magic: 0.4.0 - read-cache@1.0.0: + read-pkg@9.0.1: dependencies: - pify: 2.3.0 + '@types/normalize-package-data': 2.4.4 + normalize-package-data: 6.0.2 + parse-json: 8.3.0 + type-fest: 4.41.0 + unicorn-magic: 0.1.0 readable-stream@2.3.8: dependencies: @@ -5011,130 +9778,261 @@ snapshots: readdirp@3.6.0: dependencies: - picomatch: 2.3.1 + picomatch: 2.3.2 + + readdirp@5.0.0: {} + + real-require@0.2.0: {} + + recast@0.23.11: + dependencies: + ast-types: 0.16.1 + esprima: 4.0.1 + source-map: 0.6.1 + tiny-invariant: 1.3.3 + tslib: 2.8.1 reflect.getprototypeof@1.0.10: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 - es-abstract: 1.23.9 + es-abstract: 1.24.2 es-errors: 1.3.0 - es-object-atoms: 1.0.0 - get-intrinsic: 1.2.7 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 get-proto: 1.0.1 which-builtin-type: 1.2.1 - regenerator-runtime@0.14.0: {} - - regexp.prototype.flags@1.5.2: - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-errors: 1.3.0 - set-function-name: 2.0.2 - regexp.prototype.flags@1.5.4: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 es-errors: 1.3.0 get-proto: 1.0.1 gopd: 1.2.0 set-function-name: 2.0.2 + registry-auth-token@5.1.1: + dependencies: + '@pnpm/npm-conf': 3.0.2 + + registry-url@6.0.1: + dependencies: + rc: 1.2.8 + + require-directory@2.1.1: {} + + require-from-string@2.0.2: {} + + reselect@5.1.1: {} + resolve-from@4.0.0: {} - resolve@1.22.8: + resolve-from@5.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve@2.0.0-next.6: dependencies: - is-core-module: 2.13.1 + es-errors: 1.3.0 + is-core-module: 2.16.1 + node-exports-info: 1.6.0 + object-keys: 1.1.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - resolve@2.0.0-next.5: + restore-cursor@5.1.0: dependencies: - is-core-module: 2.13.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 + onetime: 7.0.0 + signal-exit: 4.1.0 - reusify@1.0.4: {} + rettime@0.11.7: {} - rollup@4.34.3: + reusify@1.1.0: {} + + rfdc@1.4.1: {} + + rolldown@1.0.0-rc.15: dependencies: - '@types/estree': 1.0.6 + '@oxc-project/types': 0.124.0 + '@rolldown/pluginutils': 1.0.0-rc.15 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.34.3 - '@rollup/rollup-android-arm64': 4.34.3 - '@rollup/rollup-darwin-arm64': 4.34.3 - '@rollup/rollup-darwin-x64': 4.34.3 - '@rollup/rollup-freebsd-arm64': 4.34.3 - '@rollup/rollup-freebsd-x64': 4.34.3 - '@rollup/rollup-linux-arm-gnueabihf': 4.34.3 - '@rollup/rollup-linux-arm-musleabihf': 4.34.3 - '@rollup/rollup-linux-arm64-gnu': 4.34.3 - '@rollup/rollup-linux-arm64-musl': 4.34.3 - '@rollup/rollup-linux-loongarch64-gnu': 4.34.3 - '@rollup/rollup-linux-powerpc64le-gnu': 4.34.3 - '@rollup/rollup-linux-riscv64-gnu': 4.34.3 - '@rollup/rollup-linux-s390x-gnu': 4.34.3 - '@rollup/rollup-linux-x64-gnu': 4.34.3 - '@rollup/rollup-linux-x64-musl': 4.34.3 - '@rollup/rollup-win32-arm64-msvc': 4.34.3 - '@rollup/rollup-win32-ia32-msvc': 4.34.3 - '@rollup/rollup-win32-x64-msvc': 4.34.3 + '@rolldown/binding-android-arm64': 1.0.0-rc.15 + '@rolldown/binding-darwin-arm64': 1.0.0-rc.15 + '@rolldown/binding-darwin-x64': 1.0.0-rc.15 + '@rolldown/binding-freebsd-x64': 1.0.0-rc.15 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.15 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.15 + '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.15 + '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.15 + '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.15 + '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.15 + '@rolldown/binding-linux-x64-musl': 1.0.0-rc.15 + '@rolldown/binding-openharmony-arm64': 1.0.0-rc.15 + '@rolldown/binding-wasm32-wasi': 1.0.0-rc.15 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.15 + '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.15 + + rollup@4.59.0: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.59.0 + '@rollup/rollup-android-arm64': 4.59.0 + '@rollup/rollup-darwin-arm64': 4.59.0 + '@rollup/rollup-darwin-x64': 4.59.0 + '@rollup/rollup-freebsd-arm64': 4.59.0 + '@rollup/rollup-freebsd-x64': 4.59.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.59.0 + '@rollup/rollup-linux-arm-musleabihf': 4.59.0 + '@rollup/rollup-linux-arm64-gnu': 4.59.0 + '@rollup/rollup-linux-arm64-musl': 4.59.0 + '@rollup/rollup-linux-loong64-gnu': 4.59.0 + '@rollup/rollup-linux-loong64-musl': 4.59.0 + '@rollup/rollup-linux-ppc64-gnu': 4.59.0 + '@rollup/rollup-linux-ppc64-musl': 4.59.0 + '@rollup/rollup-linux-riscv64-gnu': 4.59.0 + '@rollup/rollup-linux-riscv64-musl': 4.59.0 + '@rollup/rollup-linux-s390x-gnu': 4.59.0 + '@rollup/rollup-linux-x64-gnu': 4.59.0 + '@rollup/rollup-linux-x64-musl': 4.59.0 + '@rollup/rollup-openbsd-x64': 4.59.0 + '@rollup/rollup-openharmony-arm64': 4.59.0 + '@rollup/rollup-win32-arm64-msvc': 4.59.0 + '@rollup/rollup-win32-ia32-msvc': 4.59.0 + '@rollup/rollup-win32-x64-gnu': 4.59.0 + '@rollup/rollup-win32-x64-msvc': 4.59.0 fsevents: 2.3.3 + optional: true - run-parallel@1.2.0: + router@2.2.0: dependencies: - queue-microtask: 1.2.3 + debug: 4.4.3 + depd: 2.0.0 + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.4.2 + transitivePeerDependencies: + - supports-color - safe-array-concat@1.1.2: + run-applescript@7.1.0: {} + + run-parallel@1.2.0: dependencies: - call-bind: 1.0.7 - get-intrinsic: 1.2.7 - has-symbols: 1.1.0 - isarray: 2.0.5 + queue-microtask: 1.2.3 safe-array-concat@1.1.3: dependencies: - call-bind: 1.0.8 - call-bound: 1.0.3 - get-intrinsic: 1.2.7 + call-bind: 1.0.9 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 has-symbols: 1.1.0 isarray: 2.0.5 safe-buffer@5.1.2: {} + safe-buffer@5.2.1: {} + safe-push-apply@1.0.0: dependencies: es-errors: 1.3.0 isarray: 2.0.5 - safe-regex-test@1.0.3: - dependencies: - call-bind: 1.0.7 - es-errors: 1.3.0 - is-regex: 1.1.4 - safe-regex-test@1.1.0: dependencies: - call-bound: 1.0.3 + call-bound: 1.0.4 es-errors: 1.3.0 is-regex: 1.2.1 - scheduler@0.25.0: {} + safe-stable-stringify@2.5.0: {} + + safer-buffer@2.1.2: {} + + sax@1.6.0: {} + + scheduler@0.27.0: {} + + scule@1.3.0: {} + + semantic-release@25.0.3(typescript@6.0.3): + dependencies: + '@semantic-release/commit-analyzer': 13.0.1(semantic-release@25.0.3(typescript@6.0.3)) + '@semantic-release/error': 4.0.0 + '@semantic-release/github': 12.0.6(semantic-release@25.0.3(typescript@6.0.3)) + '@semantic-release/npm': 13.1.5(semantic-release@25.0.3(typescript@6.0.3)) + '@semantic-release/release-notes-generator': 14.1.0(semantic-release@25.0.3(typescript@6.0.3)) + aggregate-error: 5.0.0 + cosmiconfig: 9.0.1(typescript@6.0.3) + debug: 4.4.3 + env-ci: 11.2.0 + execa: 9.6.1 + figures: 6.1.0 + find-versions: 6.0.0 + get-stream: 6.0.1 + git-log-parser: 1.2.1 + hook-std: 4.0.0 + hosted-git-info: 9.0.2 + import-from-esm: 2.0.0 + lodash-es: 4.18.1 + marked: 15.0.12 + marked-terminal: 7.3.0(marked@15.0.12) + micromatch: 4.0.8 + p-each-series: 3.0.0 + p-reduce: 3.0.0 + read-package-up: 12.0.0 + resolve-from: 5.0.0 + semver: 7.7.4 + signale: 1.4.0 + yargs: 18.0.0 + transitivePeerDependencies: + - supports-color + - typescript + + semver-regex@4.0.5: {} semver@6.3.1: {} - semver@7.6.3: {} + semver@7.7.4: {} + + send@1.2.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.1 + mime-types: 3.0.2 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + seroval-plugins@1.5.2(seroval@1.5.2): + dependencies: + seroval: 1.5.2 + + seroval@1.5.2: {} + + serve-static@2.2.1: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.1 + transitivePeerDependencies: + - supports-color - set-cookie-parser@2.7.1: {} + set-cookie-parser@3.1.0: {} set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 es-errors: 1.3.0 function-bind: 1.1.2 - get-intrinsic: 1.2.7 + get-intrinsic: 1.3.0 gopd: 1.2.0 has-property-descriptors: 1.0.2 @@ -5149,35 +10047,90 @@ snapshots: dependencies: dunder-proto: 1.0.1 es-errors: 1.3.0 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 + + set-value@4.1.0: + dependencies: + is-plain-object: 2.0.4 + is-primitive: 3.0.1 setimmediate@1.0.5: {} - sharp@0.33.5: + setprototypeof@1.2.0: {} + + shadcn@4.3.0(@types/node@24.12.2)(typescript@6.0.3): + dependencies: + '@babel/core': 7.29.0 + '@babel/parser': 7.29.2 + '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) + '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) + '@dotenvx/dotenvx': 1.61.1 + '@modelcontextprotocol/sdk': 1.29.0(zod@3.25.76) + '@types/validate-npm-package-name': 4.0.2 + browserslist: 4.28.2 + commander: 14.0.3 + cosmiconfig: 9.0.1(typescript@6.0.3) + dedent: 1.7.2 + deepmerge: 4.3.1 + diff: 8.0.4 + execa: 9.6.1 + fast-glob: 3.3.3 + fs-extra: 11.3.4 + fuzzysort: 3.1.0 + https-proxy-agent: 7.0.6 + kleur: 4.1.5 + msw: 2.13.4(@types/node@24.12.2)(typescript@6.0.3) + node-fetch: 3.3.2 + open: 11.0.0 + ora: 8.2.0 + postcss: 8.5.10 + postcss-selector-parser: 7.1.1 + prompts: 2.4.2 + recast: 0.23.11 + stringify-object: 5.0.0 + tailwind-merge: 3.5.0 + ts-morph: 26.0.0 + tsconfig-paths: 4.2.0 + validate-npm-package-name: 7.0.2 + zod: 3.25.76 + zod-to-json-schema: 3.25.2(zod@3.25.76) + transitivePeerDependencies: + - '@cfworker/json-schema' + - '@types/node' + - babel-plugin-macros + - supports-color + - typescript + + sharp@0.34.5: dependencies: - color: 4.2.3 - detect-libc: 2.0.3 - semver: 7.6.3 + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.7.4 optionalDependencies: - '@img/sharp-darwin-arm64': 0.33.5 - '@img/sharp-darwin-x64': 0.33.5 - '@img/sharp-libvips-darwin-arm64': 1.0.4 - '@img/sharp-libvips-darwin-x64': 1.0.4 - '@img/sharp-libvips-linux-arm': 1.0.5 - '@img/sharp-libvips-linux-arm64': 1.0.4 - '@img/sharp-libvips-linux-s390x': 1.0.4 - '@img/sharp-libvips-linux-x64': 1.0.4 - '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 - '@img/sharp-libvips-linuxmusl-x64': 1.0.4 - '@img/sharp-linux-arm': 0.33.5 - '@img/sharp-linux-arm64': 0.33.5 - '@img/sharp-linux-s390x': 0.33.5 - '@img/sharp-linux-x64': 0.33.5 - '@img/sharp-linuxmusl-arm64': 0.33.5 - '@img/sharp-linuxmusl-x64': 0.33.5 - '@img/sharp-wasm32': 0.33.5 - '@img/sharp-win32-ia32': 0.33.5 - '@img/sharp-win32-x64': 0.33.5 + '@img/sharp-darwin-arm64': 0.34.5 + '@img/sharp-darwin-x64': 0.34.5 + '@img/sharp-libvips-darwin-arm64': 1.2.4 + '@img/sharp-libvips-darwin-x64': 1.2.4 + '@img/sharp-libvips-linux-arm': 1.2.4 + '@img/sharp-libvips-linux-arm64': 1.2.4 + '@img/sharp-libvips-linux-ppc64': 1.2.4 + '@img/sharp-libvips-linux-riscv64': 1.2.4 + '@img/sharp-libvips-linux-s390x': 1.2.4 + '@img/sharp-libvips-linux-x64': 1.2.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + '@img/sharp-linux-arm': 0.34.5 + '@img/sharp-linux-arm64': 0.34.5 + '@img/sharp-linux-ppc64': 0.34.5 + '@img/sharp-linux-riscv64': 0.34.5 + '@img/sharp-linux-s390x': 0.34.5 + '@img/sharp-linux-x64': 0.34.5 + '@img/sharp-linuxmusl-arm64': 0.34.5 + '@img/sharp-linuxmusl-x64': 0.34.5 + '@img/sharp-wasm32': 0.34.5 + '@img/sharp-win32-arm64': 0.34.5 + '@img/sharp-win32-ia32': 0.34.5 + '@img/sharp-win32-x64': 0.34.5 shebang-command@2.0.0: dependencies: @@ -5185,23 +10138,27 @@ snapshots: shebang-regex@3.0.0: {} - side-channel-list@1.0.0: + shell-quote@1.7.3: {} + + shellwords@0.1.1: {} + + side-channel-list@1.0.1: dependencies: es-errors: 1.3.0 object-inspect: 1.13.4 side-channel-map@1.0.1: dependencies: - call-bound: 1.0.3 + call-bound: 1.0.4 es-errors: 1.3.0 - get-intrinsic: 1.2.7 + get-intrinsic: 1.3.0 object-inspect: 1.13.4 side-channel-weakmap@1.0.2: dependencies: - call-bound: 1.0.3 + call-bound: 1.0.4 es-errors: 1.3.0 - get-intrinsic: 1.2.7 + get-intrinsic: 1.3.0 object-inspect: 1.13.4 side-channel-map: 1.0.1 @@ -5209,19 +10166,110 @@ snapshots: dependencies: es-errors: 1.3.0 object-inspect: 1.13.4 - side-channel-list: 1.0.0 + side-channel-list: 1.0.1 side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 + signal-exit@3.0.7: {} + signal-exit@4.1.0: {} - simple-swizzle@0.2.2: + signale@1.4.0: + dependencies: + chalk: 2.4.2 + figures: 2.0.0 + pkg-conf: 2.1.0 + + sisteransi@1.0.5: {} + + skin-tone@2.0.0: + dependencies: + unicode-emoji-modifier-base: 1.0.0 + + slash@5.1.0: {} + + slice-ansi@4.0.0: + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + + slice-ansi@7.1.2: dependencies: - is-arrayish: 0.3.2 + ansi-styles: 6.2.3 + is-fullwidth-code-point: 5.1.0 + + slice-ansi@8.0.0: + dependencies: + ansi-styles: 6.2.3 + is-fullwidth-code-point: 5.1.0 + + sonic-boom@4.2.1: + dependencies: + atomic-sleep: 1.0.0 + + sonner@2.0.7(react-dom@19.2.5(react@19.2.5))(react@19.2.5): + dependencies: + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) source-map-js@1.2.1: {} - source-map@0.5.7: {} + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + source-map@0.7.6: {} + + spawn-error-forwarder@1.0.0: {} + + spawn-sync@1.0.15: + dependencies: + concat-stream: 1.6.2 + os-shim: 0.1.3 + + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.23 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.23 + + spdx-license-ids@3.0.23: {} + + split2@1.0.0: + dependencies: + through2: 2.0.5 + + split2@4.2.0: {} + + split@1.0.1: + dependencies: + through: 2.3.8 + + statuses@2.0.2: {} + + stdin-discarder@0.2.2: {} + + stop-iteration-iterator@1.1.0: + dependencies: + es-errors: 1.3.0 + internal-slot: 1.1.0 + + stream-combiner2@1.1.1: + dependencies: + duplexer2: 0.1.4 + readable-stream: 2.3.8 + + strict-event-emitter@0.5.1: {} string-width@4.2.3: dependencies: @@ -5229,21 +10277,26 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - string-width@5.1.2: + string-width@7.2.0: + dependencies: + emoji-regex: 10.6.0 + get-east-asian-width: 1.5.0 + strip-ansi: 7.2.0 + + string-width@8.2.0: dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 + get-east-asian-width: 1.5.0 + strip-ansi: 7.2.0 string.prototype.matchall@4.0.12: dependencies: - call-bind: 1.0.8 - call-bound: 1.0.3 + call-bind: 1.0.9 + call-bound: 1.0.4 define-properties: 1.2.1 - es-abstract: 1.23.9 + es-abstract: 1.24.2 es-errors: 1.3.0 - es-object-atoms: 1.0.0 - get-intrinsic: 1.2.7 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 gopd: 1.2.0 has-symbols: 1.1.0 internal-slot: 1.1.0 @@ -5254,118 +10307,196 @@ snapshots: string.prototype.repeat@1.0.0: dependencies: define-properties: 1.2.1 - es-abstract: 1.23.3 + es-abstract: 1.24.2 string.prototype.trim@1.2.10: dependencies: - call-bind: 1.0.8 - call-bound: 1.0.3 + call-bind: 1.0.9 + call-bound: 1.0.4 define-data-property: 1.1.4 define-properties: 1.2.1 - es-abstract: 1.23.9 - es-object-atoms: 1.0.0 + es-abstract: 1.24.2 + es-object-atoms: 1.1.1 has-property-descriptors: 1.0.2 - string.prototype.trim@1.2.9: - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.23.3 - es-object-atoms: 1.0.0 - - string.prototype.trimend@1.0.8: - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-object-atoms: 1.0.0 - string.prototype.trimend@1.0.9: dependencies: - call-bind: 1.0.8 - call-bound: 1.0.3 + call-bind: 1.0.9 + call-bound: 1.0.4 define-properties: 1.2.1 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 string.prototype.trimstart@1.0.8: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.9 define-properties: 1.2.1 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 string_decoder@1.1.1: dependencies: safe-buffer: 5.1.2 + stringify-object@5.0.0: + dependencies: + get-own-enumerable-keys: 1.0.0 + is-obj: 3.0.0 + is-regexp: 3.1.0 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.1.0: + strip-ansi@7.2.0: dependencies: - ansi-regex: 6.1.0 + ansi-regex: 6.2.2 + + strip-bom@3.0.0: {} + + strip-bom@5.0.0: {} + + strip-final-newline@2.0.0: {} + + strip-final-newline@3.0.0: {} + + strip-final-newline@4.0.0: {} + + strip-json-comments@2.0.1: {} strip-json-comments@3.1.1: {} - stylis@4.2.0: {} + strip-json-comments@5.0.2: {} - sucrase@3.35.0: + strip-literal@3.1.0: dependencies: - '@jridgewell/gen-mapping': 0.3.5 - commander: 4.1.1 - glob: 10.4.5 - lines-and-columns: 1.2.4 - mz: 2.7.0 - pirates: 4.0.5 - ts-interface-checker: 0.1.13 + js-tokens: 9.0.1 - supports-color@7.2.0: + stubborn-fs@2.0.0: dependencies: - has-flag: 4.0.0 - - supports-preserve-symlinks-flag@1.0.0: {} + stubborn-utils: 1.0.2 - tailwind-merge@2.6.0: {} + stubborn-utils@1.0.2: {} - tailwindcss-animate@1.0.7(tailwindcss@3.4.17): + stylelint-config-recommended@18.0.0(stylelint@17.8.0(typescript@6.0.3)): dependencies: - tailwindcss: 3.4.17 + stylelint: 17.8.0(typescript@6.0.3) - tailwindcss-shadow-fill@1.0.1(tailwindcss@3.4.17): + stylelint-config-standard@40.0.0(stylelint@17.8.0(typescript@6.0.3)): dependencies: - flatten-tailwindcss-theme: 1.0.0 - tailwindcss: 3.4.17 + stylelint: 17.8.0(typescript@6.0.3) + stylelint-config-recommended: 18.0.0(stylelint@17.8.0(typescript@6.0.3)) - tailwindcss-text-fill@0.2.0(tailwindcss@3.4.17): + stylelint-config-tailwindcss@1.0.1(stylelint@17.8.0(typescript@6.0.3))(tailwindcss@4.2.2): dependencies: - flatten-tailwindcss-theme: 1.0.0 - tailwindcss: 3.4.17 + stylelint: 17.8.0(typescript@6.0.3) + tailwindcss: 4.2.2 - tailwindcss@3.4.17: + stylelint@17.8.0(typescript@6.0.3): dependencies: - '@alloc/quick-lru': 5.2.0 - arg: 5.0.2 - chokidar: 3.6.0 - didyoumean: 1.2.2 - dlv: 1.1.3 - fast-glob: 3.3.2 - glob-parent: 6.0.2 - is-glob: 4.0.3 - jiti: 1.21.6 - lilconfig: 3.1.3 + '@csstools/css-calc': 3.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) + '@csstools/css-syntax-patches-for-csstree': 1.1.3(css-tree@3.2.1) + '@csstools/css-tokenizer': 4.0.0 + '@csstools/media-query-list-parser': 5.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/selector-resolve-nested': 4.0.0(postcss-selector-parser@7.1.1) + '@csstools/selector-specificity': 6.0.0(postcss-selector-parser@7.1.1) + colord: 2.9.3 + cosmiconfig: 9.0.1(typescript@6.0.3) + css-functions-list: 3.3.3 + css-tree: 3.2.1 + debug: 4.4.3 + fast-glob: 3.3.3 + fastest-levenshtein: 1.0.16 + file-entry-cache: 11.1.2 + global-modules: 2.0.0 + globby: 16.2.0 + globjoin: 0.1.4 + html-tags: 5.1.0 + ignore: 7.0.5 + import-meta-resolve: 4.2.0 + is-plain-object: 5.0.0 + mathml-tag-names: 4.0.0 + meow: 14.1.0 micromatch: 4.0.8 normalize-path: 3.0.0 - object-hash: 3.0.0 picocolors: 1.1.1 - postcss: 8.5.1 - postcss-import: 15.1.0(postcss@8.5.1) - postcss-js: 4.0.1(postcss@8.5.1) - postcss-load-config: 4.0.2(postcss@8.5.1) - postcss-nested: 6.2.0(postcss@8.5.1) - postcss-selector-parser: 6.1.2 - resolve: 1.22.8 - sucrase: 3.35.0 + postcss: 8.5.10 + postcss-safe-parser: 7.0.1(postcss@8.5.10) + postcss-selector-parser: 7.1.1 + postcss-value-parser: 4.2.0 + string-width: 8.2.0 + supports-hyperlinks: 4.4.0 + svg-tags: 1.0.0 + table: 6.9.0 + write-file-atomic: 7.0.1 transitivePeerDependencies: - - ts-node + - supports-color + - typescript + + super-regex@1.1.0: + dependencies: + function-timeout: 1.0.2 + make-asynchronous: 1.1.0 + time-span: 5.1.0 + + supports-color@10.2.2: {} + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-hyperlinks@3.2.0: + dependencies: + has-flag: 4.0.0 + supports-color: 7.2.0 + + supports-hyperlinks@4.4.0: + dependencies: + has-flag: 5.0.1 + supports-color: 10.2.2 + + supports-preserve-symlinks-flag@1.0.0: {} + + svg-tags@1.0.0: {} + + synckit@0.11.12: + dependencies: + '@pkgr/core': 0.2.9 + + table@6.9.0: + dependencies: + ajv: 8.18.0 + lodash.truncate: 4.4.2 + slice-ansi: 4.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + tagged-tag@1.0.0: {} + + tailwind-api-utils@1.0.3(tailwindcss@4.2.2): + dependencies: + enhanced-resolve: 5.20.1 + jiti: 2.6.1 + local-pkg: 1.1.2 + tailwindcss: 4.2.2 + + tailwind-merge@3.5.0: {} + + tailwindcss@4.2.2: {} + + tapable@2.3.2: {} + + temp-dir@3.0.0: {} + + tempy@3.2.0: + dependencies: + is-stream: 3.0.0 + temp-dir: 3.0.0 + type-fest: 2.19.0 + unique-string: 3.0.0 thenify-all@1.6.0: dependencies: @@ -5375,182 +10506,345 @@ snapshots: dependencies: any-promise: 1.3.0 - tiny-case@1.0.3: {} + thread-stream@3.1.0: + dependencies: + real-require: 0.2.0 + + through2@2.0.5: + dependencies: + readable-stream: 2.3.8 + xtend: 4.0.2 + + through@2.3.8: {} + + time-span@5.1.0: + dependencies: + convert-hrtime: 5.0.0 + + tiny-invariant@1.3.3: {} + + tinyexec@1.1.1: {} + + tinyglobby@0.2.16: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + + tldts-core@7.0.28: {} + + tldts@7.0.28: + dependencies: + tldts-core: 7.0.28 - tiny-warning@1.0.3: {} + tmp@0.2.5: {} to-regex-range@5.0.1: dependencies: is-number: 7.0.0 - toposort@2.0.2: {} + toidentifier@1.0.1: {} + + tough-cookie@6.0.1: + dependencies: + tldts: 7.0.28 + + traverse@0.6.8: {} + + ts-api-utils@2.5.0(typescript@6.0.3): + dependencies: + typescript: 6.0.3 + + ts-morph@26.0.0: + dependencies: + '@ts-morph/common': 0.27.0 + code-block-writer: 13.0.3 - ts-api-utils@2.0.1(typescript@5.7.3): + tsconfig-paths@4.2.0: dependencies: - typescript: 5.7.3 + json5: 2.2.3 + minimist: 1.2.8 + strip-bom: 3.0.0 - ts-interface-checker@0.1.13: {} + tslib@2.8.1: {} + + tsx@4.21.0: + dependencies: + esbuild: 0.27.7 + get-tsconfig: 4.14.0 + optionalDependencies: + fsevents: 2.3.3 - tslib@2.5.3: {} + tunnel@0.0.6: {} - turbo-stream@2.4.0: {} + tw-animate-css@1.4.0: {} type-check@0.4.0: dependencies: prelude-ls: 1.2.1 + type-fest@1.4.0: {} + type-fest@2.19.0: {} - typed-array-buffer@1.0.2: + type-fest@3.13.1: {} + + type-fest@4.41.0: {} + + type-fest@5.6.0: dependencies: - call-bind: 1.0.7 - es-errors: 1.3.0 - is-typed-array: 1.1.13 + tagged-tag: 1.0.0 + + type-is@2.0.1: + dependencies: + content-type: 1.0.5 + media-typer: 1.1.0 + mime-types: 3.0.2 typed-array-buffer@1.0.3: dependencies: - call-bound: 1.0.3 + call-bound: 1.0.4 es-errors: 1.3.0 is-typed-array: 1.1.15 - typed-array-byte-length@1.0.1: - dependencies: - call-bind: 1.0.7 - for-each: 0.3.3 - gopd: 1.2.0 - has-proto: 1.0.3 - is-typed-array: 1.1.13 - typed-array-byte-length@1.0.3: dependencies: - call-bind: 1.0.8 - for-each: 0.3.3 + call-bind: 1.0.9 + for-each: 0.3.5 gopd: 1.2.0 has-proto: 1.2.0 is-typed-array: 1.1.15 - typed-array-byte-offset@1.0.2: - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.7 - for-each: 0.3.3 - gopd: 1.2.0 - has-proto: 1.0.3 - is-typed-array: 1.1.13 - typed-array-byte-offset@1.0.4: dependencies: available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - for-each: 0.3.3 + call-bind: 1.0.9 + for-each: 0.3.5 gopd: 1.2.0 has-proto: 1.2.0 is-typed-array: 1.1.15 reflect.getprototypeof: 1.0.10 - typed-array-length@1.0.6: - dependencies: - call-bind: 1.0.7 - for-each: 0.3.3 - gopd: 1.2.0 - has-proto: 1.0.3 - is-typed-array: 1.1.13 - possible-typed-array-names: 1.0.0 - typed-array-length@1.0.7: dependencies: - call-bind: 1.0.8 - for-each: 0.3.3 + call-bind: 1.0.9 + for-each: 0.3.5 gopd: 1.2.0 is-typed-array: 1.1.15 - possible-typed-array-names: 1.0.0 + possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typescript-eslint@8.23.0(eslint@9.19.0(jiti@1.21.6))(typescript@5.7.3): + typedarray@0.0.6: {} + + typescript-eslint@8.58.2(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.23.0(@typescript-eslint/parser@8.23.0(eslint@9.19.0(jiti@1.21.6))(typescript@5.7.3))(eslint@9.19.0(jiti@1.21.6))(typescript@5.7.3) - '@typescript-eslint/parser': 8.23.0(eslint@9.19.0(jiti@1.21.6))(typescript@5.7.3) - '@typescript-eslint/utils': 8.23.0(eslint@9.19.0(jiti@1.21.6))(typescript@5.7.3) - eslint: 9.19.0(jiti@1.21.6) - typescript: 5.7.3 + '@typescript-eslint/eslint-plugin': 8.58.2(@typescript-eslint/parser@8.58.2(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3))(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3) + '@typescript-eslint/parser': 8.58.2(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3) + '@typescript-eslint/typescript-estree': 8.58.2(typescript@6.0.3) + '@typescript-eslint/utils': 8.58.2(eslint@9.39.4(jiti@2.6.1))(typescript@6.0.3) + eslint: 9.39.4(jiti@2.6.1) + typescript: 6.0.3 transitivePeerDependencies: - supports-color - typescript@5.7.3: {} + typescript@6.0.3: {} - unbox-primitive@1.0.2: - dependencies: - call-bind: 1.0.7 - has-bigints: 1.0.2 - has-symbols: 1.1.0 - which-boxed-primitive: 1.0.2 + ufo@1.6.3: {} + + uglify-js@3.19.3: + optional: true + + uhyphen@0.2.0: {} unbox-primitive@1.1.0: dependencies: - call-bound: 1.0.3 - has-bigints: 1.0.2 + call-bound: 1.0.4 + has-bigints: 1.1.0 has-symbols: 1.1.0 which-boxed-primitive: 1.1.1 - undici-types@6.20.0: {} + undici-types@7.16.0: {} + + undici@6.25.0: {} + + undici@7.25.0: {} + + unicode-emoji-modifier-base@1.0.0: {} + + unicorn-magic@0.1.0: {} + + unicorn-magic@0.3.0: {} + + unicorn-magic@0.4.0: {} + + unimport@6.1.0: + dependencies: + acorn: 8.16.0 + escape-string-regexp: 5.0.0 + estree-walker: 3.0.3 + local-pkg: 1.1.2 + magic-string: 0.30.21 + mlly: 1.8.2 + pathe: 2.0.3 + picomatch: 4.0.4 + pkg-types: 2.3.0 + scule: 1.3.0 + strip-literal: 3.1.0 + tinyglobby: 0.2.16 + unplugin: 3.0.0 + unplugin-utils: 0.3.1 + + unique-string@3.0.0: + dependencies: + crypto-random-string: 4.0.0 + + universal-user-agent@7.0.3: {} universalify@2.0.1: {} - update-browserslist-db@1.1.0(browserslist@4.23.3): + unpipe@1.0.0: {} + + unplugin-utils@0.3.1: dependencies: - browserslist: 4.23.3 - escalade: 3.2.0 - picocolors: 1.1.1 + pathe: 2.0.3 + picomatch: 4.0.4 + + unplugin@2.3.11: + dependencies: + '@jridgewell/remapping': 2.3.5 + acorn: 8.16.0 + picomatch: 4.0.4 + webpack-virtual-modules: 0.6.2 + + unplugin@3.0.0: + dependencies: + '@jridgewell/remapping': 2.3.5 + picomatch: 4.0.4 + webpack-virtual-modules: 0.6.2 - update-browserslist-db@1.1.1(browserslist@4.24.2): + until-async@3.0.2: {} + + update-browserslist-db@1.2.3(browserslist@4.28.2): dependencies: - browserslist: 4.24.2 + browserslist: 4.28.2 escalade: 3.2.0 picocolors: 1.1.1 + update-notifier@7.3.1: + dependencies: + boxen: 8.0.1 + chalk: 5.6.2 + configstore: 7.1.0 + is-in-ci: 1.0.0 + is-installed-globally: 1.0.0 + is-npm: 6.1.0 + latest-version: 9.0.0 + pupa: 3.3.0 + semver: 7.7.4 + xdg-basedir: 5.1.0 + uri-js@4.4.1: dependencies: - punycode: 2.3.0 + punycode: 2.3.1 + + url-join@5.0.0: {} + + use-sync-external-store@1.6.0(react@19.2.5): + dependencies: + react: 19.2.5 - use-isomorphic-layout-effect@1.2.0(@types/react@19.0.8)(react@19.0.0): + usehooks-ts@3.1.1(react@19.2.5): dependencies: - react: 19.0.0 - optionalDependencies: - '@types/react': 19.0.8 + lodash.debounce: 4.0.8 + react: 19.2.5 util-deprecate@1.0.2: {} - vite-plugin-static-copy@2.2.0(vite@6.1.0(@types/node@22.13.1)(jiti@1.21.6)(yaml@2.6.1)): - dependencies: - chokidar: 3.5.3 - fast-glob: 3.3.2 - fs-extra: 11.2.0 - picocolors: 1.1.1 - vite: 6.1.0(@types/node@22.13.1)(jiti@1.21.6)(yaml@2.6.1) + uuid@8.3.2: {} - vite-plugin-zip-pack@1.2.4(vite@6.1.0(@types/node@22.13.1)(jiti@1.21.6)(yaml@2.6.1)): + validate-npm-package-license@3.0.4: dependencies: - jszip: 3.10.1 - vite: 6.1.0(@types/node@22.13.1)(jiti@1.21.6)(yaml@2.6.1) + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + + validate-npm-package-name@7.0.2: {} + + vary@1.1.2: {} - vite@6.1.0(@types/node@22.13.1)(jiti@1.21.6)(yaml@2.6.1): + vite-node@6.0.0(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.7.1): dependencies: - esbuild: 0.24.2 - postcss: 8.5.1 - rollup: 4.34.3 + cac: 7.0.0 + es-module-lexer: 2.0.0 + obug: 2.1.1 + pathe: 2.0.3 + vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.7.1) + transitivePeerDependencies: + - '@types/node' + - '@vitejs/devtools' + - esbuild + - jiti + - less + - sass + - sass-embedded + - stylus + - sugarss + - terser + - tsx + - yaml + + vite@8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.7.1): + dependencies: + lightningcss: 1.32.0 + picomatch: 4.0.4 + postcss: 8.5.10 + rolldown: 1.0.0-rc.15 + tinyglobby: 0.2.16 optionalDependencies: - '@types/node': 22.13.1 + '@types/node': 24.12.2 + esbuild: 0.27.7 fsevents: 2.3.3 - jiti: 1.21.6 - yaml: 2.6.1 + jiti: 2.6.1 + tsx: 4.21.0 + yaml: 2.7.1 - which-boxed-primitive@1.0.2: + watchpack@2.4.4: dependencies: - is-bigint: 1.0.4 - is-boolean-object: 1.1.2 - is-number-object: 1.0.7 - is-string: 1.0.7 - is-symbol: 1.0.4 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + + web-ext-run@0.2.4: + dependencies: + '@babel/runtime': 7.28.2 + '@devicefarmer/adbkit': 3.3.8 + chrome-launcher: 1.2.0 + debounce: 1.2.1 + es6-error: 4.1.1 + firefox-profile: 4.7.0 + fx-runner: 1.4.0 + multimatch: 6.0.0 + node-notifier: 10.0.1 + parse-json: 7.1.1 + pino: 9.7.0 + promise-toolbox: 0.21.0 + set-value: 4.1.0 + source-map-support: 0.5.21 + strip-bom: 5.0.0 + strip-json-comments: 5.0.2 + tmp: 0.2.5 + update-notifier: 7.3.1 + watchpack: 2.4.4 + zip-dir: 2.0.0 + transitivePeerDependencies: + - supports-color + + web-streams-polyfill@3.3.3: {} + + web-worker@1.5.0: {} + + webpack-virtual-modules@0.6.2: {} + + when-exit@2.1.5: {} + + when@3.7.7: {} which-boxed-primitive@1.1.1: dependencies: @@ -5562,19 +10856,19 @@ snapshots: which-builtin-type@1.2.1: dependencies: - call-bound: 1.0.3 + call-bound: 1.0.4 function.prototype.name: 1.1.8 has-tostringtag: 1.0.2 - is-async-function: 2.0.0 + is-async-function: 2.1.1 is-date-object: 1.1.0 is-finalizationregistry: 1.1.1 - is-generator-function: 1.0.10 + is-generator-function: 1.1.2 is-regex: 1.2.1 is-weakref: 1.1.1 isarray: 2.0.5 which-boxed-primitive: 1.1.1 which-collection: 1.0.2 - which-typed-array: 1.1.18 + which-typed-array: 1.1.20 which-collection@1.0.2: dependencies: @@ -5583,50 +10877,208 @@ snapshots: is-weakmap: 2.0.2 is-weakset: 2.0.4 - which-typed-array@1.1.15: + which-typed-array@1.1.20: dependencies: available-typed-arrays: 1.0.7 - call-bind: 1.0.7 - for-each: 0.3.3 + call-bind: 1.0.9 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 gopd: 1.2.0 has-tostringtag: 1.0.2 - which-typed-array@1.1.18: + which@1.2.4: dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - call-bound: 1.0.3 - for-each: 0.3.3 - gopd: 1.2.0 - has-tostringtag: 1.0.2 + is-absolute: 0.1.7 + isexe: 1.1.2 + + which@1.3.1: + dependencies: + isexe: 2.0.0 which@2.0.2: dependencies: isexe: 2.0.0 + which@4.0.0: + dependencies: + isexe: 3.1.5 + + widest-line@5.0.0: + dependencies: + string-width: 7.2.0 + + winreg@0.0.12: {} + + word-wrap@1.2.5: {} + + wordwrap@1.0.0: {} + + wrap-ansi@10.0.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 8.2.0 + strip-ansi: 7.2.0 + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 string-width: 4.2.3 strip-ansi: 6.0.1 - wrap-ansi@8.1.0: + wrap-ansi@9.0.2: + dependencies: + ansi-styles: 6.2.3 + string-width: 7.2.0 + strip-ansi: 7.2.0 + + wrappy@1.0.2: {} + + write-file-atomic@7.0.1: + dependencies: + signal-exit: 4.1.0 + + wsl-utils@0.3.1: + dependencies: + is-wsl: 3.1.1 + powershell-utils: 0.1.0 + + wxt@0.20.25(@types/node@24.12.2)(eslint@9.39.4(jiti@2.6.1))(jiti@2.6.1)(rollup@4.59.0)(tsx@4.21.0)(yaml@2.7.1): + dependencies: + '@1natsu/wait-element': 4.2.0 + '@aklinker1/rollup-plugin-visualizer': 5.12.0(rollup@4.59.0) + '@webext-core/fake-browser': 1.3.4 + '@webext-core/isolated-element': 1.1.5 + '@webext-core/match-patterns': 1.0.3 + '@wxt-dev/browser': 0.1.40 + '@wxt-dev/storage': 1.2.8 + async-mutex: 0.5.0 + c12: 3.3.4(magicast@0.5.2) + cac: 7.0.0 + chokidar: 5.0.0 + ci-info: 4.4.0 + consola: 3.4.2 + defu: 6.1.7 + dotenv-expand: 12.0.3 + esbuild: 0.27.7 + filesize: 11.0.15 + get-port-please: 3.2.0 + giget: 3.2.0 + hookable: 6.1.1 + import-meta-resolve: 4.2.0 + is-wsl: 3.1.1 + json5: 2.2.3 + jszip: 3.10.1 + linkedom: 0.18.12 + magicast: 0.5.2 + nano-spawn: 2.1.0 + nanospinner: 1.2.2 + normalize-path: 3.0.0 + nypm: 0.6.5 + ohash: 2.0.11 + open: 11.0.0 + perfect-debounce: 2.1.0 + picomatch: 4.0.4 + prompts: 2.4.2 + publish-browser-extension: 4.0.5 + scule: 1.3.0 + tinyglobby: 0.2.16 + unimport: 6.1.0 + vite: 8.0.8(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.7.1) + vite-node: 6.0.0(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.7.1) + web-ext-run: 0.2.4 + optionalDependencies: + eslint: 9.39.4(jiti@2.6.1) + transitivePeerDependencies: + - '@types/node' + - '@vitejs/devtools' + - canvas + - jiti + - less + - rollup + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + xdg-basedir@5.1.0: {} + + xml2js@0.6.2: dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 + sax: 1.6.0 + xmlbuilder: 11.0.1 + + xmlbuilder@11.0.1: {} + + xtend@4.0.2: {} + + y18n@5.0.8: {} yallist@3.1.1: {} - yaml@1.10.2: {} + yaml@2.7.1: + optional: true + + yargs-parser@20.2.9: {} + + yargs-parser@21.1.1: {} + + yargs-parser@22.0.0: {} + + yargs@16.2.0: + dependencies: + cliui: 7.0.4 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.9 + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 - yaml@2.6.1: {} + yargs@18.0.0: + dependencies: + cliui: 9.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + string-width: 7.2.0 + y18n: 5.0.8 + yargs-parser: 22.0.0 yocto-queue@0.1.0: {} - yup@1.6.1: + yocto-spinner@1.1.0: dependencies: - property-expr: 2.0.5 - tiny-case: 1.0.3 - toposort: 2.0.2 - type-fest: 2.19.0 + yoctocolors: 2.1.2 + + yoctocolors@2.1.2: {} + + zip-dir@2.0.0: + dependencies: + async: 3.2.6 + jszip: 3.10.1 + + zod-to-json-schema@3.25.2(zod@3.25.76): + dependencies: + zod: 3.25.76 + + zod-validation-error@4.0.2(zod@4.3.6): + dependencies: + zod: 4.3.6 + + zod@3.25.76: {} + + zod@4.3.6: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 00000000..0cbdab67 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,8 @@ +ignoredBuiltDependencies: + - msw + - spawn-sync +minimumReleaseAge: 1440 +onlyBuiltDependencies: + - "@tailwindcss/oxide" + - esbuild + - sharp diff --git a/postcss.config.cjs b/postcss.config.cjs deleted file mode 100644 index 33ad091d..00000000 --- a/postcss.config.cjs +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -} diff --git a/public/_locales/de/messages.json b/public/_locales/de/messages.json index 131b3c43..745ce1d0 100644 --- a/public/_locales/de/messages.json +++ b/public/_locales/de/messages.json @@ -6,5 +6,45 @@ "extDesc": { "message": "Start-/Stoppuhr fΓΌr Redmine", "description": "Extension description" + }, + "screenshotIssuesTitle": { + "message": "Aufgaben im Überblick", + "description": "Store screenshot headline for issues page" + }, + "screenshotIssuesSubtitle": { + "message": "Alle zugewiesenen Redmine-Aufgaben auf einen Blick", + "description": "Store screenshot subtitle for issues page" + }, + "screenshotTimersTitle": { + "message": "Timer starten & verwalten", + "description": "Store screenshot headline for timers page" + }, + "screenshotTimersSubtitle": { + "message": "Ein-Klick-Timer fΓΌr jede Aufgabe", + "description": "Store screenshot subtitle for timers page" + }, + "screenshotTimeEntriesTitle": { + "message": "ZeiteintrΓ€ge im Blick", + "description": "Store screenshot headline for time entries" + }, + "screenshotTimeEntriesSubtitle": { + "message": "WΓΆchentliche Übersicht aller erfassten Stunden", + "description": "Store screenshot subtitle for time entries" + }, + "screenshotManageIssuesTitle": { + "message": "Aufgaben verwalten", + "description": "Store screenshot headline for manage issues" + }, + "screenshotManageIssuesSubtitle": { + "message": "Neue Aufgaben anlegen und bestehende bearbeiten", + "description": "Store screenshot subtitle for manage issues" + }, + "screenshotSettingsTitle": { + "message": "Einfache Einrichtung", + "description": "Store screenshot headline for settings" + }, + "screenshotSettingsSubtitle": { + "message": "Mit beliebiger Redmine-Instanz verbinden und individuell anpassen", + "description": "Store screenshot subtitle for settings" } } diff --git a/public/_locales/en/messages.json b/public/_locales/en/messages.json index 7e5eafa6..70c49535 100644 --- a/public/_locales/en/messages.json +++ b/public/_locales/en/messages.json @@ -6,5 +6,45 @@ "extDesc": { "message": "Start-stop timer for Redmine", "description": "Extension description" + }, + "screenshotIssuesTitle": { + "message": "Track your issues", + "description": "Store screenshot headline for issues page" + }, + "screenshotIssuesSubtitle": { + "message": "View and manage all your assigned Redmine issues", + "description": "Store screenshot subtitle for issues page" + }, + "screenshotTimersTitle": { + "message": "Start & manage timers", + "description": "Store screenshot headline for timers page" + }, + "screenshotTimersSubtitle": { + "message": "One-click timer for any issue", + "description": "Store screenshot subtitle for timers page" + }, + "screenshotTimeEntriesTitle": { + "message": "Review time entries", + "description": "Store screenshot headline for time entries" + }, + "screenshotTimeEntriesSubtitle": { + "message": "Weekly overview of all your tracked hours", + "description": "Store screenshot subtitle for time entries" + }, + "screenshotManageIssuesTitle": { + "message": "Create & edit issues", + "description": "Store screenshot headline for manage issues" + }, + "screenshotManageIssuesSubtitle": { + "message": "Create new issues and edit existing ones", + "description": "Store screenshot subtitle for manage issues" + }, + "screenshotSettingsTitle": { + "message": "Easy setup", + "description": "Store screenshot headline for settings" + }, + "screenshotSettingsSubtitle": { + "message": "Connect to any Redmine instance and customize to your workflow", + "description": "Store screenshot subtitle for settings" } } diff --git a/public/_locales/fr/messages.json b/public/_locales/fr/messages.json index 7e5eafa6..70c49535 100644 --- a/public/_locales/fr/messages.json +++ b/public/_locales/fr/messages.json @@ -6,5 +6,45 @@ "extDesc": { "message": "Start-stop timer for Redmine", "description": "Extension description" + }, + "screenshotIssuesTitle": { + "message": "Track your issues", + "description": "Store screenshot headline for issues page" + }, + "screenshotIssuesSubtitle": { + "message": "View and manage all your assigned Redmine issues", + "description": "Store screenshot subtitle for issues page" + }, + "screenshotTimersTitle": { + "message": "Start & manage timers", + "description": "Store screenshot headline for timers page" + }, + "screenshotTimersSubtitle": { + "message": "One-click timer for any issue", + "description": "Store screenshot subtitle for timers page" + }, + "screenshotTimeEntriesTitle": { + "message": "Review time entries", + "description": "Store screenshot headline for time entries" + }, + "screenshotTimeEntriesSubtitle": { + "message": "Weekly overview of all your tracked hours", + "description": "Store screenshot subtitle for time entries" + }, + "screenshotManageIssuesTitle": { + "message": "Create & edit issues", + "description": "Store screenshot headline for manage issues" + }, + "screenshotManageIssuesSubtitle": { + "message": "Create new issues and edit existing ones", + "description": "Store screenshot subtitle for manage issues" + }, + "screenshotSettingsTitle": { + "message": "Easy setup", + "description": "Store screenshot headline for settings" + }, + "screenshotSettingsSubtitle": { + "message": "Connect to any Redmine instance and customize to your workflow", + "description": "Store screenshot subtitle for settings" } } diff --git a/public/_locales/ru/messages.json b/public/_locales/ru/messages.json index 7e5eafa6..70c49535 100644 --- a/public/_locales/ru/messages.json +++ b/public/_locales/ru/messages.json @@ -6,5 +6,45 @@ "extDesc": { "message": "Start-stop timer for Redmine", "description": "Extension description" + }, + "screenshotIssuesTitle": { + "message": "Track your issues", + "description": "Store screenshot headline for issues page" + }, + "screenshotIssuesSubtitle": { + "message": "View and manage all your assigned Redmine issues", + "description": "Store screenshot subtitle for issues page" + }, + "screenshotTimersTitle": { + "message": "Start & manage timers", + "description": "Store screenshot headline for timers page" + }, + "screenshotTimersSubtitle": { + "message": "One-click timer for any issue", + "description": "Store screenshot subtitle for timers page" + }, + "screenshotTimeEntriesTitle": { + "message": "Review time entries", + "description": "Store screenshot headline for time entries" + }, + "screenshotTimeEntriesSubtitle": { + "message": "Weekly overview of all your tracked hours", + "description": "Store screenshot subtitle for time entries" + }, + "screenshotManageIssuesTitle": { + "message": "Create & edit issues", + "description": "Store screenshot headline for manage issues" + }, + "screenshotManageIssuesSubtitle": { + "message": "Create new issues and edit existing ones", + "description": "Store screenshot subtitle for manage issues" + }, + "screenshotSettingsTitle": { + "message": "Easy setup", + "description": "Store screenshot headline for settings" + }, + "screenshotSettingsSubtitle": { + "message": "Connect to any Redmine instance and customize to your workflow", + "description": "Store screenshot subtitle for settings" } } diff --git a/public/logo128.png b/public/icon/128.png similarity index 100% rename from public/logo128.png rename to public/icon/128.png diff --git a/public/logo16.png b/public/icon/16.png similarity index 100% rename from public/logo16.png rename to public/icon/16.png diff --git a/public/logo48.png b/public/icon/48.png similarity index 100% rename from public/logo48.png rename to public/icon/48.png diff --git a/release.config.mjs b/release.config.mjs new file mode 100644 index 00000000..1442c3ec --- /dev/null +++ b/release.config.mjs @@ -0,0 +1,65 @@ +/** + * @type {import('semantic-release').GlobalConfig} + */ +export default { + branches: ["main", { name: "beta", prerelease: true }, { name: "alpha", prerelease: true }, { name: "canary", prerelease: true }], + plugins: [ + [ + "@semantic-release/commit-analyzer", + { + preset: "conventionalcommits", + }, + ], + [ + "@semantic-release/release-notes-generator", + { + preset: "conventionalcommits", + presetConfig: { + types: [ + { type: "chore", scope: "release", hidden: true }, + { type: "feat", section: "πŸš€ Features" }, + { type: "fix", section: "🩹 Fixes" }, + { type: "perf", section: "πŸ”₯ Performance" }, + { type: "chore", section: "🏑 Chore" }, + { type: "refactor", section: "πŸ› οΈ Refactors" }, + { type: "docs", section: "πŸ“– Documentation" }, + { type: "test", section: "πŸ§ͺ Tests" }, + { type: "build", section: "πŸ“¦ Builds" }, + { type: "ci", section: "⚑CI" }, + ], + }, + }, + ], + [ + "@semantic-release/npm", + { + npmPublish: false, + }, + ], + "@semantic-release/changelog", + "@semantic-release/git", + [ + "@semantic-release/github", + { + releaseBodyTemplate: ` +<% if (nextRelease.channel) { %> +[![Install-Button-Chrome]][Install-Link-Chrome] + +[Install-Button-Chrome]: https://img.shields.io/badge/INSTALL-PRE--RELEASE-71b500?style=for-the-badge&logoColor=white&logo=google-chrome +[Install-Link-Chrome]: https://chromewebstore.google.com/detail/redmine-time-tracking/adgcdimdkkaddeopcabokepmaihfhklb "Open in chrome web store" +<% } else { %> +[![Install-Button-Chrome]][Install-Link-Chrome] +[![Install-Button-Firefox]][Install-Link-Firefox] + +[Install-Button-Chrome]: https://img.shields.io/badge/Install-Chrome-71b500?style=for-the-badge&logoColor=white&logo=google-chrome +[Install-Link-Chrome]: https://chrome.google.com/webstore/detail/redmine-time-tracking/ldcanhhkffokndenejhafhlkapflgcjg "Open in chrome web store" +[Install-Button-Firefox]: https://img.shields.io/badge/Install-Firefox-71b500?style=for-the-badge&logoColor=white&logo=firefox-browser +[Install-Link-Firefox]: https://addons.mozilla.org/de/firefox/addon/redmine-time-tracking "Open in firefox add-on store" +<% } %> + +<%= nextRelease.notes %> +`, + }, + ], + ], +}; diff --git a/screenshots/banner.png b/screenshots/banner.png new file mode 100644 index 00000000..591c21d4 Binary files /dev/null and b/screenshots/banner.png differ diff --git a/screenshots/chrome-template-dark.png b/screenshots/chrome-template-dark.png deleted file mode 100644 index cfb542c2..00000000 Binary files a/screenshots/chrome-template-dark.png and /dev/null differ diff --git a/screenshots/chrome-template-light.png b/screenshots/chrome-template-light.png deleted file mode 100644 index a21d0954..00000000 Binary files a/screenshots/chrome-template-light.png and /dev/null differ diff --git a/screenshots/chrome/de/1.png b/screenshots/chrome/de/1.png new file mode 100644 index 00000000..c51ffdc9 Binary files /dev/null and b/screenshots/chrome/de/1.png differ diff --git a/screenshots/chrome/de/2.png b/screenshots/chrome/de/2.png new file mode 100644 index 00000000..7ac26a9f Binary files /dev/null and b/screenshots/chrome/de/2.png differ diff --git a/screenshots/chrome/de/3.png b/screenshots/chrome/de/3.png new file mode 100644 index 00000000..b8a3373b Binary files /dev/null and b/screenshots/chrome/de/3.png differ diff --git a/screenshots/chrome/de/4.png b/screenshots/chrome/de/4.png new file mode 100644 index 00000000..db527e38 Binary files /dev/null and b/screenshots/chrome/de/4.png differ diff --git a/screenshots/chrome/de/5.png b/screenshots/chrome/de/5.png new file mode 100644 index 00000000..54c4aa86 Binary files /dev/null and b/screenshots/chrome/de/5.png differ diff --git a/screenshots/chrome/en/1.png b/screenshots/chrome/en/1.png new file mode 100644 index 00000000..a8ffcfb4 Binary files /dev/null and b/screenshots/chrome/en/1.png differ diff --git a/screenshots/chrome/en/2.png b/screenshots/chrome/en/2.png new file mode 100644 index 00000000..d39a608d Binary files /dev/null and b/screenshots/chrome/en/2.png differ diff --git a/screenshots/chrome/en/3.png b/screenshots/chrome/en/3.png new file mode 100644 index 00000000..94195890 Binary files /dev/null and b/screenshots/chrome/en/3.png differ diff --git a/screenshots/chrome/en/4.png b/screenshots/chrome/en/4.png new file mode 100644 index 00000000..d060ba88 Binary files /dev/null and b/screenshots/chrome/en/4.png differ diff --git a/screenshots/chrome/en/5.png b/screenshots/chrome/en/5.png new file mode 100644 index 00000000..c22a59b5 Binary files /dev/null and b/screenshots/chrome/en/5.png differ diff --git a/screenshots/chrome/fr/1.png b/screenshots/chrome/fr/1.png new file mode 100644 index 00000000..2cc874c2 Binary files /dev/null and b/screenshots/chrome/fr/1.png differ diff --git a/screenshots/chrome/fr/2.png b/screenshots/chrome/fr/2.png new file mode 100644 index 00000000..af5e7e0b Binary files /dev/null and b/screenshots/chrome/fr/2.png differ diff --git a/screenshots/chrome/fr/3.png b/screenshots/chrome/fr/3.png new file mode 100644 index 00000000..40c5776a Binary files /dev/null and b/screenshots/chrome/fr/3.png differ diff --git a/screenshots/chrome/fr/4.png b/screenshots/chrome/fr/4.png new file mode 100644 index 00000000..3b482b61 Binary files /dev/null and b/screenshots/chrome/fr/4.png differ diff --git a/screenshots/chrome/fr/5.png b/screenshots/chrome/fr/5.png new file mode 100644 index 00000000..a00c2441 Binary files /dev/null and b/screenshots/chrome/fr/5.png differ diff --git a/screenshots/chrome/ru/1.png b/screenshots/chrome/ru/1.png new file mode 100644 index 00000000..ff5679fe Binary files /dev/null and b/screenshots/chrome/ru/1.png differ diff --git a/screenshots/chrome/ru/2.png b/screenshots/chrome/ru/2.png new file mode 100644 index 00000000..4c4f62f7 Binary files /dev/null and b/screenshots/chrome/ru/2.png differ diff --git a/screenshots/chrome/ru/3.png b/screenshots/chrome/ru/3.png new file mode 100644 index 00000000..99f320ce Binary files /dev/null and b/screenshots/chrome/ru/3.png differ diff --git a/screenshots/chrome/ru/4.png b/screenshots/chrome/ru/4.png new file mode 100644 index 00000000..81defa68 Binary files /dev/null and b/screenshots/chrome/ru/4.png differ diff --git a/screenshots/chrome/ru/5.png b/screenshots/chrome/ru/5.png new file mode 100644 index 00000000..f03ed2f5 Binary files /dev/null and b/screenshots/chrome/ru/5.png differ diff --git a/screenshots/chrome/thumbnail.png b/screenshots/chrome/thumbnail.png new file mode 100644 index 00000000..b103cd43 Binary files /dev/null and b/screenshots/chrome/thumbnail.png differ diff --git a/screenshots/de/dark/chrome-store/issues-add-spent-time.png b/screenshots/de/dark/chrome-store/issues-add-spent-time.png deleted file mode 100644 index 82f0282e..00000000 Binary files a/screenshots/de/dark/chrome-store/issues-add-spent-time.png and /dev/null differ diff --git a/screenshots/de/dark/chrome-store/issues-context-menu.png b/screenshots/de/dark/chrome-store/issues-context-menu.png deleted file mode 100644 index 14849ad1..00000000 Binary files a/screenshots/de/dark/chrome-store/issues-context-menu.png and /dev/null differ diff --git a/screenshots/de/dark/chrome-store/issues-search.png b/screenshots/de/dark/chrome-store/issues-search.png deleted file mode 100644 index dacbd503..00000000 Binary files a/screenshots/de/dark/chrome-store/issues-search.png and /dev/null differ diff --git a/screenshots/de/dark/chrome-store/issues.png b/screenshots/de/dark/chrome-store/issues.png deleted file mode 100644 index 7d212778..00000000 Binary files a/screenshots/de/dark/chrome-store/issues.png and /dev/null differ diff --git a/screenshots/de/dark/chrome-store/settings.png b/screenshots/de/dark/chrome-store/settings.png deleted file mode 100644 index 7c08f307..00000000 Binary files a/screenshots/de/dark/chrome-store/settings.png and /dev/null differ diff --git a/screenshots/de/dark/chrome-store/time.png b/screenshots/de/dark/chrome-store/time.png deleted file mode 100644 index 0fb8d466..00000000 Binary files a/screenshots/de/dark/chrome-store/time.png and /dev/null differ diff --git a/screenshots/de/dark/issues-add-spent-time.png b/screenshots/de/dark/issues-add-spent-time.png deleted file mode 100644 index 226c67bd..00000000 Binary files a/screenshots/de/dark/issues-add-spent-time.png and /dev/null differ diff --git a/screenshots/de/dark/issues-context-menu.png b/screenshots/de/dark/issues-context-menu.png deleted file mode 100644 index 2abb18ec..00000000 Binary files a/screenshots/de/dark/issues-context-menu.png and /dev/null differ diff --git a/screenshots/de/dark/issues-search.png b/screenshots/de/dark/issues-search.png deleted file mode 100644 index c9b23add..00000000 Binary files a/screenshots/de/dark/issues-search.png and /dev/null differ diff --git a/screenshots/de/dark/issues.png b/screenshots/de/dark/issues.png deleted file mode 100644 index 8170fba7..00000000 Binary files a/screenshots/de/dark/issues.png and /dev/null differ diff --git a/screenshots/de/dark/settings.png b/screenshots/de/dark/settings.png deleted file mode 100644 index 546a5700..00000000 Binary files a/screenshots/de/dark/settings.png and /dev/null differ diff --git a/screenshots/de/dark/time.png b/screenshots/de/dark/time.png deleted file mode 100644 index aa8f682c..00000000 Binary files a/screenshots/de/dark/time.png and /dev/null differ diff --git a/screenshots/de/light/chrome-store/issues-add-spent-time.png b/screenshots/de/light/chrome-store/issues-add-spent-time.png deleted file mode 100644 index 5eb5705b..00000000 Binary files a/screenshots/de/light/chrome-store/issues-add-spent-time.png and /dev/null differ diff --git a/screenshots/de/light/chrome-store/issues-context-menu.png b/screenshots/de/light/chrome-store/issues-context-menu.png deleted file mode 100644 index 1ab2d42b..00000000 Binary files a/screenshots/de/light/chrome-store/issues-context-menu.png and /dev/null differ diff --git a/screenshots/de/light/chrome-store/issues-search.png b/screenshots/de/light/chrome-store/issues-search.png deleted file mode 100644 index d3d1b5ee..00000000 Binary files a/screenshots/de/light/chrome-store/issues-search.png and /dev/null differ diff --git a/screenshots/de/light/chrome-store/issues.png b/screenshots/de/light/chrome-store/issues.png deleted file mode 100644 index 08c7d45e..00000000 Binary files a/screenshots/de/light/chrome-store/issues.png and /dev/null differ diff --git a/screenshots/de/light/chrome-store/settings.png b/screenshots/de/light/chrome-store/settings.png deleted file mode 100644 index 129d0782..00000000 Binary files a/screenshots/de/light/chrome-store/settings.png and /dev/null differ diff --git a/screenshots/de/light/chrome-store/time.png b/screenshots/de/light/chrome-store/time.png deleted file mode 100644 index 06b4083b..00000000 Binary files a/screenshots/de/light/chrome-store/time.png and /dev/null differ diff --git a/screenshots/de/light/issues-add-spent-time.png b/screenshots/de/light/issues-add-spent-time.png deleted file mode 100644 index ca4d1df2..00000000 Binary files a/screenshots/de/light/issues-add-spent-time.png and /dev/null differ diff --git a/screenshots/de/light/issues-context-menu.png b/screenshots/de/light/issues-context-menu.png deleted file mode 100644 index 484e7dc1..00000000 Binary files a/screenshots/de/light/issues-context-menu.png and /dev/null differ diff --git a/screenshots/de/light/issues-search.png b/screenshots/de/light/issues-search.png deleted file mode 100644 index 72e35aff..00000000 Binary files a/screenshots/de/light/issues-search.png and /dev/null differ diff --git a/screenshots/de/light/issues.png b/screenshots/de/light/issues.png deleted file mode 100644 index c8380644..00000000 Binary files a/screenshots/de/light/issues.png and /dev/null differ diff --git a/screenshots/de/light/settings.png b/screenshots/de/light/settings.png deleted file mode 100644 index aad08948..00000000 Binary files a/screenshots/de/light/settings.png and /dev/null differ diff --git a/screenshots/de/light/time.png b/screenshots/de/light/time.png deleted file mode 100644 index 91bf0071..00000000 Binary files a/screenshots/de/light/time.png and /dev/null differ diff --git a/screenshots/en/dark/chrome-store/issues-add-spent-time.png b/screenshots/en/dark/chrome-store/issues-add-spent-time.png deleted file mode 100644 index 88cfd34c..00000000 Binary files a/screenshots/en/dark/chrome-store/issues-add-spent-time.png and /dev/null differ diff --git a/screenshots/en/dark/chrome-store/issues-context-menu.png b/screenshots/en/dark/chrome-store/issues-context-menu.png deleted file mode 100644 index cb528da2..00000000 Binary files a/screenshots/en/dark/chrome-store/issues-context-menu.png and /dev/null differ diff --git a/screenshots/en/dark/chrome-store/issues-search.png b/screenshots/en/dark/chrome-store/issues-search.png deleted file mode 100644 index 63e66d68..00000000 Binary files a/screenshots/en/dark/chrome-store/issues-search.png and /dev/null differ diff --git a/screenshots/en/dark/chrome-store/issues.png b/screenshots/en/dark/chrome-store/issues.png deleted file mode 100644 index c0cdee19..00000000 Binary files a/screenshots/en/dark/chrome-store/issues.png and /dev/null differ diff --git a/screenshots/en/dark/chrome-store/settings.png b/screenshots/en/dark/chrome-store/settings.png deleted file mode 100644 index 20ab9bf5..00000000 Binary files a/screenshots/en/dark/chrome-store/settings.png and /dev/null differ diff --git a/screenshots/en/dark/chrome-store/time.png b/screenshots/en/dark/chrome-store/time.png deleted file mode 100644 index 2597b815..00000000 Binary files a/screenshots/en/dark/chrome-store/time.png and /dev/null differ diff --git a/screenshots/en/dark/issues-add-spent-time.png b/screenshots/en/dark/issues-add-spent-time.png deleted file mode 100644 index 1874efd5..00000000 Binary files a/screenshots/en/dark/issues-add-spent-time.png and /dev/null differ diff --git a/screenshots/en/dark/issues-context-menu.png b/screenshots/en/dark/issues-context-menu.png deleted file mode 100644 index 72fad441..00000000 Binary files a/screenshots/en/dark/issues-context-menu.png and /dev/null differ diff --git a/screenshots/en/dark/issues-search.png b/screenshots/en/dark/issues-search.png deleted file mode 100644 index 3ed21e5d..00000000 Binary files a/screenshots/en/dark/issues-search.png and /dev/null differ diff --git a/screenshots/en/dark/issues.png b/screenshots/en/dark/issues.png deleted file mode 100644 index 37a9818c..00000000 Binary files a/screenshots/en/dark/issues.png and /dev/null differ diff --git a/screenshots/en/dark/settings.png b/screenshots/en/dark/settings.png deleted file mode 100644 index 1ca5493d..00000000 Binary files a/screenshots/en/dark/settings.png and /dev/null differ diff --git a/screenshots/en/dark/time.png b/screenshots/en/dark/time.png deleted file mode 100644 index e94db3d7..00000000 Binary files a/screenshots/en/dark/time.png and /dev/null differ diff --git a/screenshots/en/light/chrome-store/issues-add-spent-time.png b/screenshots/en/light/chrome-store/issues-add-spent-time.png deleted file mode 100644 index 34ca3e7a..00000000 Binary files a/screenshots/en/light/chrome-store/issues-add-spent-time.png and /dev/null differ diff --git a/screenshots/en/light/chrome-store/issues-context-menu.png b/screenshots/en/light/chrome-store/issues-context-menu.png deleted file mode 100644 index b44e8146..00000000 Binary files a/screenshots/en/light/chrome-store/issues-context-menu.png and /dev/null differ diff --git a/screenshots/en/light/chrome-store/issues-search.png b/screenshots/en/light/chrome-store/issues-search.png deleted file mode 100644 index a11b0da9..00000000 Binary files a/screenshots/en/light/chrome-store/issues-search.png and /dev/null differ diff --git a/screenshots/en/light/chrome-store/issues.png b/screenshots/en/light/chrome-store/issues.png deleted file mode 100644 index f52bfea2..00000000 Binary files a/screenshots/en/light/chrome-store/issues.png and /dev/null differ diff --git a/screenshots/en/light/chrome-store/settings.png b/screenshots/en/light/chrome-store/settings.png deleted file mode 100644 index ed8ee2e4..00000000 Binary files a/screenshots/en/light/chrome-store/settings.png and /dev/null differ diff --git a/screenshots/en/light/chrome-store/time.png b/screenshots/en/light/chrome-store/time.png deleted file mode 100644 index f1679d5c..00000000 Binary files a/screenshots/en/light/chrome-store/time.png and /dev/null differ diff --git a/screenshots/en/light/issues-add-spent-time.png b/screenshots/en/light/issues-add-spent-time.png deleted file mode 100644 index 20776828..00000000 Binary files a/screenshots/en/light/issues-add-spent-time.png and /dev/null differ diff --git a/screenshots/en/light/issues-context-menu.png b/screenshots/en/light/issues-context-menu.png deleted file mode 100644 index 88d771e6..00000000 Binary files a/screenshots/en/light/issues-context-menu.png and /dev/null differ diff --git a/screenshots/en/light/issues-search.png b/screenshots/en/light/issues-search.png deleted file mode 100644 index e34d1046..00000000 Binary files a/screenshots/en/light/issues-search.png and /dev/null differ diff --git a/screenshots/en/light/issues.png b/screenshots/en/light/issues.png deleted file mode 100644 index 0765050d..00000000 Binary files a/screenshots/en/light/issues.png and /dev/null differ diff --git a/screenshots/en/light/settings.png b/screenshots/en/light/settings.png deleted file mode 100644 index caafa1c5..00000000 Binary files a/screenshots/en/light/settings.png and /dev/null differ diff --git a/screenshots/en/light/time.png b/screenshots/en/light/time.png deleted file mode 100644 index 8528ef9d..00000000 Binary files a/screenshots/en/light/time.png and /dev/null differ diff --git a/screenshots/generate-store-screenshots.ts b/screenshots/generate-store-screenshots.ts new file mode 100644 index 00000000..6ec114ca --- /dev/null +++ b/screenshots/generate-store-screenshots.ts @@ -0,0 +1,477 @@ +import fs from "fs"; +import path from "path"; +import sharp from "sharp"; + +const LANGUAGES = ["en", "de", "fr", "ru"] as const; +type Language = (typeof LANGUAGES)[number]; + +const SCREENSHOT_WIDTH = 1280; +const SCREENSHOT_HEIGHT = 800; +const THUMBNAIL_WIDTH = 440; +const THUMBNAIL_HEIGHT = 280; +const BANNER_WIDTH = 1280; +const BANNER_HEIGHT = 640; + +const POPUP_WIDTH = 320; +const POPUP_HEIGHT = 548; + +const RADIUS = 12; +const BORDER_BLUR = 18; +const BORDER_GRAD = ["#1e40af", "#3b82f6", "#93c5fd"]; + +const THEME = { + bgStart: "#0f172a", + bgEnd: "#1e293b", + accent: "#3b82f6", + accentGlow: "rgba(59, 130, 246, 0.15)", + text: "#f8fafc", + textSub: "#94a3b8", +}; + +interface Messages { + [key: string]: { message: string }; +} + +function loadMessages(locale: Language): Messages { + const filePath = path.join("public", "_locales", locale, "messages.json"); + return JSON.parse(fs.readFileSync(filePath, "utf-8")) as Messages; +} + +function getHeadline(titleKey: string, subtitleKey: string, messages: Messages): { title: string; subtitle: string } { + return { + title: messages[titleKey]?.message ?? titleKey, + subtitle: messages[subtitleKey]?.message ?? "", + }; +} + +function escapeXml(str: string): string { + return str.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'"); +} + +function popupPath(locale: Language, testFile: string, testName: string): string { + return path.join("tests", "screenshots", `Chrome-popup-dark-${locale}`, testFile, `${testName}.png`); +} + +function backgroundSvg(w: number, h: number): string { + return ` + + + + + + + + + + + + +`; +} + +function headlineSvg(w: number, h: number, title: string, subtitle: string, iconPath: string, options: { x: number; y: number; iconSize?: number; titleSize?: number; subtitleSize?: number }): string { + const iconSize = options.iconSize ?? 34; + const titleSize = options.titleSize ?? 38; + const subtitleSize = options.subtitleSize ?? 16; + const x = options.x; + const groupY = options.y; + const iconTextGap = 12; + const textX = x + iconSize + iconTextGap; + + const titleY = groupY + titleSize; + const capTop = titleY - Math.round(titleSize * 0.72); + const capHeight = Math.round(titleSize * 0.72); + const iconY = capTop + Math.round((capHeight - iconSize) / 2); + const subtitleY = titleY + subtitleSize + 10; + const lineY = subtitleY + subtitleSize + 6; + + return ` + + ${iconPath} + + + ${escapeXml(title)} + + + ${escapeXml(subtitle)} + + +`; +} + +function roundedMaskSvg(w: number, h: number, r: number): string { + return ` + +`; +} + +function borderGradDefs(id: string): string { + const [c0, c1, c2] = BORDER_GRAD; + return ` + + + + + + `; +} + +async function roundImage(inputPath: string, w: number, h: number, r: number): Promise { + const mask = Buffer.from(roundedMaskSvg(w, h, r)); + return sharp(inputPath) + .resize(w, h) + .composite([{ input: mask, blend: "dest-in" }]) + .png() + .toBuffer(); +} + +async function addScreenshotWithBorder(composites: sharp.OverlayOptions[], image: Buffer, top: number, left: number, imgW: number, imgH: number) { + const sw = 14; + const expand = sw / 2; + const glowSvg = Buffer.from( + ` + ${borderGradDefs("g")} + + ` + ); + const glow = await sharp(glowSvg).blur(BORDER_BLUR).png().toBuffer(); + + const crispSvg = Buffer.from( + ` + ${borderGradDefs("g")} + + ` + ); + + composites.push({ input: glow, top: 0, left: 0 }); + composites.push({ input: image, top, left }); + composites.push({ input: crispSvg, top: 0, left: 0 }); +} + +async function generateSinglePopup( + outputPath: string, + popup: { file: string; name: string }, + headline: { titleKey: string; subtitleKey: string; icon: string }, + locale: Language, + messages: Messages +): Promise { + const ppPath = popupPath(locale, popup.file, popup.name); + if (!fs.existsSync(ppPath)) { + console.warn(`\x1b[31m skip ${path.basename(outputPath)} β€” screenshot not found:\x1b[0m\n ${ppPath}`); + return false; + } + + const hl = getHeadline(headline.titleKey, headline.subtitleKey, messages); + const bg = Buffer.from(backgroundSvg(SCREENSHOT_WIDTH, SCREENSHOT_HEIGHT)); + const composites: sharp.OverlayOptions[] = []; + + const ppScale = 1.2; + const ppW = Math.round(POPUP_WIDTH * ppScale); + const ppH = Math.round(POPUP_HEIGHT * ppScale); + const ppLeft = SCREENSHOT_WIDTH - ppW - 140; + const ppTop = Math.round((SCREENSHOT_HEIGHT - ppH) / 2); + + const ppRounded = await roundImage(ppPath, ppW, ppH, RADIUS); + await addScreenshotWithBorder(composites, ppRounded, ppTop, ppLeft, ppW, ppH); + + composites.push({ + input: Buffer.from( + headlineSvg(SCREENSHOT_WIDTH, SCREENSHOT_HEIGHT, hl.title, hl.subtitle, headline.icon, { + x: 60, + y: Math.round(SCREENSHOT_HEIGHT / 2 - 90), + titleSize: 38, + subtitleSize: 16, + iconSize: 34, + }) + ), + top: 0, + left: 0, + }); + + await sharp(bg).composite(composites).png().toFile(outputPath); + console.log(`\x1b[32m created ${outputPath}\x1b[0m`); + return true; +} + +async function generateDualPopup( + outputPath: string, + popup1: { file: string; name: string }, + popup2: { file: string; name: string }, + headline: { titleKey: string; subtitleKey: string; icon: string }, + locale: Language, + messages: Messages +): Promise { + const p1Path = popupPath(locale, popup1.file, popup1.name); + const p2Path = popupPath(locale, popup2.file, popup2.name); + const missing = [p1Path, p2Path].filter((p) => !fs.existsSync(p)); + if (missing.length > 0) { + console.warn(`\x1b[31m skip ${path.basename(outputPath)} β€” screenshots not found:\x1b[0m\n${missing.map((p) => ` ${p}`).join("\n")}`); + return false; + } + + const hl = getHeadline(headline.titleKey, headline.subtitleKey, messages); + const bg = Buffer.from(backgroundSvg(SCREENSHOT_WIDTH, SCREENSHOT_HEIGHT)); + const composites: sharp.OverlayOptions[] = []; + + const ppScale = 0.95; + const ppW = Math.round(POPUP_WIDTH * ppScale); + const ppH = Math.round(POPUP_HEIGHT * ppScale); + const gap = 28; + const popupsLeft = SCREENSHOT_WIDTH - (ppW * 2 + gap) - 80; + const pp1Top = Math.round((SCREENSHOT_HEIGHT - ppH) / 2) - 20; + const pp2Top = pp1Top + 40; + + const [pp1Rounded, pp2Rounded] = await Promise.all([roundImage(p1Path, ppW, ppH, RADIUS), roundImage(p2Path, ppW, ppH, RADIUS)]); + await addScreenshotWithBorder(composites, pp1Rounded, pp1Top, popupsLeft, ppW, ppH); + await addScreenshotWithBorder(composites, pp2Rounded, pp2Top, popupsLeft + ppW + gap, ppW, ppH); + + composites.push({ + input: Buffer.from( + headlineSvg(SCREENSHOT_WIDTH, SCREENSHOT_HEIGHT, hl.title, hl.subtitle, headline.icon, { + x: 50, + y: Math.round(SCREENSHOT_HEIGHT / 2 - 90), + titleSize: 36, + subtitleSize: 15, + iconSize: 32, + }) + ), + top: 0, + left: 0, + }); + + await sharp(bg).composite(composites).png().toFile(outputPath); + console.log(`\x1b[32m created ${outputPath}\x1b[0m`); + return true; +} + +interface PromoImageOptions { + canvasWidth: number; + canvasHeight: number; + pad: number; + textAreaRight: number; + iconSize: number; + fontSize: number; + lineGap: number; + iconTextGap: number; + outputSize?: { width: number; height: number }; +} + +async function generatePromoImage(outputPath: string, locale: Language, messages: Messages, opts: PromoImageOptions): Promise { + const { canvasWidth: cW, canvasHeight: cH, pad: PAD, textAreaRight, iconSize, fontSize, lineGap, iconTextGap } = opts; + const scale = 2; + + const shotPaths = [ + popupPath(locale, "IssuesPage.spec.tsx", "Start-timer"), + popupPath(locale, "IssuesPage.spec.tsx", "Add-spent-time"), + popupPath(locale, "SettingsPage.spec.tsx", "Settings-page"), + ] as const; + + const missing = shotPaths.filter((p) => !fs.existsSync(p)); + if (missing.length > 0) { + console.warn(`\x1b[31m skip ${path.basename(outputPath)} β€” screenshots not found:\x1b[0m\n${missing.map((p) => ` ${p}`).join("\n")}`); + return false; + } + + const appName = messages["extName"]?.message ?? "Redmine Time Tracking"; + + const bg = Buffer.from(backgroundSvg(cW, cH)); + const composites: sharp.OverlayOptions[] = []; + + const ppH = Math.round(cH * 0.82); + const ppW = Math.round(ppH * (POPUP_WIDTH / POPUP_HEIGHT)); + const frontLeft = cW - PAD - ppW; + const frontTop = cH - PAD - ppH; + const cardStep = Math.round((frontLeft - textAreaRight) / 2); + const vertRange = frontTop - PAD; + + const stackConfigs = [ + { shot: 2, dx: -cardStep * 2, dy: -vertRange }, + { shot: 1, dx: -cardStep, dy: -Math.round(vertRange / 2) }, + { shot: 0, dx: 0, dy: 0 }, + ] as const; + + const stackedShots = await Promise.all( + stackConfigs.map(async (cfg) => ({ + cfg, + image: await roundImage(shotPaths[cfg.shot], ppW, ppH, RADIUS * scale), + })) + ); + + for (const { cfg, image } of stackedShots) { + const left = frontLeft + cfg.dx; + const top = frontTop + cfg.dy; + + const borderSvg = Buffer.from( + ` + ${borderGradDefs(`b${cfg.shot}`)} + + ` + ); + + composites.push({ input: image, top, left }); + composites.push({ input: Buffer.from(borderSvg), top, left }); + } + + const nameParts = appName.split(" "); + const midIdx = Math.ceil(nameParts.length / 2); + const line1 = nameParts.slice(0, midIdx).join(" "); + const line2 = nameParts.slice(midIdx).join(" "); + + const groupH = iconSize + iconTextGap + fontSize + (line2 ? lineGap + fontSize : 0); + const groupTop = Math.round((cH - groupH) / 2); + const textTop = groupTop + iconSize + iconTextGap; + const centerX = Math.round(textAreaRight / 2); + + const icon = await sharp("public/icon/128.png").resize(iconSize, iconSize).png().toBuffer(); + composites.push({ input: icon, top: groupTop, left: centerX - Math.round(iconSize / 2) }); + + composites.push({ + input: Buffer.from( + ` + ${escapeXml(line1)} + ${ + line2 + ? `${escapeXml(line2)}` + : "" + } + ` + ), + top: 0, + left: 0, + }); + + const composed = await sharp(bg).composite(composites).png().toBuffer(); + const output = opts.outputSize ? sharp(composed).resize(opts.outputSize.width, opts.outputSize.height).png() : sharp(composed); + await output.toFile(outputPath); + console.log(`\x1b[32m created ${outputPath}\x1b[0m`); + return true; +} + +async function generateThumbnail(outputPath: string, locale: Language, messages: Messages): Promise { + return generatePromoImage(outputPath, locale, messages, { + canvasWidth: THUMBNAIL_WIDTH * 2, + canvasHeight: THUMBNAIL_HEIGHT * 2, + pad: 20, + textAreaRight: 300, + iconSize: 56, + fontSize: 30, + lineGap: 6, + iconTextGap: 14, + outputSize: { width: THUMBNAIL_WIDTH, height: THUMBNAIL_HEIGHT }, + }); +} + +async function generateBanner(outputPath: string, locale: Language, messages: Messages): Promise { + return generatePromoImage(outputPath, locale, messages, { + canvasWidth: BANNER_WIDTH, + canvasHeight: BANNER_HEIGHT, + pad: 40, + textAreaRight: Math.round(BANNER_WIDTH * 0.38), + iconSize: 72, + fontSize: 42, + lineGap: 8, + iconTextGap: 18, + }); +} + +const ICON_ISSUES = ``; +const ICON_TIMER = ``; +const ICON_TIME = ``; +const ICON_SETTINGS = ``; + +interface StoreImage { + filename: string; + generate: (outputPath: string, locale: Language, messages: Messages) => Promise; +} + +const STORE_IMAGES: StoreImage[] = [ + { + filename: "1.png", + generate: (out, locale, messages) => + generateDualPopup( + out, + { file: "IssuesPage.spec.tsx", name: "Start-timer" }, + { file: "IssuesPage.spec.tsx", name: "Search-issues" }, + { titleKey: "screenshotIssuesTitle", subtitleKey: "screenshotIssuesSubtitle", icon: ICON_ISSUES }, + locale, + messages + ), + }, + { + filename: "2.png", + generate: (out, locale, messages) => + generateDualPopup( + out, + { file: "TimersPage.spec.tsx", name: "Timers-page" }, + { file: "IssuesPage.spec.tsx", name: "Add-spent-time" }, + { titleKey: "screenshotTimersTitle", subtitleKey: "screenshotTimersSubtitle", icon: ICON_TIMER }, + locale, + messages + ), + }, + { + filename: "3.png", + generate: (out, locale, messages) => + generateSinglePopup( + out, + { file: "TimePage.spec.tsx", name: "Time-page" }, + { titleKey: "screenshotTimeEntriesTitle", subtitleKey: "screenshotTimeEntriesSubtitle", icon: ICON_TIME }, + locale, + messages + ), + }, + { + filename: "4.png", + generate: (out, locale, messages) => + generateDualPopup( + out, + { file: "IssuesPage.spec.tsx", name: "Create-issue" }, + { file: "IssuesPage.spec.tsx", name: "Edit-issue" }, + { titleKey: "screenshotManageIssuesTitle", subtitleKey: "screenshotManageIssuesSubtitle", icon: ICON_ISSUES }, + locale, + messages + ), + }, + { + filename: "5.png", + generate: (out, locale, messages) => + generateSinglePopup( + out, + { file: "SettingsPage.spec.tsx", name: "Settings-page" }, + { titleKey: "screenshotSettingsTitle", subtitleKey: "screenshotSettingsSubtitle", icon: ICON_SETTINGS }, + locale, + messages + ), + }, +]; + +async function main() { + for (const locale of LANGUAGES) { + const messages = loadMessages(locale); + const chromeDir = path.join("screenshots", "chrome", locale); + fs.mkdirSync(chromeDir, { recursive: true }); + console.log(`[${locale}]`); + await Promise.all(STORE_IMAGES.map((img) => img.generate(path.join(chromeDir, img.filename), locale, messages))); + } + + const enMessages = loadMessages("en"); + + const chromeRoot = path.join("screenshots", "chrome"); + console.log("[thumbnail]"); + await generateThumbnail(path.join(chromeRoot, "thumbnail.png"), "en", enMessages); + + const screenshotsRoot = path.join("screenshots"); + console.log("[banner]"); + await generateBanner(path.join(screenshotsRoot, "banner.png"), "en", enMessages); +} + +main().catch(console.error); diff --git a/screenshots/ru/dark/chrome-store/issues-add-spent-time.png b/screenshots/ru/dark/chrome-store/issues-add-spent-time.png deleted file mode 100644 index ec59bd72..00000000 Binary files a/screenshots/ru/dark/chrome-store/issues-add-spent-time.png and /dev/null differ diff --git a/screenshots/ru/dark/chrome-store/issues-context-menu.png b/screenshots/ru/dark/chrome-store/issues-context-menu.png deleted file mode 100644 index 9c6527ef..00000000 Binary files a/screenshots/ru/dark/chrome-store/issues-context-menu.png and /dev/null differ diff --git a/screenshots/ru/dark/chrome-store/issues-search.png b/screenshots/ru/dark/chrome-store/issues-search.png deleted file mode 100644 index 4838bc6f..00000000 Binary files a/screenshots/ru/dark/chrome-store/issues-search.png and /dev/null differ diff --git a/screenshots/ru/dark/chrome-store/issues.png b/screenshots/ru/dark/chrome-store/issues.png deleted file mode 100644 index e88083a0..00000000 Binary files a/screenshots/ru/dark/chrome-store/issues.png and /dev/null differ diff --git a/screenshots/ru/dark/chrome-store/settings.png b/screenshots/ru/dark/chrome-store/settings.png deleted file mode 100644 index 76679321..00000000 Binary files a/screenshots/ru/dark/chrome-store/settings.png and /dev/null differ diff --git a/screenshots/ru/dark/chrome-store/time.png b/screenshots/ru/dark/chrome-store/time.png deleted file mode 100644 index 1241278a..00000000 Binary files a/screenshots/ru/dark/chrome-store/time.png and /dev/null differ diff --git a/screenshots/ru/dark/issues-add-spent-time.png b/screenshots/ru/dark/issues-add-spent-time.png deleted file mode 100644 index 104312c3..00000000 Binary files a/screenshots/ru/dark/issues-add-spent-time.png and /dev/null differ diff --git a/screenshots/ru/dark/issues-context-menu.png b/screenshots/ru/dark/issues-context-menu.png deleted file mode 100644 index 68d4551c..00000000 Binary files a/screenshots/ru/dark/issues-context-menu.png and /dev/null differ diff --git a/screenshots/ru/dark/issues-search.png b/screenshots/ru/dark/issues-search.png deleted file mode 100644 index 8e710ece..00000000 Binary files a/screenshots/ru/dark/issues-search.png and /dev/null differ diff --git a/screenshots/ru/dark/issues.png b/screenshots/ru/dark/issues.png deleted file mode 100644 index c956c5ac..00000000 Binary files a/screenshots/ru/dark/issues.png and /dev/null differ diff --git a/screenshots/ru/dark/settings.png b/screenshots/ru/dark/settings.png deleted file mode 100644 index bab45dad..00000000 Binary files a/screenshots/ru/dark/settings.png and /dev/null differ diff --git a/screenshots/ru/dark/time.png b/screenshots/ru/dark/time.png deleted file mode 100644 index d537f8bb..00000000 Binary files a/screenshots/ru/dark/time.png and /dev/null differ diff --git a/screenshots/ru/light/chrome-store/issues-add-spent-time.png b/screenshots/ru/light/chrome-store/issues-add-spent-time.png deleted file mode 100644 index ccc9af99..00000000 Binary files a/screenshots/ru/light/chrome-store/issues-add-spent-time.png and /dev/null differ diff --git a/screenshots/ru/light/chrome-store/issues-context-menu.png b/screenshots/ru/light/chrome-store/issues-context-menu.png deleted file mode 100644 index c0585211..00000000 Binary files a/screenshots/ru/light/chrome-store/issues-context-menu.png and /dev/null differ diff --git a/screenshots/ru/light/chrome-store/issues-search.png b/screenshots/ru/light/chrome-store/issues-search.png deleted file mode 100644 index 1f0242c1..00000000 Binary files a/screenshots/ru/light/chrome-store/issues-search.png and /dev/null differ diff --git a/screenshots/ru/light/chrome-store/issues.png b/screenshots/ru/light/chrome-store/issues.png deleted file mode 100644 index 880376a1..00000000 Binary files a/screenshots/ru/light/chrome-store/issues.png and /dev/null differ diff --git a/screenshots/ru/light/chrome-store/settings.png b/screenshots/ru/light/chrome-store/settings.png deleted file mode 100644 index 58fb7972..00000000 Binary files a/screenshots/ru/light/chrome-store/settings.png and /dev/null differ diff --git a/screenshots/ru/light/chrome-store/time.png b/screenshots/ru/light/chrome-store/time.png deleted file mode 100644 index 20e253fb..00000000 Binary files a/screenshots/ru/light/chrome-store/time.png and /dev/null differ diff --git a/screenshots/ru/light/issues-add-spent-time.png b/screenshots/ru/light/issues-add-spent-time.png deleted file mode 100644 index 10e22e03..00000000 Binary files a/screenshots/ru/light/issues-add-spent-time.png and /dev/null differ diff --git a/screenshots/ru/light/issues-context-menu.png b/screenshots/ru/light/issues-context-menu.png deleted file mode 100644 index fecb1106..00000000 Binary files a/screenshots/ru/light/issues-context-menu.png and /dev/null differ diff --git a/screenshots/ru/light/issues-search.png b/screenshots/ru/light/issues-search.png deleted file mode 100644 index c6eb26d7..00000000 Binary files a/screenshots/ru/light/issues-search.png and /dev/null differ diff --git a/screenshots/ru/light/issues.png b/screenshots/ru/light/issues.png deleted file mode 100644 index 67c465f5..00000000 Binary files a/screenshots/ru/light/issues.png and /dev/null differ diff --git a/screenshots/ru/light/settings.png b/screenshots/ru/light/settings.png deleted file mode 100644 index 00b439b2..00000000 Binary files a/screenshots/ru/light/settings.png and /dev/null differ diff --git a/screenshots/ru/light/time.png b/screenshots/ru/light/time.png deleted file mode 100644 index fc6a9c3e..00000000 Binary files a/screenshots/ru/light/time.png and /dev/null differ diff --git a/screenshots/screenshot.ts b/screenshots/screenshot.ts deleted file mode 100644 index 78892339..00000000 --- a/screenshots/screenshot.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Page } from "@playwright/test"; -import fs from "fs"; -import sharp from "sharp"; - -export const createScreenshot = async (name: string, page: Page, locale: string, colorScheme: string) => { - // Take a screenshot - const buffer = await page.screenshot({ - path: `screenshots/${locale}/${colorScheme}/${name}.png`, - }); - - // Create folder if not exists - if (!fs.existsSync(`screenshots/${locale}/${colorScheme}/chrome-store`)) { - fs.mkdirSync(`screenshots/${locale}/${colorScheme}/chrome-store`); - } - - // Create store screenshot - await sharp(`screenshots/chrome-template-${colorScheme}.png`) - .composite([{ input: buffer, top: 80, left: 828 }]) - .toFile(`screenshots/${locale}/${colorScheme}/chrome-store/${name}.png`); -}; diff --git a/screenshots/thumbnail.png b/screenshots/thumbnail.png deleted file mode 100644 index 2d1a70ea..00000000 Binary files a/screenshots/thumbnail.png and /dev/null differ diff --git a/src/App.tsx b/src/App.tsx deleted file mode 100644 index 105e6e32..00000000 --- a/src/App.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import { faGear, faList, faStopwatch, faUpRightFromSquare } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import clsx from "clsx"; -import { Suspense, lazy } from "react"; -import { useIntl } from "react-intl"; -import { Navigate, Route, Routes } from "react-router-dom"; -import Navbar from "./components/general/Navbar"; -import Toast from "./components/general/Toast"; -import { clsxm } from "./utils/clsxm"; -import { getPlatform } from "./utils/platform"; -import { createPopOut, getWindowLocationType } from "./utils/popout"; - -const IssuesPage = lazy(() => import("./pages/IssuesPage")); -const SettingsPage = lazy(() => import("./pages/SettingsPage")); -const TimePage = lazy(() => import("./pages/TimePage")); - -function App() { - const { formatMessage } = useIntl(); - - const locationType = getWindowLocationType(); - - return ( -
{ - e.preventDefault(); - }} - > -
- , - name: formatMessage({ id: "nav.tabs.issues" }), - }, - { - href: "/time", - icon: , - name: formatMessage({ id: "nav.tabs.time" }), - }, - { - href: "/settings", - icon: , - name: formatMessage({ id: "nav.tabs.settings" }), - }, - ]} - /> - {locationType === "popup" && } -
-
-
- - } /> - - - - - } - /> - - - - } - /> - - - - } - /> - - } /> - -
-
-
- ); -} - -export default App; diff --git a/src/api/redmine/MissingRedmineConfigError.ts b/src/api/redmine/MissingRedmineConfigError.ts new file mode 100644 index 00000000..af31ea91 --- /dev/null +++ b/src/api/redmine/MissingRedmineConfigError.ts @@ -0,0 +1,6 @@ +export class MissingRedmineConfigError extends Error { + constructor(message = "Redmine URL is not configured") { + super(message); + this.name = MissingRedmineConfigError.name; + } +} diff --git a/src/api/redmine.ts b/src/api/redmine/RedmineApiClient.ts similarity index 74% rename from src/api/redmine.ts rename to src/api/redmine/RedmineApiClient.ts index 35f692d3..2e7bcd19 100644 --- a/src/api/redmine.ts +++ b/src/api/redmine/RedmineApiClient.ts @@ -1,6 +1,7 @@ -import { AxiosInstance } from "axios"; +import axios, { AxiosInstance } from "axios"; import { formatISO } from "date-fns"; import qs from "qs"; +import { MissingRedmineConfigError } from "./MissingRedmineConfigError"; import { TCreateIssue, TCreateTimeEntry, @@ -20,12 +21,27 @@ import { TUpdateTimeEntry, TUser, TVersion, -} from "../types/redmine"; +} from "./types"; -export class RedmineApi { +export class RedmineApiClient { private instance: AxiosInstance; - constructor(instance: AxiosInstance) { - this.instance = instance; + public id = crypto.randomUUID(); + + constructor(redmineURL: string, redmineApiKey: string) { + this.instance = axios.create({ + baseURL: redmineURL, + headers: { + "X-Redmine-API-Key": redmineApiKey, + "Cache-Control": "no-cache, no-store, max-age=0", + Expires: "0", + }, + }); + this.instance.interceptors.request.use((config) => { + if (!config.baseURL) { + throw new MissingRedmineConfigError(); + } + return config; + }); this.instance.interceptors.response.use( (response) => { const contentType = response.headers["content-type"]; @@ -47,21 +63,29 @@ export class RedmineApi { } // Issues - async getOpenIssues( - { projectId, issueIds, assignedTo }: { projectId?: number; issueIds?: number[]; assignedTo?: number | "me" }, + async getIssues( + { projectId, issueIds, statusId, assignedTo }: { projectId?: number; issueIds?: number[]; statusId?: number | "open" | "closed" | "*"; assignedTo?: number | "me" }, { offset, limit }: { offset: number; limit: number } = { offset: 0, limit: 100 } ): Promise< TPaginatedResponse<{ issues: TIssue[]; }> > { + if (issueIds?.length === 0) { + return { + issues: [], + total_count: 0, + offset, + limit, + }; + } return this.instance .get( `/issues.json?${qs.stringify({ project_id: projectId, issue_id: issueIds?.join(","), assigned_to_id: assignedTo, - status_id: "open", + status_id: statusId, sort: "updated_on:desc", offset, limit, @@ -70,8 +94,27 @@ export class RedmineApi { .then((res) => res.data); } - async searchOpenIssues( - query: string, + async searchIssues( + { + query, + projectId, + scope, + titlesOnly, + openIssuesOnly, + }: { + query: string; + titlesOnly?: boolean; + openIssuesOnly?: boolean; + } & ( + | { + projectId: number; + scope?: "subprojects"; + } + | { + projectId?: never; + scope?: "all" | "my_projects" | "bookmarks"; // "bookmarks" available since Redmine 5.1.0 + } + ), { offset, limit }: { offset: number; limit: number } = { offset: 0, limit: 100 } ): Promise< TPaginatedResponse<{ @@ -80,12 +123,12 @@ export class RedmineApi { > { return this.instance .get( - `/search.json?${qs.stringify({ - q: query, - scope: "my_project", - titles_only: 1, + `${projectId ? `/projects/${projectId}` : ""}/search.json?${qs.stringify({ issues: 1, - open_issues: 1, + q: query, + scope, + ...(titlesOnly ? { titles_only: 1 } : {}), + ...(openIssuesOnly ? { open_issues: 1 } : {}), offset, limit, })}` @@ -135,7 +178,7 @@ export class RedmineApi { } // Projects - async getAllMyProjects({ offset, limit }: { offset: number; limit: number } = { offset: 0, limit: 100 }): Promise< + async getProjects({ offset, limit }: { offset: number; limit: number } = { offset: 0, limit: 100 }): Promise< TPaginatedResponse<{ projects: TProject[]; }> @@ -185,9 +228,16 @@ export class RedmineApi { } */ // Time entries - async getAllMyTimeEntries( - from: Date, - to: Date, + async getTimeEntries( + { + userId, + from, + to, + }: { + userId?: "me" | number; + from?: Date; + to?: Date; + }, { offset, limit }: { offset: number; limit: number } = { offset: 0, limit: 100 } ): Promise< TPaginatedResponse<{ @@ -197,9 +247,9 @@ export class RedmineApi { return this.instance .get( `/time_entries.json?${qs.stringify({ - user_id: "me", - from: formatISO(from, { representation: "date" }), - to: formatISO(to, { representation: "date" }), + user_id: userId, + ...(from && { from: formatISO(from, { representation: "date" }) }), + ...(to && { to: formatISO(to, { representation: "date" }) }), offset, limit, })}` @@ -234,7 +284,7 @@ export class RedmineApi { } // Roles and permissions - async getAllRoles(): Promise { + async getRoles(): Promise { return this.instance.get(`/roles.json`).then((res) => res.data.roles); } @@ -242,7 +292,7 @@ export class RedmineApi { return this.instance.get(`/roles/${id}.json`).then((res) => res.data.role); } - async getMyUser(): Promise { + async getCurrentUser(): Promise { return this.instance.get("/users/current.json?include=memberships").then((res) => res.data.user); } } diff --git a/src/api/redmine/hooks/useRedmineCurrentUser.ts b/src/api/redmine/hooks/useRedmineCurrentUser.ts new file mode 100644 index 00000000..41b429e9 --- /dev/null +++ b/src/api/redmine/hooks/useRedmineCurrentUser.ts @@ -0,0 +1,12 @@ +import { redmineCurrentUserQuery } from "@/api/redmine/queries/currentUser"; +import { useRedmineApi } from "@/provider/RedmineApiProvider"; +import { useQuery } from "@tanstack/react-query"; + +export const useRedmineCurrentUser = (queryOptions?: Omit, "queryKey" | "queryFn">) => { + const redmineApi = useRedmineApi(); + + return useQuery({ + ...redmineCurrentUserQuery(redmineApi), + ...queryOptions, + }); +}; diff --git a/src/api/redmine/hooks/useRedmineIssue.ts b/src/api/redmine/hooks/useRedmineIssue.ts new file mode 100644 index 00000000..ba35fd46 --- /dev/null +++ b/src/api/redmine/hooks/useRedmineIssue.ts @@ -0,0 +1,12 @@ +import { redmineIssueQuery } from "@/api/redmine/queries/issues"; +import { useRedmineApi } from "@/provider/RedmineApiProvider"; +import { useQuery } from "@tanstack/react-query"; + +export const useRedmineIssue = (issueId: number, queryOptions?: Omit, "queryKey" | "queryFn">) => { + const redmineApi = useRedmineApi(); + + return useQuery({ + ...redmineIssueQuery(redmineApi, issueId), + ...queryOptions, + }); +}; diff --git a/src/hooks/useIssueStatuses.ts b/src/api/redmine/hooks/useRedmineIssueAllowedStatuses.ts similarity index 51% rename from src/hooks/useIssueStatuses.ts rename to src/api/redmine/hooks/useRedmineIssueAllowedStatuses.ts index 6bac8c34..3fc66e23 100644 --- a/src/hooks/useIssueStatuses.ts +++ b/src/api/redmine/hooks/useRedmineIssueAllowedStatuses.ts @@ -1,22 +1,24 @@ +import { redmineIssueQuery } from "@/api/redmine/queries/issues"; +import { redmineIssueStatusesQuery } from "@/api/redmine/queries/issueStatuses"; import { useQuery } from "@tanstack/react-query"; -import { useRedmineApi } from "../provider/RedmineApiProvider"; -import useIssue from "./useIssue"; +import { useRedmineApi } from "../../../provider/RedmineApiProvider"; -type Options = { - issueStaleTime?: number; -}; - -const useIssueStatuses = (issueId: number, { issueStaleTime }: Options = {}) => { +/** + * Hook to get the allowed statuses for a redmine issue + */ +export const useRedmineIssueAllowedStatuses = (issueId: number, queryOptions?: Omit, "queryKey" | "queryFn">) => { const redmineApi = useRedmineApi(); - const issueQuery = useIssue(issueId, { staleTime: issueStaleTime }); + const issueQuery = useQuery({ + ...redmineIssueQuery(redmineApi, issueId), + ...queryOptions, + }); const hasIssueNoAllowedStatuses = !!issueQuery.data && issueQuery.data.allowed_statuses === undefined; const issueStatusesQuery = useQuery({ - queryKey: ["issueStatuses"], - queryFn: () => redmineApi.getIssueStatuses(), - enabled: hasIssueNoAllowedStatuses, + ...redmineIssueStatusesQuery(redmineApi), + enabled: (queryOptions?.enabled ?? true) && hasIssueNoAllowedStatuses, }); const statuses = hasIssueNoAllowedStatuses @@ -27,10 +29,7 @@ const useIssueStatuses = (issueId: number, { issueStaleTime }: Options = {}) => issueQuery.data?.allowed_statuses; return { - data: statuses, - isLoading: issueQuery.isLoading || issueStatusesQuery.isLoading, - isError: issueQuery.isError || issueStatusesQuery.isError, + statuses, hasIssueNoAllowedStatuses, }; }; -export default useIssueStatuses; diff --git a/src/api/redmine/hooks/useRedmineIssuePriorities.ts b/src/api/redmine/hooks/useRedmineIssuePriorities.ts new file mode 100644 index 00000000..8e34ba03 --- /dev/null +++ b/src/api/redmine/hooks/useRedmineIssuePriorities.ts @@ -0,0 +1,111 @@ +import { redmineIssuePrioritiesQuery } from "@/api/redmine/queries/issuePriorities"; +import { useRedmineApi } from "@/provider/RedmineApiProvider"; +import { combineFlatSuspenseQueries } from "@/utils/query"; +import { useQuery, useSuspenseQueries } from "@tanstack/react-query"; +import { TIssue, TIssuePriority } from "../types"; + +type Options = { + enabled?: boolean; +}; + +/** + * Hook to get redmine issue priorities + */ +export const useRedmineIssuePriorities = ({ enabled = true }: Options = {}) => { + const redmineApi = useRedmineApi(); + + const issuePrioritiesQuery = useQuery({ + ...redmineIssuePrioritiesQuery(redmineApi), + enabled, + }); + + const priorities = issuePrioritiesQuery.data ?? []; + const priorityTypeMap = buildPriorityTypeMap(priorities); + + return { + priorities, + defaultPriority: getDefaultPriority(priorities), + getPriorityType: (issue: TIssue) => getPriorityType(issue, priorityTypeMap), + isPending: issuePrioritiesQuery.isPending, + }; +}; + +/** + * Hook to get redmine issue priorities with suspense + */ +export const useSuspenseIssuePriorities = ({ enabled = true }: Options = {}) => { + const redmineApi = useRedmineApi(); + + const issuePrioritiesQuery = useSuspenseQueries({ + queries: enabled ? [redmineIssuePrioritiesQuery(redmineApi)] : ([] as ReturnType[]), + combine: combineFlatSuspenseQueries, + }); + + return { + priorities: issuePrioritiesQuery.data, + }; +}; + +export type PriorityType = "highest" | "high" | "medium-high" | "medium" | "default" | "low" | "lowest" | "unknown"; + +/** + * Build priority type map + * + * Depending on the default priority position, assign priority types + * + * Examples: + * ["lowest", "low", "low", "low", "default", "medium", "medium", "medium", "medium-high", "high", "highest"] + * ["lowest", "default", "medium-high", "high", "highest"] + * ["lowest", "default", "high", "highest"] + * ["lowest", "default", "highest"] + * ["default", "high", "highest"] + * ["lowest", "low", "default"] + * ["default", "highest"] + */ +const buildPriorityTypeMap = (priorities: TIssuePriority[]): Map => { + const priorityTypeMap = new Map(); + + let defaultIdx = priorities.findIndex((p) => p.is_default); + if (defaultIdx === -1) { + // If no default priority is set, use the lower middle as default + defaultIdx = Math.floor((priorities.length - 1) / 2); + } + + priorities.forEach((priority, idx) => { + if (idx === defaultIdx) { + priorityTypeMap.set(priority.id, "default"); + } else if (idx < defaultIdx) { + if (idx === 0) { + priorityTypeMap.set(priority.id, "lowest"); + } else { + priorityTypeMap.set(priority.id, "low"); + } + } else if (idx > defaultIdx) { + if (idx === priorities.length - 1) { + priorityTypeMap.set(priority.id, "highest"); + } else if (idx === priorities.length - 2) { + priorityTypeMap.set(priority.id, "high"); + } else if (idx === priorities.length - 3) { + priorityTypeMap.set(priority.id, "medium-high"); + } else { + priorityTypeMap.set(priority.id, "medium"); + } + } + }); + + return priorityTypeMap; +}; + +/** + * Get priority type for issue + */ +const getPriorityType = (issue: TIssue, priorityTypeMap: ReturnType) => { + return priorityTypeMap.get(issue.priority.id) ?? "unknown"; +}; + +/** + * Get default priority + */ +const getDefaultPriority = (priorities: TIssuePriority[]) => { + return priorities.find((p) => p.is_default); +}; diff --git a/src/api/redmine/hooks/useRedmineIssueStatuses.ts b/src/api/redmine/hooks/useRedmineIssueStatuses.ts new file mode 100644 index 00000000..ab749257 --- /dev/null +++ b/src/api/redmine/hooks/useRedmineIssueStatuses.ts @@ -0,0 +1,12 @@ +import { redmineIssueStatusesQuery } from "@/api/redmine/queries/issueStatuses"; +import { useRedmineApi } from "@/provider/RedmineApiProvider"; +import { useQuery } from "@tanstack/react-query"; + +export const useRedmineIssueStatuses = (queryOptions?: Omit, "queryKey" | "queryFn">) => { + const redmineApi = useRedmineApi(); + + return useQuery({ + ...redmineIssueStatusesQuery(redmineApi), + ...queryOptions, + }); +}; diff --git a/src/api/redmine/hooks/useRedmineIssues.ts b/src/api/redmine/hooks/useRedmineIssues.ts new file mode 100644 index 00000000..7bf49111 --- /dev/null +++ b/src/api/redmine/hooks/useRedmineIssues.ts @@ -0,0 +1,16 @@ +import { useSuspenseRedminePaginatedInfiniteQuery } from "@/api/redmine/hooks/useRedminePaginatedInfiniteQuery"; +import { redmineIssuesQuery } from "@/api/redmine/queries/issues"; +import { useRedmineApi } from "@/provider/RedmineApiProvider"; + +export const useSuspenseRedmineIssues = ( + options: Parameters[1], + queryOptions?: Omit, "queryKey" | "queryFn" | "enabled" | "throwOnError" | "placeholderData"> +) => { + const redmineApi = useRedmineApi(); + + return useSuspenseRedminePaginatedInfiniteQuery({ + ...redmineIssuesQuery(redmineApi, options), + ...queryOptions, + autoFetchPages: true, + }); +}; diff --git a/src/api/redmine/hooks/useRedmineIssuesSearch.ts b/src/api/redmine/hooks/useRedmineIssuesSearch.ts new file mode 100644 index 00000000..8bddc8fb --- /dev/null +++ b/src/api/redmine/hooks/useRedmineIssuesSearch.ts @@ -0,0 +1,76 @@ +import { redmineIssuesQuery } from "@/api/redmine/queries/issues"; +import { redmineSearchIssuesQuery } from "@/api/redmine/queries/search"; +import { keepPreviousData } from "@tanstack/react-query"; +import { IssueSearchContext } from "../../../components/issue/IssueSearch"; +import { useRedmineApi } from "../../../provider/RedmineApiProvider"; +import { useRedminePaginatedInfiniteQuery } from "./useRedminePaginatedInfiniteQuery"; + +const STALE_DATA_TIME = 1000 * 60; // 1 minute + +const useRedmineIssuesSearch = (search: IssueSearchContext) => { + const redmineApi = useRedmineApi(); + + const isSearching = search.isSearching && search.settings.mode === "remote"; + + const [_, _issueIdSearch] = search.query.match(/^#(\d+)$/) ?? []; // search for # + const issueIdSearch = _issueIdSearch ? Number(_issueIdSearch) : undefined; + + // Search issues + const searchResultQuery = useRedminePaginatedInfiniteQuery({ + ...redmineSearchIssuesQuery(redmineApi, { + query: search.query, + ...(search.inProject?.id + ? { + projectId: search.inProject.id, + } + : { + scope: "my_projects", + }), + titlesOnly: search.settings.remoteSearchOptions.titlesOnly, // search option: titles only + openIssuesOnly: search.settings.remoteSearchOptions.openIssuesOnly, // search option: open issues only + }), + select: (data) => + data.pages + .map((page) => page.results) + .flat() + .map((result) => result.id), + enabled: isSearching && !issueIdSearch, + placeholderData: keepPreviousData, + staleTime: STALE_DATA_TIME, + }); + + // Collect issueIds + const issueIds = isSearching + ? issueIdSearch + ? // just search by issueId + [issueIdSearch] + : // use search results + (searchResultQuery.data ?? []) + : []; + + // Query issues by ids + const issuesQuery = useRedminePaginatedInfiniteQuery({ + ...redmineIssuesQuery(redmineApi, { + issueIds: issueIds, + projectId: search.inProject?.id, // filter: project (search in project) + assignedTo: search.settings.remoteSearchOptions.assignedToMe ? "me" : undefined, // search option: assigned to me + statusId: search.settings.remoteSearchOptions.openIssuesOnly ? "open" : "*", // search option: open issues only + }), + enabled: issueIds.length > 0 && !searchResultQuery.isFetching, + placeholderData: keepPreviousData, + staleTime: STALE_DATA_TIME, + autoFetchPages: 10, // Auto fetch (max 10 pages) + }); + + const issues = issuesQuery.data ?? []; + + return { + data: issues, + isLoading: issuesQuery.isLoading, + isError: issuesQuery.isError, + hasNextPage: searchResultQuery.hasNextPage, + fetchNextPage: searchResultQuery.fetchNextPage, + }; +}; + +export default useRedmineIssuesSearch; diff --git a/src/api/redmine/hooks/useRedmineMultipleProjectVersions.ts b/src/api/redmine/hooks/useRedmineMultipleProjectVersions.ts new file mode 100644 index 00000000..f3fd5512 --- /dev/null +++ b/src/api/redmine/hooks/useRedmineMultipleProjectVersions.ts @@ -0,0 +1,35 @@ +import { redmineProjectVersionsQuery } from "@/api/redmine/queries/projectVersions"; +import { useSuspenseQueries, UseSuspenseQueryResult } from "@tanstack/react-query"; +import { useDeferredValue } from "react"; +import { useRedmineApi } from "../../../provider/RedmineApiProvider"; +import { TVersion } from "../types"; + +type Options = { + enabled?: boolean; +}; + +/** + * Hook to get multiple project versions with suspense + */ +export const useSuspenseRedmineMultipleProjectVersions = (projectIds: number[], { enabled = true }: Options = {}) => { + const redmineApi = useRedmineApi(); + + const deferredProjectIds = useDeferredValue(projectIds); + const versionsQueries = useSuspenseQueries({ + queries: (enabled ? deferredProjectIds : []).map((id) => redmineProjectVersionsQuery(redmineApi, id)), + combine: combineSuspenseMultipleVersions, + }); + + return { + projectVersionsMap: versionsQueries.data, + }; +}; + +const combineSuspenseMultipleVersions = (results: UseSuspenseQueryResult[]) => ({ + data: results.reduce>((result, query) => { + if (query.data && query.data[0]) { + result[query.data[0].project.id] = query.data; + } + return result; + }, {}), +}); diff --git a/src/api/redmine/hooks/useRedminePaginatedInfiniteQuery.ts b/src/api/redmine/hooks/useRedminePaginatedInfiniteQuery.ts new file mode 100644 index 00000000..b3fb1a4d --- /dev/null +++ b/src/api/redmine/hooks/useRedminePaginatedInfiniteQuery.ts @@ -0,0 +1,127 @@ +import { + DefaultError, + InfiniteData, + infiniteQueryOptions, + QueryKey, + UnusedSkipTokenInfiniteOptions, + useInfiniteQuery, + UseInfiniteQueryOptions, + useSuspenseInfiniteQuery, + UseSuspenseInfiniteQueryOptions, +} from "@tanstack/react-query"; +import { useEffect, useState } from "react"; +import { TPaginatedResponse } from "../types"; + +const defaultInitialPageParam = { + offset: 0, + limit: 100, +}; + +export const redminePaginatedInfiniteQueryOptions = < + TQueryFnData extends TPaginatedResponse, + TError = DefaultError, + TData = InfiniteData, + TQueryKey extends QueryKey = QueryKey, +>( + options: Omit, "initialPageParam" | "getNextPageParam" | "getPreviousPageParam"> +) => + infiniteQueryOptions({ + initialPageParam: defaultInitialPageParam, + getNextPageParam: (lastPage) => (lastPage.total_count > lastPage.offset + lastPage.limit ? { offset: lastPage.offset + lastPage.limit, limit: lastPage.limit } : undefined), + ...options, + }); + +/** + * Hook to fetch paginated data from Redmine API using infinite query + */ +export const useRedminePaginatedInfiniteQuery = < + TQueryFnData extends TPaginatedResponse, + TError = DefaultError, + TData = InfiniteData, + TQueryKey extends QueryKey = QueryKey, +>({ + autoFetchPages = false, + ...options +}: Omit, "initialPageParam" | "getNextPageParam" | "getPreviousPageParam"> & { + /** + * Automatically fetch next pages + * - `false`: disabled + * - `true`: enabled until there are no more pages + * - `number`: enabled with a limit of pages to fetch + * + * @default false + */ + autoFetchPages?: boolean | number; +}) => { + const query = useInfiniteQuery({ + initialPageParam: defaultInitialPageParam, + getNextPageParam: (lastPage) => (lastPage.total_count > lastPage.offset + lastPage.limit ? { offset: lastPage.offset + lastPage.limit, limit: lastPage.limit } : undefined), + ...options, + }); + + // Auto fetch pages + const { hasNextPage, isFetchingNextPage, fetchNextPage } = query; + const { enabled } = options; + const [autoFetchedPages, setAutoFetchedPages] = useState(0); + useEffect(() => { + // Disabled or nothing to fetch + if (enabled === false || !autoFetchPages || !hasNextPage || isFetchingNextPage) return; + + // No more pages to fetch (limit reached) + if (typeof autoFetchPages === "number" && autoFetchedPages >= autoFetchPages) return; + + // Fetch next page and increment counter after the fetch completes + fetchNextPage().then(() => { + setAutoFetchedPages((prev) => prev + 1); + }); + }, [enabled, hasNextPage, isFetchingNextPage, fetchNextPage, autoFetchPages, autoFetchedPages]); + + return query; +}; + +/** + * Hook to fetch paginated data from Redmine API using infinite query + */ +export const useSuspenseRedminePaginatedInfiniteQuery = < + TQueryFnData extends TPaginatedResponse, + TError = DefaultError, + TData = InfiniteData, + TQueryKey extends QueryKey = QueryKey, +>({ + autoFetchPages = false, + ...options +}: Omit, "initialPageParam" | "getNextPageParam" | "getPreviousPageParam"> & { + /** + * Automatically fetch next pages + * - `false`: disabled + * - `true`: enabled until there are no more pages + * - `number`: enabled with a limit of pages to fetch + * + * @default false + */ + autoFetchPages?: boolean | number; +}) => { + const query = useSuspenseInfiniteQuery({ + initialPageParam: defaultInitialPageParam, + getNextPageParam: (lastPage) => (lastPage.total_count > lastPage.offset + lastPage.limit ? { offset: lastPage.offset + lastPage.limit, limit: lastPage.limit } : undefined), + ...options, + }); + + // Auto fetch pages + const { hasNextPage, isFetchingNextPage, fetchNextPage } = query; + const [autoFetchedPages, setAutoFetchedPages] = useState(0); + useEffect(() => { + // Disabled or nothing to fetch + if (!autoFetchPages || !hasNextPage || isFetchingNextPage) return; + + // No more pages to fetch (limit reached) + if (typeof autoFetchPages === "number" && autoFetchedPages >= autoFetchPages) return; + + // Fetch next page + fetchNextPage().then(() => { + setAutoFetchedPages((prev) => prev + 1); + }); + }, [hasNextPage, isFetchingNextPage, fetchNextPage, autoFetchPages, autoFetchedPages]); + + return query; +}; diff --git a/src/api/redmine/hooks/useRedmineProject.ts b/src/api/redmine/hooks/useRedmineProject.ts new file mode 100644 index 00000000..26e2541b --- /dev/null +++ b/src/api/redmine/hooks/useRedmineProject.ts @@ -0,0 +1,12 @@ +import { redmineProjectQuery } from "@/api/redmine/queries/projects"; +import { useRedmineApi } from "@/provider/RedmineApiProvider"; +import { useQuery } from "@tanstack/react-query"; + +export const useRedmineProject = (projectId: number, queryOptions?: Omit, "queryKey" | "queryFn">) => { + const redmineApi = useRedmineApi(); + + return useQuery({ + ...redmineProjectQuery(redmineApi, projectId), + ...queryOptions, + }); +}; diff --git a/src/api/redmine/hooks/useRedmineProjectIssueTrackers.ts b/src/api/redmine/hooks/useRedmineProjectIssueTrackers.ts new file mode 100644 index 00000000..fa924606 --- /dev/null +++ b/src/api/redmine/hooks/useRedmineProjectIssueTrackers.ts @@ -0,0 +1,20 @@ +import { redmineIssueTrackersQuery } from "@/api/redmine/queries/issueTrackers"; +import { redmineProjectQuery } from "@/api/redmine/queries/projects"; +import { useQuery } from "@tanstack/react-query"; +import { useRedmineApi } from "../../../provider/RedmineApiProvider"; + +export const useRedmineProjectIssueTrackers = (projectId: number) => { + const redmineApi = useRedmineApi(); + + const projectQuery = useQuery(redmineProjectQuery(redmineApi, projectId)); + const issueTrackersQuery = useQuery(redmineIssueTrackersQuery(redmineApi)); + + const enabledTrackers = projectQuery.data?.trackers?.map((tracker) => tracker.id); + const trackers = enabledTrackers ? issueTrackersQuery.data?.filter((t) => enabledTrackers.includes(t.id)) : issueTrackersQuery.data; + + return { + trackers, + defaultTracker: trackers?.[0], + isPending: issueTrackersQuery.isPending || projectQuery.isPending, + }; +}; diff --git a/src/api/redmine/hooks/useRedmineProjectMembers.ts b/src/api/redmine/hooks/useRedmineProjectMembers.ts new file mode 100644 index 00000000..9339f925 --- /dev/null +++ b/src/api/redmine/hooks/useRedmineProjectMembers.ts @@ -0,0 +1,63 @@ +import { redmineProjectMembershipsQuery } from "@/api/redmine/queries/projectMemberships"; +import { redmineRolesQuery } from "@/api/redmine/queries/roles"; +import { useQuery } from "@tanstack/react-query"; +import { useRedmineApi } from "../../../provider/RedmineApiProvider"; +import { TMembership, TReference } from "../types"; +import { useRedminePaginatedInfiniteQuery } from "./useRedminePaginatedInfiniteQuery"; + +type Options = { + enabled?: boolean; +}; + +export type TProjectMember = TMembership["user"] & { + roles: TMembership["roles"]; + highestRole?: TMembership["roles"][0]; +}; + +export const useRedmineProjectMembers = (projectId: number, { enabled = true }: Options = {}) => { + const redmineApi = useRedmineApi(); + + const membershipsQuery = useRedminePaginatedInfiniteQuery({ + ...redmineProjectMembershipsQuery(redmineApi, projectId), + enabled: enabled, + autoFetchPages: true, + }); + + const rolesQuery = useQuery({ + ...redmineRolesQuery(redmineApi), + enabled: enabled, + }); + + const rolesSortMap = buildRolesSortMap(rolesQuery.data ?? []); + + const members: TProjectMember[] = + membershipsQuery.data + ?.filter((m) => m.user) + .map((m) => ({ + ...m.user!, + roles: m.roles, + highestRole: getHighestRole(m.roles, rolesSortMap), + })) ?? []; + + return { + members, + isPending: membershipsQuery.isPending || rolesQuery.isPending, + }; +}; + +const buildRolesSortMap = (roles: TReference[]) => { + const sortMap = new Map(); + roles.forEach((role, index) => { + sortMap.set(role.id, index); + }); + return sortMap; +}; + +const getHighestRole = (roles: TReference[], rolesSortMap: Map) => { + return roles.reduce((highestRole, role) => { + if (!highestRole || (rolesSortMap.get(role.id) ?? 0) < (rolesSortMap.get(highestRole.id) ?? 0)) { + highestRole = role; + } + return highestRole; + }, undefined); +}; diff --git a/src/api/redmine/hooks/useRedmineProjectTimeEntryActivities.ts b/src/api/redmine/hooks/useRedmineProjectTimeEntryActivities.ts new file mode 100644 index 00000000..c1fa9dad --- /dev/null +++ b/src/api/redmine/hooks/useRedmineProjectTimeEntryActivities.ts @@ -0,0 +1,25 @@ +import { redmineProjectQuery } from "@/api/redmine/queries/projects"; +import { redmineTimeEntryActivitiesQuery } from "@/api/redmine/queries/timeEntryActivities"; +import { useQuery } from "@tanstack/react-query"; +import { useRedmineApi } from "../../../provider/RedmineApiProvider"; + +export const useRedmineProjectTimeEntryActivities = (projectId: number) => { + const redmineApi = useRedmineApi(); + + const projectQuery = useQuery(redmineProjectQuery(redmineApi, projectId)); + const systemTimeEntryActivitiesQuery = useQuery(redmineTimeEntryActivitiesQuery(redmineApi)); + + const projectTimeEntryActivities = projectQuery.data?.time_entry_activities; + const activities = projectTimeEntryActivities + ? projectTimeEntryActivities?.map((activity) => ({ + ...systemTimeEntryActivitiesQuery.data?.find((systemActivity) => systemActivity.id === activity.id), + ...activity, + })) + : systemTimeEntryActivitiesQuery.data?.filter((activity) => activity.active !== false); + + return { + activities, + defaultActivity: activities?.find((entry) => entry.is_default), + isPending: projectQuery.isPending || systemTimeEntryActivitiesQuery.isPending, + }; +}; diff --git a/src/api/redmine/hooks/useRedmineProjectVersions.ts b/src/api/redmine/hooks/useRedmineProjectVersions.ts new file mode 100644 index 00000000..c2f80990 --- /dev/null +++ b/src/api/redmine/hooks/useRedmineProjectVersions.ts @@ -0,0 +1,12 @@ +import { redmineProjectVersionsQuery } from "@/api/redmine/queries/projectVersions"; +import { useRedmineApi } from "@/provider/RedmineApiProvider"; +import { useQuery } from "@tanstack/react-query"; + +export const useRedmineProjectVersions = (projectId: number, queryOptions?: Omit, "queryKey" | "queryFn">) => { + const redmineApi = useRedmineApi(); + + return useQuery({ + ...redmineProjectVersionsQuery(redmineApi, projectId), + ...queryOptions, + }); +}; diff --git a/src/api/redmine/hooks/useRedmineProjects.ts b/src/api/redmine/hooks/useRedmineProjects.ts new file mode 100644 index 00000000..102b9abf --- /dev/null +++ b/src/api/redmine/hooks/useRedmineProjects.ts @@ -0,0 +1,13 @@ +import { useRedminePaginatedInfiniteQuery } from "@/api/redmine/hooks/useRedminePaginatedInfiniteQuery"; +import { redmineProjectsQuery } from "@/api/redmine/queries/projects"; +import { useRedmineApi } from "@/provider/RedmineApiProvider"; + +export const useRedmineProjects = (queryOptions?: Omit, "queryKey" | "queryFn">) => { + const redmineApi = useRedmineApi(); + + return useRedminePaginatedInfiniteQuery({ + ...redmineProjectsQuery(redmineApi), + ...queryOptions, + autoFetchPages: true, + }); +}; diff --git a/src/api/redmine/hooks/useRedmineTimeEntries.ts b/src/api/redmine/hooks/useRedmineTimeEntries.ts new file mode 100644 index 00000000..b5c5f1ea --- /dev/null +++ b/src/api/redmine/hooks/useRedmineTimeEntries.ts @@ -0,0 +1,26 @@ +import { useRedminePaginatedInfiniteQuery, useSuspenseRedminePaginatedInfiniteQuery } from "@/api/redmine/hooks/useRedminePaginatedInfiniteQuery"; +import { redmineTimeEntriesQuery } from "@/api/redmine/queries/timeEntries"; +import { useRedmineApi } from "@/provider/RedmineApiProvider"; + +export const useRedmineTimeEntries = (options: Parameters[1], queryOptions?: Omit, "queryKey" | "queryFn">) => { + const redmineApi = useRedmineApi(); + + return useRedminePaginatedInfiniteQuery({ + ...redmineTimeEntriesQuery(redmineApi, options), + ...queryOptions, + autoFetchPages: true, + }); +}; + +export const useSuspenseRedmineTimeEntries = ( + options: Parameters[1], + queryOptions?: Omit, "queryKey" | "queryFn" | "enabled" | "throwOnError" | "placeholderData"> +) => { + const redmineApi = useRedmineApi(); + + return useSuspenseRedminePaginatedInfiniteQuery({ + ...redmineTimeEntriesQuery(redmineApi, options), + ...queryOptions, + autoFetchPages: true, + }); +}; diff --git a/src/api/redmine/hooks/useTestRedmineConnection.ts b/src/api/redmine/hooks/useTestRedmineConnection.ts new file mode 100644 index 00000000..5424d936 --- /dev/null +++ b/src/api/redmine/hooks/useTestRedmineConnection.ts @@ -0,0 +1,26 @@ +import { RedmineApiClient } from "@/api/redmine/RedmineApiClient"; +import { useQuery } from "@tanstack/react-query"; +import { useRedmineApi } from "../../../provider/RedmineApiProvider"; + +export const useTestRedmineConnection = (customRedmineApiClient?: RedmineApiClient) => { + const defaultRedmineApi = useRedmineApi(); + const redmineApiClient = customRedmineApiClient ?? defaultRedmineApi; + + const myUserQuery = useQuery({ + queryKey: ["redmine", "testRedmineConnection", redmineApiClient], + queryFn: () => redmineApiClient.getCurrentUser(), + retry: 1, + staleTime: 0, + gcTime: 0, + meta: { + displayErrorToast: false, + }, + }); + + return { + data: myUserQuery.data, + isLoading: myUserQuery.isLoading, + isError: myUserQuery.isError, + error: myUserQuery.error, + }; +}; diff --git a/src/api/redmine/queries/currentUser.ts b/src/api/redmine/queries/currentUser.ts new file mode 100644 index 00000000..c7fa3566 --- /dev/null +++ b/src/api/redmine/queries/currentUser.ts @@ -0,0 +1,11 @@ +import { RedmineApiClient } from "@/api/redmine/RedmineApiClient"; +import { queryOptions } from "@tanstack/react-query"; + +/** + * Query current redmine user + */ +export const redmineCurrentUserQuery = (redmineApi: RedmineApiClient) => + queryOptions({ + queryKey: ["redmine", "currentUser"], + queryFn: () => redmineApi.getCurrentUser(), + }); diff --git a/src/api/redmine/queries/issuePriorities.ts b/src/api/redmine/queries/issuePriorities.ts new file mode 100644 index 00000000..d1ba2348 --- /dev/null +++ b/src/api/redmine/queries/issuePriorities.ts @@ -0,0 +1,12 @@ +import { RedmineApiClient } from "@/api/redmine/RedmineApiClient"; +import { queryOptions } from "@tanstack/react-query"; + +/** + * Query redmine issue priorities + */ +export const redmineIssuePrioritiesQuery = (redmineApi: RedmineApiClient) => + queryOptions({ + queryKey: ["redmine", "issuePriorities"], + queryFn: () => redmineApi.getIssuePriorities(), + select: (data) => data.filter((priority) => priority.active !== false), + }); diff --git a/src/api/redmine/queries/issueStatuses.ts b/src/api/redmine/queries/issueStatuses.ts new file mode 100644 index 00000000..3b8f5f23 --- /dev/null +++ b/src/api/redmine/queries/issueStatuses.ts @@ -0,0 +1,11 @@ +import { RedmineApiClient } from "@/api/redmine/RedmineApiClient"; +import { queryOptions } from "@tanstack/react-query"; + +/** + * Query redmine issue statuses + */ +export const redmineIssueStatusesQuery = (redmineApi: RedmineApiClient) => + queryOptions({ + queryKey: ["redmine", "issueStatuses"], + queryFn: () => redmineApi.getIssueStatuses(), + }); diff --git a/src/api/redmine/queries/issueTrackers.ts b/src/api/redmine/queries/issueTrackers.ts new file mode 100644 index 00000000..ed2bf617 --- /dev/null +++ b/src/api/redmine/queries/issueTrackers.ts @@ -0,0 +1,11 @@ +import { RedmineApiClient } from "@/api/redmine/RedmineApiClient"; +import { queryOptions } from "@tanstack/react-query"; + +/** + * Query redmine issue trackers + */ +export const redmineIssueTrackersQuery = (redmineApi: RedmineApiClient) => + queryOptions({ + queryKey: ["redmine", "issueTrackers"], + queryFn: () => redmineApi.getIssueTrackers(), + }); diff --git a/src/api/redmine/queries/issues.ts b/src/api/redmine/queries/issues.ts new file mode 100644 index 00000000..d9af963a --- /dev/null +++ b/src/api/redmine/queries/issues.ts @@ -0,0 +1,31 @@ +import { redminePaginatedInfiniteQueryOptions } from "@/api/redmine/hooks/useRedminePaginatedInfiniteQuery"; +import { RedmineApiClient } from "@/api/redmine/RedmineApiClient"; +import { InvalidateQueryFilters, queryOptions } from "@tanstack/react-query"; + +const STALE_TIME = 1000 * 60; +const AUTO_REFRESH_INTERVAL = 1000 * 60 * 15; + +export const redmineIssuesQueries = { + queryKey: ["redmine", "issues"], +} satisfies InvalidateQueryFilters; + +/** + * Query single redmine issue + */ +export const redmineIssueQuery = (redmineApi: RedmineApiClient, issueId: number) => + queryOptions({ + queryKey: ["redmine", "issues", issueId], + queryFn: () => redmineApi.getIssue(issueId), + }); + +/** + * Query multiple redmine issues + */ +export const redmineIssuesQuery = (redmineApi: RedmineApiClient, options: Parameters[0]) => + redminePaginatedInfiniteQueryOptions({ + queryKey: ["redmine", "issues", options], + queryFn: ({ pageParam }) => redmineApi.getIssues(options, pageParam), + select: (data) => data.pages.map((page) => page.issues).flat(), + staleTime: STALE_TIME, + refetchInterval: AUTO_REFRESH_INTERVAL, + }); diff --git a/src/api/redmine/queries/projectMemberships.ts b/src/api/redmine/queries/projectMemberships.ts new file mode 100644 index 00000000..0d3dc43b --- /dev/null +++ b/src/api/redmine/queries/projectMemberships.ts @@ -0,0 +1,12 @@ +import { redminePaginatedInfiniteQueryOptions } from "@/api/redmine/hooks/useRedminePaginatedInfiniteQuery"; +import { RedmineApiClient } from "@/api/redmine/RedmineApiClient"; + +/** + * Query redmine project memberships + */ +export const redmineProjectMembershipsQuery = (redmineApi: RedmineApiClient, projectId: number) => + redminePaginatedInfiniteQueryOptions({ + queryKey: ["redmine", "projectMemberships", projectId], + queryFn: ({ pageParam }) => redmineApi.getProjectMemberships(projectId, pageParam), + select: (data) => data.pages.map((page) => page.memberships).flat(), + }); diff --git a/src/api/redmine/queries/projectVersions.ts b/src/api/redmine/queries/projectVersions.ts new file mode 100644 index 00000000..3a44b755 --- /dev/null +++ b/src/api/redmine/queries/projectVersions.ts @@ -0,0 +1,23 @@ +import { RedmineApiClient } from "@/api/redmine/RedmineApiClient"; +import { TVersion } from "@/api/redmine/types"; +import { queryOptions } from "@tanstack/react-query"; + +/** + * Query redmine project versions + */ +export const redmineProjectVersionsQuery = (redmineApi: RedmineApiClient, projectId: number) => + queryOptions({ + queryKey: ["redmine", "projectVersions", projectId], + queryFn: () => redmineApi.getProjectVersions(projectId), + select: (data) => sortVersions(data), + }); + +/** + * Sort project versions + */ +const sortVersions = (versions: TVersion[]) => { + return versions.sort( + // Sort oldest version first. Versions without date, last + (a, b) => (b.due_date ? 1 : 0) - (a.due_date ? 1 : 0) || new Date(a.due_date ?? 0).getTime() - new Date(b.due_date ?? 0).getTime() || (b.status === "open" ? 1 : 0) - (a.status === "open" ? 1 : 0) + ); +}; diff --git a/src/api/redmine/queries/projects.ts b/src/api/redmine/queries/projects.ts new file mode 100644 index 00000000..e2380820 --- /dev/null +++ b/src/api/redmine/queries/projects.ts @@ -0,0 +1,22 @@ +import { redminePaginatedInfiniteQueryOptions } from "@/api/redmine/hooks/useRedminePaginatedInfiniteQuery"; +import { RedmineApiClient } from "@/api/redmine/RedmineApiClient"; +import { queryOptions } from "@tanstack/react-query"; + +/** + * Query single redmine project + */ +export const redmineProjectQuery = (redmineApi: RedmineApiClient, projectId: number) => + queryOptions({ + queryKey: ["redmine", "projects", projectId], + queryFn: () => redmineApi.getProject(projectId), + }); + +/** + * Query all redmine projects + */ +export const redmineProjectsQuery = (redmineApi: RedmineApiClient) => + redminePaginatedInfiniteQueryOptions({ + queryKey: ["redmine", "projects"], + queryFn: ({ pageParam }) => redmineApi.getProjects(pageParam), + select: (data) => data.pages.map((page) => page.projects).flat(), + }); diff --git a/src/api/redmine/queries/roles.ts b/src/api/redmine/queries/roles.ts new file mode 100644 index 00000000..8f46043f --- /dev/null +++ b/src/api/redmine/queries/roles.ts @@ -0,0 +1,20 @@ +import { RedmineApiClient } from "@/api/redmine/RedmineApiClient"; +import { queryOptions } from "@tanstack/react-query"; + +/** + * Query all redmine roles + */ +export const redmineRolesQuery = (redmineApi: RedmineApiClient) => + queryOptions({ + queryKey: ["redmine", "roles"], + queryFn: () => redmineApi.getRoles(), + }); + +/** + * Query single redmine role + */ +export const redmineRoleQuery = (redmineApi: RedmineApiClient, roleId: number) => + queryOptions({ + queryKey: ["redmine", "roles", roleId], + queryFn: () => redmineApi.getRole(roleId), + }); diff --git a/src/api/redmine/queries/search.ts b/src/api/redmine/queries/search.ts new file mode 100644 index 00000000..7dcbe6c6 --- /dev/null +++ b/src/api/redmine/queries/search.ts @@ -0,0 +1,12 @@ +import { redminePaginatedInfiniteQueryOptions } from "@/api/redmine/hooks/useRedminePaginatedInfiniteQuery"; +import { RedmineApiClient } from "@/api/redmine/RedmineApiClient"; + +/** + * Query redmine issues by search query + */ +export const redmineSearchIssuesQuery = (redmineApi: RedmineApiClient, options: Parameters[0]) => + redminePaginatedInfiniteQueryOptions({ + queryKey: ["redmine", "search", options], + queryFn: ({ pageParam }) => redmineApi.searchIssues(options, pageParam), + select: (data) => data.pages.map((page) => page.results).flat(), + }); diff --git a/src/api/redmine/queries/timeEntries.ts b/src/api/redmine/queries/timeEntries.ts new file mode 100644 index 00000000..c9061f44 --- /dev/null +++ b/src/api/redmine/queries/timeEntries.ts @@ -0,0 +1,22 @@ +import { redminePaginatedInfiniteQueryOptions } from "@/api/redmine/hooks/useRedminePaginatedInfiniteQuery"; +import { RedmineApiClient } from "@/api/redmine/RedmineApiClient"; +import { InvalidateQueryFilters } from "@tanstack/react-query"; + +const STALE_TIME = 1000 * 60; +const AUTO_REFRESH_INTERVAL = 1000 * 60 * 15; + +export const redmineTimeEntriesQueries = { + queryKey: ["redmine", "timeEntries"], +} satisfies InvalidateQueryFilters; + +/** + * Query multiple redmine time entries + */ +export const redmineTimeEntriesQuery = (redmineApi: RedmineApiClient, options: Parameters[0]) => + redminePaginatedInfiniteQueryOptions({ + queryKey: ["redmine", "timeEntries", options], + queryFn: ({ pageParam }) => redmineApi.getTimeEntries(options, pageParam), + select: (data) => data.pages.map((page) => page.time_entries).flat(), + staleTime: STALE_TIME, + refetchInterval: AUTO_REFRESH_INTERVAL, + }); diff --git a/src/api/redmine/queries/timeEntryActivities.ts b/src/api/redmine/queries/timeEntryActivities.ts new file mode 100644 index 00000000..15d79d73 --- /dev/null +++ b/src/api/redmine/queries/timeEntryActivities.ts @@ -0,0 +1,11 @@ +import { RedmineApiClient } from "@/api/redmine/RedmineApiClient"; +import { queryOptions } from "@tanstack/react-query"; + +/** + * Query redmine time entry activities + */ +export const redmineTimeEntryActivitiesQuery = (redmineApi: RedmineApiClient) => + queryOptions({ + queryKey: ["redmine", "timeEntryActivities"], + queryFn: () => redmineApi.getTimeEntryActivities(), + }); diff --git a/src/types/redmine.ts b/src/api/redmine/types.ts similarity index 88% rename from src/types/redmine.ts rename to src/api/redmine/types.ts index 508e6606..231c5522 100644 --- a/src/types/redmine.ts +++ b/src/api/redmine/types.ts @@ -20,7 +20,7 @@ export type TIssue = { author: TReference; assigned_to?: TReference; subject: string; - description: string; + description?: string; done_ratio: number; fixed_version?: TReference; start_date?: string; // YYYY-MM-DD @@ -37,6 +37,7 @@ export type TIssue = { updated_on: string; closed_on?: string; allowed_statuses?: TIssueStatus[]; // available since Redmine 5.0.0 + custom_fields?: TCustomFieldValue[]; }; export type TCreateIssue = { @@ -44,21 +45,21 @@ export type TCreateIssue = { tracker_id: number; status_id: number; priority_id: number; - category_id?: number; - assigned_to_id?: number; + category_id?: number | null; + assigned_to_id?: number | null; subject: string; - description?: string; - fixed_version_id?: number; - parent_issue_id?: number; + description?: string | null; + fixed_version_id?: number | null; + parent_issue_id?: number | null; is_private?: boolean; - start_date?: Date; - due_date?: Date; - estimated_hours?: number; - done_ratio?: number; + start_date?: Date | null; + due_date?: Date | null; + estimated_hours?: number | null; + done_ratio?: number | null; }; export type TUpdateIssue = Partial & { - notes?: string; + notes?: string | null; private_notes?: boolean; }; @@ -67,6 +68,7 @@ export type TIssuePriority = { name: string; is_default: boolean; active: boolean; // available since Redmine 4.1.0 + custom_fields?: TCustomFieldValue[]; }; export type TIssueTracker = { @@ -89,8 +91,9 @@ export type TSearchResult = { export type TProject = { id: number; name: string; - description: string; identifier: string; + description: string; + homepage?: string; inherit_members: boolean; // available since Redmine 4.1.0 is_public: boolean; status: number; @@ -101,6 +104,7 @@ export type TProject = { time_entry_activities?: TReference[]; // available since Redmine 3.4.0 created_on: string; updated_on: string; + custom_fields?: TCustomFieldValue[]; }; export type TMembership = { @@ -126,6 +130,7 @@ export type TVersion = { wiki_page_title: string; created_on: string; updated_on: string; + custom_fields?: TCustomFieldValue[]; }; /* export type TIssueCategory = { @@ -149,6 +154,7 @@ export type TTimeEntry = { spent_on: string; created_on: string; updated_on: string; + custom_fields?: TCustomFieldValue[]; }; export type TTimeEntryActivity = { @@ -156,15 +162,16 @@ export type TTimeEntryActivity = { name: string; is_default: boolean; active?: boolean; // available since Redmine 4.1.0 + custom_fields?: TCustomFieldValue[]; }; export type TCreateTimeEntry = { issue_id: number; - user_id: number; + user_id?: number; spent_on: Date; activity_id: number; hours: number; - comments?: string; + comments?: string | null; }; export type TUpdateTimeEntry = Partial & { @@ -268,9 +275,18 @@ export type TUser = { updated_on: string; last_login_on: string; passwd_changed_on: string; + avatar_url?: string; // available since Redmine 5.0.0 memberships?: TMembership[]; }; +// Customer fields +export type TCustomFieldValue = { + id: number; + name: string; + multiple?: boolean; + value: null | string | string[]; +}; + // Other export type TRedmineError = { errors: string[]; diff --git a/src/assets/themes/dark.css b/src/assets/themes/dark.css deleted file mode 100644 index 6d1bff14..00000000 --- a/src/assets/themes/dark.css +++ /dev/null @@ -1,820 +0,0 @@ -@media (prefers-color-scheme: dark) { - .flatpickr-calendar { - background: transparent; - opacity: 0; - display: none; - text-align: center; - visibility: hidden; - padding: 0; - -webkit-animation: none; - animation: none; - direction: ltr; - border: 0; - font-size: 14px; - line-height: 24px; - border-radius: 5px; - position: absolute; - width: 307.875px; - -webkit-box-sizing: border-box; - box-sizing: border-box; - -ms-touch-action: manipulation; - touch-action: manipulation; - background: var(--color-background); - -webkit-box-shadow: - 1px 0 0 #20222c, - -1px 0 0 #20222c, - 0 1px 0 #20222c, - 0 -1px 0 #20222c, - 0 3px 13px rgba(0, 0, 0, 0.08); - box-shadow: - 1px 0 0 #20222c, - -1px 0 0 #20222c, - 0 1px 0 #20222c, - 0 -1px 0 #20222c, - 0 3px 13px rgba(0, 0, 0, 0.08); - border: 1px solid var(--color-background-inner); - } - .flatpickr-calendar.open, - .flatpickr-calendar.inline { - opacity: 1; - max-height: 640px; - visibility: visible; - } - .flatpickr-calendar.open { - display: inline-block; - z-index: 99999; - } - .flatpickr-calendar.animate.open { - -webkit-animation: fpFadeInDown 300ms cubic-bezier(0.23, 1, 0.32, 1); - animation: fpFadeInDown 300ms cubic-bezier(0.23, 1, 0.32, 1); - } - .flatpickr-calendar.inline { - display: block; - position: relative; - top: 2px; - } - .flatpickr-calendar.static { - position: absolute; - top: calc(100% + 2px); - } - .flatpickr-calendar.static.open { - z-index: 999; - display: block; - } - .flatpickr-calendar.multiMonth .flatpickr-days .dayContainer:nth-child(n + 1) .flatpickr-day.inRange:nth-child(7n + 7) { - -webkit-box-shadow: none !important; - box-shadow: none !important; - } - .flatpickr-calendar.multiMonth .flatpickr-days .dayContainer:nth-child(n + 2) .flatpickr-day.inRange:nth-child(7n + 1) { - -webkit-box-shadow: - -2px 0 0 #e6e6e6, - 5px 0 0 #e6e6e6; - box-shadow: - -2px 0 0 #e6e6e6, - 5px 0 0 #e6e6e6; - } - .flatpickr-calendar .hasWeeks .dayContainer, - .flatpickr-calendar .hasTime .dayContainer { - border-bottom: 0; - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; - } - .flatpickr-calendar .hasWeeks .dayContainer { - border-left: 0; - } - .flatpickr-calendar.hasTime .flatpickr-time { - height: 40px; - border-top: 1px solid #20222c; - } - .flatpickr-calendar.noCalendar.hasTime .flatpickr-time { - height: auto; - } - .flatpickr-calendar:before, - .flatpickr-calendar:after { - position: absolute; - display: block; - pointer-events: none; - border: solid transparent; - content: ""; - height: 0; - width: 0; - left: 22px; - } - .flatpickr-calendar.rightMost:before, - .flatpickr-calendar.arrowRight:before, - .flatpickr-calendar.rightMost:after, - .flatpickr-calendar.arrowRight:after { - left: auto; - right: 22px; - } - .flatpickr-calendar.arrowCenter:before, - .flatpickr-calendar.arrowCenter:after { - left: 50%; - right: 50%; - } - .flatpickr-calendar:before { - border-width: 5px; - margin: 0 -5px; - } - .flatpickr-calendar:after { - border-width: 4px; - margin: 0 -4px; - } - .flatpickr-calendar.arrowTop:before, - .flatpickr-calendar.arrowTop:after { - bottom: 100%; - } - .flatpickr-calendar.arrowTop:before { - border-bottom-color: #20222c; - } - .flatpickr-calendar.arrowTop:after { - border-bottom-color: var(--color-background); - } - .flatpickr-calendar.arrowBottom:before, - .flatpickr-calendar.arrowBottom:after { - top: 100%; - } - .flatpickr-calendar.arrowBottom:before { - border-top-color: #20222c; - } - .flatpickr-calendar.arrowBottom:after { - border-top-color: var(--color-background); - } - .flatpickr-calendar:focus { - outline: 0; - } - .flatpickr-wrapper { - position: relative; - display: inline-block; - } - .flatpickr-months { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - } - .flatpickr-months .flatpickr-month { - background: transparent; - color: #fff; - fill: #fff; - height: 34px; - line-height: 1; - text-align: center; - position: relative; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - overflow: hidden; - -webkit-box-flex: 1; - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - } - .flatpickr-months .flatpickr-prev-month, - .flatpickr-months .flatpickr-next-month { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - text-decoration: none; - cursor: pointer; - position: absolute; - top: 0; - height: 34px; - padding: 10px; - z-index: 3; - color: #fff; - fill: #fff; - } - .flatpickr-months .flatpickr-prev-month.flatpickr-disabled, - .flatpickr-months .flatpickr-next-month.flatpickr-disabled { - display: none; - } - .flatpickr-months .flatpickr-prev-month i, - .flatpickr-months .flatpickr-next-month i { - position: relative; - } - .flatpickr-months .flatpickr-prev-month.flatpickr-prev-month, - .flatpickr-months .flatpickr-next-month.flatpickr-prev-month { - /* - /*rtl:begin:ignore*/ - /* - */ - left: 0; - /* - /*rtl:end:ignore*/ - /* - */ - } - /* - /*rtl:begin:ignore*/ - /* - /*rtl:end:ignore*/ - .flatpickr-months .flatpickr-prev-month.flatpickr-next-month, - .flatpickr-months .flatpickr-next-month.flatpickr-next-month { - /* - /*rtl:begin:ignore*/ - /* - */ - right: 0; - /* - /*rtl:end:ignore*/ - /* - */ - } - /* - /*rtl:begin:ignore*/ - /* - /*rtl:end:ignore*/ - .flatpickr-months .flatpickr-prev-month:hover, - .flatpickr-months .flatpickr-next-month:hover { - color: #eee; - } - .flatpickr-months .flatpickr-prev-month:hover svg, - .flatpickr-months .flatpickr-next-month:hover svg { - fill: var(--color-primary); - } - .flatpickr-months .flatpickr-prev-month svg, - .flatpickr-months .flatpickr-next-month svg { - width: 14px; - height: 14px; - } - .flatpickr-months .flatpickr-prev-month svg path, - .flatpickr-months .flatpickr-next-month svg path { - -webkit-transition: fill 0.1s; - transition: fill 0.1s; - fill: inherit; - } - .numInputWrapper { - position: relative; - height: auto; - } - .numInputWrapper input, - .numInputWrapper span { - display: inline-block; - } - .numInputWrapper input { - width: 100%; - } - .numInputWrapper input::-ms-clear { - display: none; - } - .numInputWrapper input::-webkit-outer-spin-button, - .numInputWrapper input::-webkit-inner-spin-button { - margin: 0; - -webkit-appearance: none; - } - .numInputWrapper span { - position: absolute; - right: 0; - width: 14px; - padding: 0 4px 0 2px; - height: 50%; - line-height: 50%; - opacity: 0; - cursor: pointer; - border: 1px solid rgba(255, 255, 255, 0.15); - -webkit-box-sizing: border-box; - box-sizing: border-box; - } - .numInputWrapper span:hover { - background: rgba(192, 187, 167, 0.1); - } - .numInputWrapper span:active { - background: rgba(192, 187, 167, 0.2); - } - .numInputWrapper span:after { - display: block; - content: ""; - position: absolute; - } - .numInputWrapper span.arrowUp { - top: 0; - border-bottom: 0; - } - .numInputWrapper span.arrowUp:after { - border-left: 4px solid transparent; - border-right: 4px solid transparent; - border-bottom: 4px solid rgba(255, 255, 255, 0.6); - top: 26%; - } - .numInputWrapper span.arrowDown { - top: 50%; - } - .numInputWrapper span.arrowDown:after { - border-left: 4px solid transparent; - border-right: 4px solid transparent; - border-top: 4px solid rgba(255, 255, 255, 0.6); - top: 40%; - } - .numInputWrapper span svg { - width: inherit; - height: auto; - } - .numInputWrapper span svg path { - fill: rgba(255, 255, 255, 0.5); - } - .numInputWrapper:hover { - background: rgba(192, 187, 167, 0.05); - } - .numInputWrapper:hover span { - opacity: 1; - } - .flatpickr-current-month { - font-size: 135%; - line-height: inherit; - font-weight: 300; - color: inherit; - position: absolute; - width: 75%; - left: 12.5%; - padding: 7.48px 0 0 0; - line-height: 1; - height: 34px; - display: inline-block; - text-align: center; - -webkit-transform: translate3d(0px, 0px, 0px); - transform: translate3d(0px, 0px, 0px); - } - .flatpickr-current-month span.cur-month { - font-family: inherit; - font-weight: 700; - color: inherit; - display: inline-block; - margin-left: 0.5ch; - padding: 0; - } - .flatpickr-current-month span.cur-month:hover { - background: rgba(192, 187, 167, 0.05); - } - .flatpickr-current-month .numInputWrapper { - width: 6ch; - width: 7ch\0; - display: inline-block; - } - .flatpickr-current-month .numInputWrapper span.arrowUp:after { - border-bottom-color: #fff; - } - .flatpickr-current-month .numInputWrapper span.arrowDown:after { - border-top-color: #fff; - } - .flatpickr-current-month input.cur-year { - background: transparent; - -webkit-box-sizing: border-box; - box-sizing: border-box; - color: inherit; - cursor: text; - padding: 0 0 0 0.5ch; - margin: 0; - display: inline-block; - font-size: inherit; - font-family: inherit; - font-weight: 300; - line-height: inherit; - height: auto; - border: 0; - border-radius: 0; - vertical-align: initial; - -webkit-appearance: textfield; - -moz-appearance: textfield; - appearance: textfield; - } - .flatpickr-current-month input.cur-year:focus { - outline: 0; - } - .flatpickr-current-month input.cur-year[disabled], - .flatpickr-current-month input.cur-year[disabled]:hover { - font-size: 100%; - color: rgba(255, 255, 255, 0.5); - background: transparent; - pointer-events: none; - } - .flatpickr-current-month .flatpickr-monthDropdown-months { - appearance: menulist; - background: var(--color-background); - border: none; - border-radius: 0; - box-sizing: border-box; - color: inherit; - cursor: pointer; - font-size: inherit; - font-family: inherit; - font-weight: 300; - height: auto; - line-height: inherit; - margin: -1px 0 0 0; - outline: none; - padding: 0 0 0 0.5ch; - position: relative; - vertical-align: initial; - -webkit-box-sizing: border-box; - -webkit-appearance: menulist; - -moz-appearance: menulist; - width: auto; - } - .flatpickr-current-month .flatpickr-monthDropdown-months:focus, - .flatpickr-current-month .flatpickr-monthDropdown-months:active { - outline: none; - } - .flatpickr-current-month .flatpickr-monthDropdown-months:hover { - background: rgba(192, 187, 167, 0.05); - } - .flatpickr-current-month .flatpickr-monthDropdown-months .flatpickr-monthDropdown-month { - background-color: var(--color-background); - outline: none; - padding: 0; - } - .flatpickr-weekdays { - background: var(--color-background-inner); - text-align: center; - overflow: hidden; - width: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-align: center; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - height: 28px; - } - .flatpickr-weekdays .flatpickr-weekdaycontainer { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-flex: 1; - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - } - span.flatpickr-weekday { - cursor: default; - font-size: 90%; - background: transparent; - color: #fff; - line-height: 1; - margin: 0; - text-align: center; - display: block; - -webkit-box-flex: 1; - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - font-weight: bolder; - } - .dayContainer, - .flatpickr-weeks { - padding: 1px 0 0 0; - } - .flatpickr-days { - position: relative; - overflow: hidden; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-align: start; - -webkit-align-items: flex-start; - -ms-flex-align: start; - align-items: flex-start; - width: 307.875px; - } - .flatpickr-days:focus { - outline: 0; - } - .dayContainer { - padding: 0; - outline: 0; - text-align: left; - width: 307.875px; - min-width: 307.875px; - max-width: 307.875px; - -webkit-box-sizing: border-box; - box-sizing: border-box; - display: inline-block; - display: -ms-flexbox; - display: -webkit-box; - display: -webkit-flex; - display: flex; - -webkit-flex-wrap: wrap; - flex-wrap: wrap; - -ms-flex-wrap: wrap; - -ms-flex-pack: justify; - -webkit-justify-content: space-around; - justify-content: space-around; - -webkit-transform: translate3d(0px, 0px, 0px); - transform: translate3d(0px, 0px, 0px); - opacity: 1; - } - .dayContainer + .dayContainer { - -webkit-box-shadow: -1px 0 0 #20222c; - box-shadow: -1px 0 0 #20222c; - } - .flatpickr-day { - background: none; - border: 1px solid transparent; - border-radius: 150px; - -webkit-box-sizing: border-box; - box-sizing: border-box; - color: rgba(255, 255, 255, 0.95); - cursor: pointer; - font-weight: 400; - width: 14.2857143%; - -webkit-flex-basis: 14.2857143%; - -ms-flex-preferred-size: 14.2857143%; - flex-basis: 14.2857143%; - max-width: 39px; - height: 39px; - line-height: 39px; - margin: 0; - display: inline-block; - position: relative; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - text-align: center; - } - .flatpickr-day.inRange, - .flatpickr-day.prevMonthDay.inRange, - .flatpickr-day.nextMonthDay.inRange, - .flatpickr-day.today.inRange, - .flatpickr-day.prevMonthDay.today.inRange, - .flatpickr-day.nextMonthDay.today.inRange, - .flatpickr-day:hover, - .flatpickr-day.prevMonthDay:hover, - .flatpickr-day.nextMonthDay:hover, - .flatpickr-day:focus, - .flatpickr-day.prevMonthDay:focus, - .flatpickr-day.nextMonthDay:focus { - cursor: pointer; - outline: 0; - background: var(--color-background-hover); - border-color: var(--color-primary); - } - .flatpickr-day.today { - border-color: var(--color-primary); - } - .flatpickr-day.today:hover, - .flatpickr-day.today:focus { - border-color: var(--color-primary); - background: var(--color-primary); - color: #fff; - } - .flatpickr-day.selected, - .flatpickr-day.startRange, - .flatpickr-day.endRange, - .flatpickr-day.selected.inRange, - .flatpickr-day.startRange.inRange, - .flatpickr-day.endRange.inRange, - .flatpickr-day.selected:focus, - .flatpickr-day.startRange:focus, - .flatpickr-day.endRange:focus, - .flatpickr-day.selected:hover, - .flatpickr-day.startRange:hover, - .flatpickr-day.endRange:hover, - .flatpickr-day.selected.prevMonthDay, - .flatpickr-day.startRange.prevMonthDay, - .flatpickr-day.endRange.prevMonthDay, - .flatpickr-day.selected.nextMonthDay, - .flatpickr-day.startRange.nextMonthDay, - .flatpickr-day.endRange.nextMonthDay { - background: var(--color-primary); - -webkit-box-shadow: none; - box-shadow: none; - color: #fff; - border-color: var(--color-primary); - } - .flatpickr-day.selected.startRange, - .flatpickr-day.startRange.startRange, - .flatpickr-day.endRange.startRange { - border-radius: 50px 0 0 50px; - } - .flatpickr-day.selected.endRange, - .flatpickr-day.startRange.endRange, - .flatpickr-day.endRange.endRange { - border-radius: 0 50px 50px 0; - } - .flatpickr-day.selected.startRange + .endRange:not(:nth-child(7n + 1)), - .flatpickr-day.startRange.startRange + .endRange:not(:nth-child(7n + 1)), - .flatpickr-day.endRange.startRange + .endRange:not(:nth-child(7n + 1)) { - -webkit-box-shadow: -10px 0 0 var(--color-primary); - box-shadow: -10px 0 0 var(--color-primary); - } - .flatpickr-day.selected.startRange.endRange, - .flatpickr-day.startRange.startRange.endRange, - .flatpickr-day.endRange.startRange.endRange { - border-radius: 50px; - } - .flatpickr-day.inRange { - border-radius: 0; - -webkit-box-shadow: - -5px 0 0 #646c8c, - 5px 0 0 #646c8c; - box-shadow: - -5px 0 0 #646c8c, - 5px 0 0 #646c8c; - } - .flatpickr-day.flatpickr-disabled, - .flatpickr-day.flatpickr-disabled:hover, - .flatpickr-day.prevMonthDay, - .flatpickr-day.nextMonthDay, - .flatpickr-day.notAllowed, - .flatpickr-day.notAllowed.prevMonthDay, - .flatpickr-day.notAllowed.nextMonthDay { - color: rgba(255, 255, 255, 0.3); - background: transparent; - border-color: transparent; - cursor: default; - } - .flatpickr-day.flatpickr-disabled, - .flatpickr-day.flatpickr-disabled:hover { - cursor: not-allowed; - color: rgba(255, 255, 255, 0.1); - } - .flatpickr-day.week.selected { - border-radius: 0; - -webkit-box-shadow: - -5px 0 0 var(--color-primary), - 5px 0 0 var(--color-primary); - box-shadow: - -5px 0 0 var(--color-primary), - 5px 0 0 var(--color-primary); - } - .flatpickr-day.hidden { - visibility: hidden; - } - .rangeMode .flatpickr-day { - margin-top: 1px; - } - .flatpickr-weekwrapper { - float: left; - } - .flatpickr-weekwrapper .flatpickr-weeks { - padding: 0 12px; - -webkit-box-shadow: 1px 0 0 #20222c; - box-shadow: 1px 0 0 #20222c; - } - .flatpickr-weekwrapper .flatpickr-weekday { - float: none; - width: 100%; - line-height: 28px; - } - .flatpickr-weekwrapper span.flatpickr-day, - .flatpickr-weekwrapper span.flatpickr-day:hover { - display: block; - width: 100%; - max-width: none; - color: rgba(255, 255, 255, 0.3); - background: transparent; - cursor: default; - border: none; - } - .flatpickr-innerContainer { - display: block; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-sizing: border-box; - box-sizing: border-box; - overflow: hidden; - } - .flatpickr-rContainer { - display: inline-block; - padding: 0; - -webkit-box-sizing: border-box; - box-sizing: border-box; - } - .flatpickr-time { - text-align: center; - outline: 0; - display: block; - height: 0; - line-height: 40px; - max-height: 40px; - -webkit-box-sizing: border-box; - box-sizing: border-box; - overflow: hidden; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - } - .flatpickr-time:after { - content: ""; - display: table; - clear: both; - } - .flatpickr-time .numInputWrapper { - -webkit-box-flex: 1; - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - width: 40%; - height: 40px; - float: left; - } - .flatpickr-time .numInputWrapper span.arrowUp:after { - border-bottom-color: rgba(255, 255, 255, 0.95); - } - .flatpickr-time .numInputWrapper span.arrowDown:after { - border-top-color: rgba(255, 255, 255, 0.95); - } - .flatpickr-time.hasSeconds .numInputWrapper { - width: 26%; - } - .flatpickr-time.time24hr .numInputWrapper { - width: 49%; - } - .flatpickr-time input { - background: transparent; - -webkit-box-shadow: none; - box-shadow: none; - border: 0; - border-radius: 0; - text-align: center; - margin: 0; - padding: 0; - height: inherit; - line-height: inherit; - color: rgba(255, 255, 255, 0.95); - font-size: 14px; - position: relative; - -webkit-box-sizing: border-box; - box-sizing: border-box; - -webkit-appearance: textfield; - -moz-appearance: textfield; - appearance: textfield; - } - .flatpickr-time input.flatpickr-hour { - font-weight: bold; - } - .flatpickr-time input.flatpickr-minute, - .flatpickr-time input.flatpickr-second { - font-weight: 400; - } - .flatpickr-time input:focus { - outline: 0; - border: 0; - } - .flatpickr-time .flatpickr-time-separator, - .flatpickr-time .flatpickr-am-pm { - height: inherit; - float: left; - line-height: inherit; - color: rgba(255, 255, 255, 0.95); - font-weight: bold; - width: 2%; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-align-self: center; - -ms-flex-item-align: center; - align-self: center; - } - .flatpickr-time .flatpickr-am-pm { - outline: 0; - width: 18%; - cursor: pointer; - text-align: center; - font-weight: 400; - } - .flatpickr-time input:hover, - .flatpickr-time .flatpickr-am-pm:hover, - .flatpickr-time input:focus, - .flatpickr-time .flatpickr-am-pm:focus { - background: #6a7395; - } - .flatpickr-input[readonly] { - cursor: pointer; - } - @-webkit-keyframes fpFadeInDown { - from { - opacity: 0; - -webkit-transform: translate3d(0, -20px, 0); - transform: translate3d(0, -20px, 0); - } - to { - opacity: 1; - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - } - @keyframes fpFadeInDown { - from { - opacity: 0; - -webkit-transform: translate3d(0, -20px, 0); - transform: translate3d(0, -20px, 0); - } - to { - opacity: 1; - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - } -} diff --git a/src/assets/themes/light.css b/src/assets/themes/light.css deleted file mode 100644 index 33e164cc..00000000 --- a/src/assets/themes/light.css +++ /dev/null @@ -1,825 +0,0 @@ -@media (prefers-color-scheme: light) { - .flatpickr-calendar { - background: transparent; - opacity: 0; - display: none; - text-align: center; - visibility: hidden; - padding: 0; - -webkit-animation: none; - animation: none; - direction: ltr; - border: 0; - font-size: 14px; - line-height: 24px; - border-radius: 5px; - position: absolute; - width: 307.875px; - -webkit-box-sizing: border-box; - box-sizing: border-box; - -ms-touch-action: manipulation; - touch-action: manipulation; - background: var(--color-background); - -webkit-box-shadow: 0 3px 13px rgba(0, 0, 0, 0.08); - box-shadow: 0 3px 13px rgba(0, 0, 0, 0.08); - border: 1px solid var(--color-background-inner); - } - .flatpickr-calendar.open, - .flatpickr-calendar.inline { - opacity: 1; - max-height: 640px; - visibility: visible; - } - .flatpickr-calendar.open { - display: inline-block; - z-index: 99999; - } - .flatpickr-calendar.animate.open { - -webkit-animation: fpFadeInDown 300ms cubic-bezier(0.23, 1, 0.32, 1); - animation: fpFadeInDown 300ms cubic-bezier(0.23, 1, 0.32, 1); - } - .flatpickr-calendar.inline { - display: block; - position: relative; - top: 2px; - } - .flatpickr-calendar.static { - position: absolute; - top: calc(100% + 2px); - } - .flatpickr-calendar.static.open { - z-index: 999; - display: block; - } - .flatpickr-calendar.multiMonth .flatpickr-days .dayContainer:nth-child(n + 1) .flatpickr-day.inRange:nth-child(7n + 7) { - -webkit-box-shadow: none !important; - box-shadow: none !important; - } - .flatpickr-calendar.multiMonth .flatpickr-days .dayContainer:nth-child(n + 2) .flatpickr-day.inRange:nth-child(7n + 1) { - -webkit-box-shadow: - -2px 0 0 #e6e6e6, - 5px 0 0 #e6e6e6; - box-shadow: - -2px 0 0 #e6e6e6, - 5px 0 0 #e6e6e6; - } - .flatpickr-calendar .hasWeeks .dayContainer, - .flatpickr-calendar .hasTime .dayContainer { - border-bottom: 0; - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; - } - .flatpickr-calendar .hasWeeks .dayContainer { - border-left: 0; - } - .flatpickr-calendar.hasTime .flatpickr-time { - height: 40px; - border-top: 1px solid var(--color-background); - } - .flatpickr-calendar.hasTime .flatpickr-innerContainer { - border-bottom: 0; - } - .flatpickr-calendar.hasTime .flatpickr-time { - border: 1px solid var(--color-background); - } - .flatpickr-calendar.noCalendar.hasTime .flatpickr-time { - height: auto; - } - .flatpickr-calendar:before, - .flatpickr-calendar:after { - position: absolute; - display: block; - pointer-events: none; - border: solid transparent; - content: ""; - height: 0; - width: 0; - left: 22px; - } - .flatpickr-calendar.rightMost:before, - .flatpickr-calendar.arrowRight:before, - .flatpickr-calendar.rightMost:after, - .flatpickr-calendar.arrowRight:after { - left: auto; - right: 22px; - } - .flatpickr-calendar.arrowCenter:before, - .flatpickr-calendar.arrowCenter:after { - left: 50%; - right: 50%; - } - .flatpickr-calendar:before { - border-width: 5px; - margin: 0 -5px; - } - .flatpickr-calendar:after { - border-width: 4px; - margin: 0 -4px; - } - .flatpickr-calendar.arrowTop:before, - .flatpickr-calendar.arrowTop:after { - bottom: 100%; - } - .flatpickr-calendar.arrowTop:before { - border-bottom-color: var(--color-background); - } - .flatpickr-calendar.arrowTop:after { - border-bottom-color: var(--color-background); - } - .flatpickr-calendar.arrowBottom:before, - .flatpickr-calendar.arrowBottom:after { - top: 100%; - } - .flatpickr-calendar.arrowBottom:before { - border-top-color: var(--color-background); - } - .flatpickr-calendar.arrowBottom:after { - border-top-color: var(--color-background); - } - .flatpickr-calendar:focus { - outline: 0; - } - .flatpickr-wrapper { - position: relative; - display: inline-block; - } - .flatpickr-months { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - } - .flatpickr-months .flatpickr-month { - border-radius: 5px 5px 0 0; - background: transparent; - color: #5a6171; - fill: #5a6171; - height: 34px; - line-height: 1; - text-align: center; - position: relative; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - overflow: hidden; - -webkit-box-flex: 1; - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - } - .flatpickr-months .flatpickr-prev-month, - .flatpickr-months .flatpickr-next-month { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - text-decoration: none; - cursor: pointer; - position: absolute; - top: 0; - height: 34px; - padding: 10px; - z-index: 3; - color: #5a6171; - fill: #5a6171; - } - .flatpickr-months .flatpickr-prev-month.flatpickr-disabled, - .flatpickr-months .flatpickr-next-month.flatpickr-disabled { - display: none; - } - .flatpickr-months .flatpickr-prev-month i, - .flatpickr-months .flatpickr-next-month i { - position: relative; - } - .flatpickr-months .flatpickr-prev-month.flatpickr-prev-month, - .flatpickr-months .flatpickr-next-month.flatpickr-prev-month { - /* - /*rtl:begin:ignore*/ - /* - */ - left: 0; - /* - /*rtl:end:ignore*/ - /* - */ - } - /* - /*rtl:begin:ignore*/ - /* - /*rtl:end:ignore*/ - .flatpickr-months .flatpickr-prev-month.flatpickr-next-month, - .flatpickr-months .flatpickr-next-month.flatpickr-next-month { - /* - /*rtl:begin:ignore*/ - /* - */ - right: 0; - /* - /*rtl:end:ignore*/ - /* - */ - } - /* - /*rtl:begin:ignore*/ - /* - /*rtl:end:ignore*/ - .flatpickr-months .flatpickr-prev-month:hover, - .flatpickr-months .flatpickr-next-month:hover { - color: #bbb; - } - .flatpickr-months .flatpickr-prev-month:hover svg, - .flatpickr-months .flatpickr-next-month:hover svg { - fill: var(--color-primary); - } - .flatpickr-months .flatpickr-prev-month svg, - .flatpickr-months .flatpickr-next-month svg { - width: 14px; - height: 14px; - } - .flatpickr-months .flatpickr-prev-month svg path, - .flatpickr-months .flatpickr-next-month svg path { - -webkit-transition: fill 0.1s; - transition: fill 0.1s; - fill: inherit; - } - .numInputWrapper { - position: relative; - height: auto; - } - .numInputWrapper input, - .numInputWrapper span { - display: inline-block; - } - .numInputWrapper input { - width: 100%; - } - .numInputWrapper input::-ms-clear { - display: none; - } - .numInputWrapper input::-webkit-outer-spin-button, - .numInputWrapper input::-webkit-inner-spin-button { - margin: 0; - -webkit-appearance: none; - } - .numInputWrapper span { - position: absolute; - right: 0; - width: 14px; - padding: 0 4px 0 2px; - height: 50%; - line-height: 50%; - opacity: 0; - cursor: pointer; - border: 1px solid rgba(72, 72, 72, 0.15); - -webkit-box-sizing: border-box; - box-sizing: border-box; - } - .numInputWrapper span:hover { - background: rgba(0, 0, 0, 0.1); - } - .numInputWrapper span:active { - background: rgba(0, 0, 0, 0.2); - } - .numInputWrapper span:after { - display: block; - content: ""; - position: absolute; - } - .numInputWrapper span.arrowUp { - top: 0; - border-bottom: 0; - } - .numInputWrapper span.arrowUp:after { - border-left: 4px solid transparent; - border-right: 4px solid transparent; - border-bottom: 4px solid rgba(72, 72, 72, 0.6); - top: 26%; - } - .numInputWrapper span.arrowDown { - top: 50%; - } - .numInputWrapper span.arrowDown:after { - border-left: 4px solid transparent; - border-right: 4px solid transparent; - border-top: 4px solid rgba(72, 72, 72, 0.6); - top: 40%; - } - .numInputWrapper span svg { - width: inherit; - height: auto; - } - .numInputWrapper span svg path { - fill: rgba(90, 97, 113, 0.5); - } - .numInputWrapper:hover { - background: rgba(0, 0, 0, 0.05); - } - .numInputWrapper:hover span { - opacity: 1; - } - .flatpickr-current-month { - font-size: 135%; - line-height: inherit; - font-weight: 300; - color: inherit; - position: absolute; - width: 75%; - left: 12.5%; - padding: 7.48px 0 0 0; - line-height: 1; - height: 34px; - display: inline-block; - text-align: center; - -webkit-transform: translate3d(0px, 0px, 0px); - transform: translate3d(0px, 0px, 0px); - } - .flatpickr-current-month span.cur-month { - font-family: inherit; - font-weight: 700; - color: inherit; - display: inline-block; - margin-left: 0.5ch; - padding: 0; - } - .flatpickr-current-month span.cur-month:hover { - background: rgba(0, 0, 0, 0.05); - } - .flatpickr-current-month .numInputWrapper { - width: 6ch; - width: 7ch\0; - display: inline-block; - } - .flatpickr-current-month .numInputWrapper span.arrowUp:after { - border-bottom-color: #5a6171; - } - .flatpickr-current-month .numInputWrapper span.arrowDown:after { - border-top-color: #5a6171; - } - .flatpickr-current-month input.cur-year { - background: transparent; - -webkit-box-sizing: border-box; - box-sizing: border-box; - color: inherit; - cursor: text; - padding: 0 0 0 0.5ch; - margin: 0; - display: inline-block; - font-size: inherit; - font-family: inherit; - font-weight: 300; - line-height: inherit; - height: auto; - border: 0; - border-radius: 0; - vertical-align: initial; - -webkit-appearance: textfield; - -moz-appearance: textfield; - appearance: textfield; - } - .flatpickr-current-month input.cur-year:focus { - outline: 0; - } - .flatpickr-current-month input.cur-year[disabled], - .flatpickr-current-month input.cur-year[disabled]:hover { - font-size: 100%; - color: rgba(90, 97, 113, 0.5); - background: transparent; - pointer-events: none; - } - .flatpickr-current-month .flatpickr-monthDropdown-months { - appearance: menulist; - background: var(--color-background); - border: none; - border-radius: 0; - box-sizing: border-box; - color: inherit; - cursor: pointer; - font-size: inherit; - font-family: inherit; - font-weight: 300; - height: auto; - line-height: inherit; - margin: -1px 0 0 0; - outline: none; - padding: 0 0 0 0.5ch; - position: relative; - vertical-align: initial; - -webkit-box-sizing: border-box; - -webkit-appearance: menulist; - -moz-appearance: menulist; - width: auto; - } - .flatpickr-current-month .flatpickr-monthDropdown-months:focus, - .flatpickr-current-month .flatpickr-monthDropdown-months:active { - outline: none; - } - .flatpickr-current-month .flatpickr-monthDropdown-months:hover { - background: rgba(0, 0, 0, 0.05); - } - .flatpickr-current-month .flatpickr-monthDropdown-months .flatpickr-monthDropdown-month { - background-color: var(--color-background); - outline: none; - padding: 0; - } - .flatpickr-weekdays { - background: var(--color-background-inner); - text-align: center; - overflow: hidden; - width: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-align: center; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - height: 28px; - } - .flatpickr-weekdays .flatpickr-weekdaycontainer { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-flex: 1; - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - } - span.flatpickr-weekday { - cursor: default; - font-size: 90%; - background: transparent; - color: #5a6171; - line-height: 1; - margin: 0; - text-align: center; - display: block; - -webkit-box-flex: 1; - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - font-weight: bolder; - } - .dayContainer, - .flatpickr-weeks { - padding: 1px 0 0 0; - } - .flatpickr-days { - position: relative; - overflow: hidden; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-align: start; - -webkit-align-items: flex-start; - -ms-flex-align: start; - align-items: flex-start; - width: 307.875px; - border-left: 1px solid var(--color-background); - border-right: 1px solid var(--color-background); - } - .flatpickr-days:focus { - outline: 0; - } - .dayContainer { - padding: 0; - outline: 0; - text-align: left; - width: 307.875px; - min-width: 307.875px; - max-width: 307.875px; - -webkit-box-sizing: border-box; - box-sizing: border-box; - display: inline-block; - display: -ms-flexbox; - display: -webkit-box; - display: -webkit-flex; - display: flex; - -webkit-flex-wrap: wrap; - flex-wrap: wrap; - -ms-flex-wrap: wrap; - -ms-flex-pack: justify; - -webkit-justify-content: space-around; - justify-content: space-around; - -webkit-transform: translate3d(0px, 0px, 0px); - transform: translate3d(0px, 0px, 0px); - opacity: 1; - } - .dayContainer + .dayContainer { - -webkit-box-shadow: -1px 0 0 var(--color-background); - box-shadow: -1px 0 0 var(--color-background); - } - .flatpickr-day { - background: none; - border: 1px solid transparent; - border-radius: 150px; - -webkit-box-sizing: border-box; - box-sizing: border-box; - color: #484848; - cursor: pointer; - font-weight: 400; - width: 14.2857143%; - -webkit-flex-basis: 14.2857143%; - -ms-flex-preferred-size: 14.2857143%; - flex-basis: 14.2857143%; - max-width: 39px; - height: 39px; - line-height: 39px; - margin: 0; - display: inline-block; - position: relative; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - text-align: center; - } - .flatpickr-day.inRange, - .flatpickr-day.prevMonthDay.inRange, - .flatpickr-day.nextMonthDay.inRange, - .flatpickr-day.today.inRange, - .flatpickr-day.prevMonthDay.today.inRange, - .flatpickr-day.nextMonthDay.today.inRange, - .flatpickr-day:hover, - .flatpickr-day.prevMonthDay:hover, - .flatpickr-day.nextMonthDay:hover, - .flatpickr-day:focus, - .flatpickr-day.prevMonthDay:focus, - .flatpickr-day.nextMonthDay:focus { - cursor: pointer; - outline: 0; - background: var(--color-background-hover); - border-color: var(--color-primary); - } - .flatpickr-day.today { - border-color: var(--color-primary); - } - .flatpickr-day.today:hover, - .flatpickr-day.today:focus { - border-color: var(--color-primary); - background: var(--color-primary); - color: #fff; - } - .flatpickr-day.selected, - .flatpickr-day.startRange, - .flatpickr-day.endRange, - .flatpickr-day.selected.inRange, - .flatpickr-day.startRange.inRange, - .flatpickr-day.endRange.inRange, - .flatpickr-day.selected:focus, - .flatpickr-day.startRange:focus, - .flatpickr-day.endRange:focus, - .flatpickr-day.selected:hover, - .flatpickr-day.startRange:hover, - .flatpickr-day.endRange:hover, - .flatpickr-day.selected.prevMonthDay, - .flatpickr-day.startRange.prevMonthDay, - .flatpickr-day.endRange.prevMonthDay, - .flatpickr-day.selected.nextMonthDay, - .flatpickr-day.startRange.nextMonthDay, - .flatpickr-day.endRange.nextMonthDay { - background: var(--color-primary); - -webkit-box-shadow: none; - box-shadow: none; - color: #fff; - border-color: var(--color-primary); - } - .flatpickr-day.selected.startRange, - .flatpickr-day.startRange.startRange, - .flatpickr-day.endRange.startRange { - border-radius: 50px 0 0 50px; - } - .flatpickr-day.selected.endRange, - .flatpickr-day.startRange.endRange, - .flatpickr-day.endRange.endRange { - border-radius: 0 50px 50px 0; - } - .flatpickr-day.selected.startRange + .endRange:not(:nth-child(7n + 1)), - .flatpickr-day.startRange.startRange + .endRange:not(:nth-child(7n + 1)), - .flatpickr-day.endRange.startRange + .endRange:not(:nth-child(7n + 1)) { - -webkit-box-shadow: -10px 0 0 var(--color-primary); - box-shadow: -10px 0 0 var(--color-primary); - } - .flatpickr-day.selected.startRange.endRange, - .flatpickr-day.startRange.startRange.endRange, - .flatpickr-day.endRange.startRange.endRange { - border-radius: 50px; - } - .flatpickr-day.inRange { - border-radius: 0; - -webkit-box-shadow: - -5px 0 0 #e2e2e2, - 5px 0 0 #e2e2e2; - box-shadow: - -5px 0 0 #e2e2e2, - 5px 0 0 #e2e2e2; - } - .flatpickr-day.flatpickr-disabled, - .flatpickr-day.flatpickr-disabled:hover, - .flatpickr-day.prevMonthDay, - .flatpickr-day.nextMonthDay, - .flatpickr-day.notAllowed, - .flatpickr-day.notAllowed.prevMonthDay, - .flatpickr-day.notAllowed.nextMonthDay { - color: rgba(72, 72, 72, 0.3); - background: transparent; - border-color: transparent; - cursor: default; - } - .flatpickr-day.flatpickr-disabled, - .flatpickr-day.flatpickr-disabled:hover { - cursor: not-allowed; - color: rgba(10, 10, 10, 0.2); - } - .flatpickr-day.week.selected { - border-radius: 0; - -webkit-box-shadow: - -5px 0 0 var(--color-primary), - 5px 0 0 var(--color-primary); - box-shadow: - -5px 0 0 var(--color-primary), - 5px 0 0 var(--color-primary); - } - .flatpickr-day.hidden { - visibility: hidden; - } - .rangeMode .flatpickr-day { - margin-top: 1px; - } - .flatpickr-weekwrapper { - float: left; - } - .flatpickr-weekwrapper .flatpickr-weeks { - padding: 0 12px; - border-left: 1px solid var(--color-background); - } - .flatpickr-weekwrapper .flatpickr-weekday { - float: none; - width: 100%; - line-height: 28px; - } - .flatpickr-weekwrapper span.flatpickr-day, - .flatpickr-weekwrapper span.flatpickr-day:hover { - display: block; - width: 100%; - max-width: none; - color: rgba(72, 72, 72, 0.3); - background: transparent; - cursor: default; - border: none; - } - .flatpickr-innerContainer { - display: block; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-sizing: border-box; - box-sizing: border-box; - overflow: hidden; - background: #fff; - border-bottom: 1px solid var(--color-background); - } - .flatpickr-rContainer { - display: inline-block; - padding: 0; - -webkit-box-sizing: border-box; - box-sizing: border-box; - } - .flatpickr-time { - text-align: center; - outline: 0; - display: block; - height: 0; - line-height: 40px; - max-height: 40px; - -webkit-box-sizing: border-box; - box-sizing: border-box; - overflow: hidden; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - background: #fff; - border-radius: 0 0 5px 5px; - } - .flatpickr-time:after { - content: ""; - display: table; - clear: both; - } - .flatpickr-time .numInputWrapper { - -webkit-box-flex: 1; - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - width: 40%; - height: 40px; - float: left; - } - .flatpickr-time .numInputWrapper span.arrowUp:after { - border-bottom-color: #484848; - } - .flatpickr-time .numInputWrapper span.arrowDown:after { - border-top-color: #484848; - } - .flatpickr-time.hasSeconds .numInputWrapper { - width: 26%; - } - .flatpickr-time.time24hr .numInputWrapper { - width: 49%; - } - .flatpickr-time input { - background: transparent; - -webkit-box-shadow: none; - box-shadow: none; - border: 0; - border-radius: 0; - text-align: center; - margin: 0; - padding: 0; - height: inherit; - line-height: inherit; - color: #484848; - font-size: 14px; - position: relative; - -webkit-box-sizing: border-box; - box-sizing: border-box; - -webkit-appearance: textfield; - -moz-appearance: textfield; - appearance: textfield; - } - .flatpickr-time input.flatpickr-hour { - font-weight: bold; - } - .flatpickr-time input.flatpickr-minute, - .flatpickr-time input.flatpickr-second { - font-weight: 400; - } - .flatpickr-time input:focus { - outline: 0; - border: 0; - } - .flatpickr-time .flatpickr-time-separator, - .flatpickr-time .flatpickr-am-pm { - height: inherit; - float: left; - line-height: inherit; - color: #484848; - font-weight: bold; - width: 2%; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-align-self: center; - -ms-flex-item-align: center; - align-self: center; - } - .flatpickr-time .flatpickr-am-pm { - outline: 0; - width: 18%; - cursor: pointer; - text-align: center; - font-weight: 400; - } - .flatpickr-time input:hover, - .flatpickr-time .flatpickr-am-pm:hover, - .flatpickr-time input:focus, - .flatpickr-time .flatpickr-am-pm:focus { - background: #eaeaea; - } - .flatpickr-input[readonly] { - cursor: pointer; - } - @-webkit-keyframes fpFadeInDown { - from { - opacity: 0; - -webkit-transform: translate3d(0, -20px, 0); - transform: translate3d(0, -20px, 0); - } - to { - opacity: 1; - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - } - @keyframes fpFadeInDown { - from { - opacity: 0; - -webkit-transform: translate3d(0, -20px, 0); - transform: translate3d(0, -20px, 0); - } - to { - opacity: 1; - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - } - span.flatpickr-day.selected { - font-weight: bold; - } -} diff --git a/src/background.ts b/src/background.ts deleted file mode 100644 index a0c78f5c..00000000 --- a/src/background.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { getSettings } from "./provider/SettingsProvider"; - -/** - * Open options page on install and set uninstall URL - */ -chrome.runtime.onInstalled.addListener(({ reason }) => { - if (reason === chrome.runtime.OnInstalledReason.INSTALL) { - chrome.runtime.openOptionsPage(); - chrome.runtime.setUninstallURL("https://github.com/CrawlerCode/redmine-time-tracking/discussions/1"); - } -}); - -/** - * Register content script on configured Redmine URL - * and re-register on Redmine URL change - */ -const registerContentScript = async () => { - const settings = await getSettings(); - if (!settings.redmineURL) return; - - // Unregister content script - await chrome.scripting - .unregisterContentScripts({ - ids: ["content"], - }) - .catch(() => undefined); - - // If showCurrentIssueTimer is disabled, do not register content script - if (!settings.features.showCurrentIssueTimer) return; - - // Register content script - await chrome.scripting.registerContentScripts([ - { - id: "content", - js: ["inject-content-module.js"], - matches: [`${settings.redmineURL}/*`], - runAt: "document_end", - }, - ]); -}; -registerContentScript(); -chrome.runtime.onMessage.addListener((message) => { - if (["settings-changed:redmineURL", "settings-changed:showCurrentIssueTimer"].includes(message)) { - registerContentScript(); - } -}); diff --git a/src/components/error/ErrorComponent.tsx b/src/components/error/ErrorComponent.tsx new file mode 100644 index 00000000..8d2e19e5 --- /dev/null +++ b/src/components/error/ErrorComponent.tsx @@ -0,0 +1,44 @@ +import { MissingRedmineConfigError } from "@/api/redmine/MissingRedmineConfigError"; +import { getErrorMessage } from "@/utils/error"; +import { useQueryErrorResetBoundary } from "@tanstack/react-query"; +import { ErrorComponentProps } from "@tanstack/react-router"; +import { isAxiosError } from "axios"; +import { AlertCircleIcon } from "lucide-react"; +import { useIntl } from "react-intl"; +import { Alert, AlertDescription, AlertTitle } from "../ui/alert"; +import { Button } from "../ui/button"; + +export function ErrorComponent({ error, reset: resetPage }: ErrorComponentProps) { + const { formatMessage } = useIntl(); + const { reset: resetQueries } = useQueryErrorResetBoundary(); + + return ( + + + + {isAxiosError(error) + ? formatMessage({ id: "general.error.api-error" }) + : error instanceof MissingRedmineConfigError + ? formatMessage({ id: "general.error.missing-redmine-configuration" }) + : formatMessage({ id: "general.error.unknown-error" }, { name: error.name })} + + {!(error instanceof MissingRedmineConfigError) && ( + + {getErrorMessage(error)} +
+ +
+
+ )} +
+ ); +} diff --git a/src/components/error/GlobalErrorComponent.tsx b/src/components/error/GlobalErrorComponent.tsx new file mode 100644 index 00000000..523be567 --- /dev/null +++ b/src/components/error/GlobalErrorComponent.tsx @@ -0,0 +1,12 @@ +import { ErrorComponentProps } from "@tanstack/react-router"; +import { ErrorComponent } from "./ErrorComponent"; + +export function GlobalErrorComponent(props: ErrorComponentProps) { + return ( +
+
+ +
+
+ ); +} diff --git a/src/components/error/NotFoundComponent.tsx b/src/components/error/NotFoundComponent.tsx new file mode 100644 index 00000000..4d06f007 --- /dev/null +++ b/src/components/error/NotFoundComponent.tsx @@ -0,0 +1,14 @@ +import { AlertCircleIcon } from "lucide-react"; +import { FormattedMessage } from "react-intl"; +import { Alert, AlertTitle } from "../ui/alert"; + +export function NotFoundComponent() { + return ( + + + + + + + ); +} diff --git a/src/components/form/CheckboxField.tsx b/src/components/form/CheckboxField.tsx new file mode 100644 index 00000000..3b5464e0 --- /dev/null +++ b/src/components/form/CheckboxField.tsx @@ -0,0 +1,30 @@ +import { ComponentProps, useId } from "react"; +import { useFieldContext } from "../../hooks/useAppForm"; +import { Checkbox } from "../ui/checkbox"; +import { Field, FieldContent, FieldDescription, FieldError, FieldLabel } from "../ui/field"; + +type CheckboxFieldProps = Omit, "checked" | "onCheckedChange" | "onBlur" | "className"> & { + description?: string; + className?: string; +}; + +export const CheckboxField = ({ title, description, className, ...props }: CheckboxFieldProps) => { + const { name, state, handleChange, handleBlur } = useFieldContext(); + const isInvalid = !state.meta.isValid && state.meta.isTouched; + const id = useId(); + + return ( + + handleChange(!!checked)} onBlur={handleBlur} aria-invalid={isInvalid} /> + + + + {title} + + {isInvalid && } + + {description && {description}} + + + ); +}; diff --git a/src/components/form/ComboboxField.tsx b/src/components/form/ComboboxField.tsx new file mode 100644 index 00000000..c1ecd509 --- /dev/null +++ b/src/components/form/ComboboxField.tsx @@ -0,0 +1,158 @@ +import { Loader2Icon } from "lucide-react"; +import { ComponentProps, ReactNode, useId } from "react"; +import { useIntl } from "react-intl"; +import { useFieldContext } from "../../hooks/useAppForm"; +import { + Combobox, + ComboboxChip, + ComboboxChips, + ComboboxChipsInput, + ComboboxClear, + ComboboxCollection, + ComboboxContent, + ComboboxEmpty, + ComboboxGroup, + ComboboxInput, + ComboboxItem, + ComboboxLabel, + ComboboxList, + ComboboxValue, + useComboboxAnchor, +} from "../ui/combobox"; +import { Field, FieldError, FieldLabel } from "../ui/field"; + +type Item = { value: Value; label: string; icon?: ReactNode; disabled?: boolean }; +type Group = { label: string; items: Item[] }; + +type ComboboxFieldProps = Omit< + ComponentProps, Mode extends "multiple" ? true : false>>, + "multiple" | "value" | "defaultValue" | "onValueChange" | "items" +> & { + mode?: Mode; + title?: string; + placeholder?: string; + items: Item[] | Group[]; + noOptionsMessage?: string; + isLoading?: boolean; + className?: string; +}; + +export const ComboboxField = ({ + mode = "single" as Mode, + items, + title, + placeholder, + required, + disabled, + noOptionsMessage, + isLoading, + className, + ...props +}: ComboboxFieldProps) => { + const { name, state, handleChange, handleBlur } = useFieldContext(); + const isInvalid = !state.meta.isValid && state.meta.isTouched; + const id = useId(); + + const { formatMessage } = useIntl(); + + const anchor = useComboboxAnchor(); + + return ( + + + {title} + + handleChange(Array.isArray(value) ? (value.map((v) => v.value) as Value[]) : value ? (value.value as Value) : null)} + > + {mode === "single" && ( + + {isLoading && } + + )} + {mode === "multiple" && ( + + + {(selected: Item[]) => ( + <> + {selected.map((item) => ( + + {item.label} + + ))} + + + )} + + {isLoading && } + {!required && } + + )} + + {noOptionsMessage ?? formatMessage({ id: "general.no-options" })} + + {(item: Item | Group) => + typeof item === "object" && "items" in item ? ( + + {item.label} + + {(childItem: Item) => ( + + {childItem.icon} + {childItem.label} + + )} + + + ) : ( + + {item.icon} + {item.label} + + ) + } + + + + {isInvalid && } + + ); +}; + +const findSelectedItem = (value: null | Value | Value[], items: ComboboxFieldProps["items"]): null | Item => { + for (const item of items) { + if (typeof item === "object" && "items" in item) { + const found = findSelectedItem(value, item.items); + if (found) { + return found; + } + } else if (item.value === value) { + return item; + } + } + return null; +}; + +const findSelectedItems = (value: null | Value | Value[], items: ComboboxFieldProps["items"]): Item[] => { + if (!Array.isArray(value)) { + return []; + } + + const selected = []; + for (const item of items) { + if (typeof item === "object" && "items" in item) { + selected.push(...findSelectedItems(value, item.items)); + } else if (value.includes(item.value)) { + selected.push(item); + } + } + return selected; +}; diff --git a/src/components/form/DateField.tsx b/src/components/form/DateField.tsx new file mode 100644 index 00000000..0b8fbae3 --- /dev/null +++ b/src/components/form/DateField.tsx @@ -0,0 +1,130 @@ +import { cn } from "@/lib/utils"; +import { XIcon } from "lucide-react"; +import { ComponentProps, useEffect, useId, useState } from "react"; +import { DateRange } from "react-day-picker"; +import { useIntl } from "react-intl"; +import { useFieldContext } from "../../hooks/useAppForm"; +import { Button } from "../ui/button"; +import { Calendar } from "../ui/calendar"; +import { Field, FieldError, FieldLabel } from "../ui/field"; +import { InputGroupButton } from "../ui/input-group"; +import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover"; + +type DateFieldProps = Omit, "mode" | "selected" | "onSelect" | "onBlur" | "disabled"> & { + mode?: Exclude["mode"], "default">; + placeholder?: string; + required?: boolean; + disabled?: boolean; + disabledDates?: ComponentProps["disabled"]; +}; + +export const DateField = ({ title, disabled, placeholder, mode = "single", className, disabledDates, ...props }: DateFieldProps) => { + const { name, state, handleChange, handleBlur } = useFieldContext(); + const isInvalid = !state.meta.isValid && state.meta.isTouched; + const id = useId(); + + const [open, setOpen] = useState(false); + + const { locale } = useIntl(); + const [calendarLocale, setCalendarLocale] = useState["locale"]>(); + useEffect(() => { + import("react-day-picker/locale").then((locales) => { + setCalendarLocale(locales[locale === "en" ? "enUS" : locale]); + }); + }, [locale]); + + return ( + + + {title} + + + + } + > + + {!props.required && } + + + { + handleChange(date); + if (mode === "single") setOpen(false); + }} + locale={calendarLocale} + /> + + + {isInvalid && } + + ); +}; + +const DateValue = ({ mode, value, placeholder }: { mode: NonNullable; placeholder?: string; value: null | Date | Date[] | DateRange }) => { + const { formatDate } = useIntl(); + + if (mode === "single" && value && value instanceof Date) { + return formatDate(value); + } else if (mode === "multiple" && Array.isArray(value)) { + return value.map((date) => formatDate(date)).join(", "); + } else if (mode === "range" && typeof value === "object" && value && (value as DateRange).from && (value as DateRange).to) { + return `${formatDate((value as DateRange).from)} - ${formatDate((value as DateRange).to)}`; + } + return placeholder || ""; +}; + +const ClearButton = ({ + mode, + value, + handleChange, +}: { + mode: NonNullable; + value: null | Date | Date[] | DateRange; + handleChange: (value: null | Date | Date[] | DateRange) => void; +}) => { + switch (mode) { + case "single": + if (!value) return null; + break; + case "multiple": + if (!Array.isArray(value) || value.length === 0) return null; + break; + case "range": + if (typeof value !== "object" || !value || !("from" in value) || !("to" in value)) return null; + break; + } + + return ( + { + e.preventDefault(); + e.stopPropagation(); + handleChange(mode === "multiple" ? [] : null); + }} + > + + + ); +}; diff --git a/src/components/form/HoursField.tsx b/src/components/form/HoursField.tsx new file mode 100644 index 00000000..00018e6c --- /dev/null +++ b/src/components/form/HoursField.tsx @@ -0,0 +1,101 @@ +import { ComponentProps, useEffect, useEffectEvent, useId, useState } from "react"; +import { useFieldContext } from "../../hooks/useAppForm"; +import { useSettings } from "../../provider/SettingsProvider"; +import { Field, FieldError, FieldLabel } from "../ui/field"; +import { Input } from "../ui/input"; + +export const HoursField = ({ + title, + required, + className, + ...props +}: Omit, "value" | "onChange" | "onBlur" | "className"> & { + className?: string; +}) => { + const { name, state, handleChange, handleBlur } = useFieldContext(); + const isInvalid = !state.meta.isValid && state.meta.isTouched; + const id = useId(); + + const { settings } = useSettings(); + + return ( + + + {title} + + {settings.style.timeFormat === "decimal" ? ( + handleChange(isNaN(e.target.valueAsNumber) ? null : e.target.valueAsNumber)} + onBlur={handleBlur} + aria-invalid={isInvalid} + type="number" + min="0" + step="0.01" + className="appearance-none" + /> + ) : ( + handleChange(e.target.value ? parseHmmToHours(e.target.value) : null)} + onBlur={handleBlur} + aria-invalid={isInvalid} + className="appearance-none" + /> + )} + {isInvalid && } + + ); +}; + +const TimeInput = ({ value, onChange, onBlur, ...props }: ComponentProps) => { + const [raw, setRaw] = useState(""); + + const updateRaw = useEffectEvent(setRaw); + useEffect(() => updateRaw(typeof value === "string" ? value : ""), [value]); + + return ( + setRaw(e.target.value)} + onBlur={(e) => { + const match = raw.match(/^\s*(\d+)[,:]?([0-5]?\d)?\s*$/); + if (match) { + e.target.value = `${Number(match[1])}:${Number(match[2] ?? 0) + .toString() + .padStart(2, "0")}`; + } else { + e.target.value = ""; + } + setRaw(e.target.value); + onBlur?.(e); + onChange?.(e); + }} + /> + ); +}; + +// Helper to format number of hours (float) to H:mm string +function formatHoursToHmm(hours: number | null): string { + if (!hours || isNaN(hours)) hours = 0; + const h = Math.floor(hours); + const m = Math.round((hours - h) * 60); + return `${h}:${m.toString().padStart(2, "0")}`; +} + +// Helper to parse H:mm string to number of hours (float) +function parseHmmToHours(value: string): number { + const match = value?.match(/^(\d+):([0-5]?\d)$/); + if (!match) return 0; + const h = parseInt(match[1]!, 10); + const m = parseInt(match[2]!, 10); + if (isNaN(h) || isNaN(m)) return 0; + return h + m / 60; +} diff --git a/src/components/form/SelectField.tsx b/src/components/form/SelectField.tsx new file mode 100644 index 00000000..39ce5264 --- /dev/null +++ b/src/components/form/SelectField.tsx @@ -0,0 +1,80 @@ +import { ComponentProps, ReactNode, useId } from "react"; +import { useFieldContext } from "../../hooks/useAppForm"; +import { Field, FieldError, FieldLabel } from "../ui/field"; +import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from "../ui/select"; + +type Item = { value: Value; label: string; icon?: ReactNode }; +type Group = { label: string; items: Item[] }; + +type SelectFieldProps = Omit>>, "multiple" | "value" | "defaultValue" | "onValueChange" | "items"> & { + items: Item[] | Group[]; + title?: string; + placeholder?: string; + className?: string; +}; + +export const SelectField = ({ items, title, placeholder, required, disabled, className, children, ...props }: SelectFieldProps) => { + const { name, state, handleChange, handleBlur } = useFieldContext(); + const isInvalid = !state.meta.isValid && state.meta.isTouched; + const id = useId(); + + return ( + + + {title} + + + {isInvalid && } + {children} + + ); +}; + +const findSelectedItem = (value: null | Value, items: SelectFieldProps["items"]): null | Item => { + for (const item of items) { + if (typeof item === "object" && "items" in item) { + const found = findSelectedItem(value, item.items); + if (found) { + return found; + } + } else if (item.value === value) { + return item; + } + } + return null; +}; diff --git a/src/components/form/SubmitButton.tsx b/src/components/form/SubmitButton.tsx new file mode 100644 index 00000000..024c6828 --- /dev/null +++ b/src/components/form/SubmitButton.tsx @@ -0,0 +1,21 @@ +import { Loader2Icon } from "lucide-react"; +import { ComponentProps } from "react"; +import { useFormContext } from "../../hooks/useAppForm"; +import { Button } from "../ui/button"; + +export const SubmitButton = ({ children = "Submit", ...props }: ComponentProps) => { + const form = useFormContext(); + + return ( + state.isSubmitting} + // eslint-disable-next-line react/no-children-prop + children={(isSubmitting) => ( + + )} + /> + ); +}; diff --git a/src/components/form/SwitchField.tsx b/src/components/form/SwitchField.tsx new file mode 100644 index 00000000..d69d6563 --- /dev/null +++ b/src/components/form/SwitchField.tsx @@ -0,0 +1,34 @@ +import { ComponentProps, useId } from "react"; +import { useFieldContext } from "../../hooks/useAppForm"; +import { Field, FieldContent, FieldDescription, FieldError, FieldInfo, FieldLabel } from "../ui/field"; +import { Switch } from "../ui/switch"; + +type SwitchFieldProps = Omit, "id" | "checked" | "onCheckedChange" | "onBlur" | "className"> & { + position?: "start" | "end"; + description?: string; + info?: string; + className?: string; +}; + +export const SwitchField = ({ title, description, info, position = "start", className, ...props }: SwitchFieldProps) => { + const { name, state, handleChange, handleBlur } = useFieldContext(); + const isInvalid = !state.meta.isValid && state.meta.isTouched; + const id = useId(); + + return ( + + {position === "start" && handleChange(checked)} onBlur={handleBlur} />} + + + + {title} + {info && {info}} + + {isInvalid && } + + {description && {description}} + + {position === "end" && handleChange(checked)} onBlur={handleBlur} />} + + ); +}; diff --git a/src/components/form/TextField.tsx b/src/components/form/TextField.tsx new file mode 100644 index 00000000..62c6cd14 --- /dev/null +++ b/src/components/form/TextField.tsx @@ -0,0 +1,41 @@ +import { ComponentProps, useId } from "react"; +import { useFieldContext } from "../../hooks/useAppForm"; +import { Field, FieldError, FieldLabel } from "../ui/field"; +import { Input } from "../ui/input"; + +type TextFieldProps = Omit, "id" | "value" | "onChange" | "onBlur" | "className"> & { + className?: string; + classNames?: { + input?: string; + }; + fieldErrorVariant?: ComponentProps["variant"]; +}; + +export const TextField = ({ title, required, className, classNames, fieldErrorVariant, children, ...props }: TextFieldProps) => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const { name, state, handleChange, handleBlur } = useFieldContext(); + const isInvalid = !state.meta.isValid && state.meta.isTouched; + const id = useId(); + + return ( + + {title && ( + + {title} + + )} + handleChange(props.type === "number" ? e.target.valueAsNumber : e.target.value)} + onBlur={handleBlur} + aria-invalid={isInvalid} + className={classNames?.input} + /> + {isInvalid && fieldErrorVariant !== "tooltip" && } + {children} + + ); +}; diff --git a/src/components/form/TextareaField.tsx b/src/components/form/TextareaField.tsx new file mode 100644 index 00000000..e7113ea6 --- /dev/null +++ b/src/components/form/TextareaField.tsx @@ -0,0 +1,22 @@ +import { ComponentProps, useId } from "react"; +import { useFieldContext } from "../../hooks/useAppForm"; +import { Field, FieldError, FieldLabel } from "../ui/field"; +import { Textarea } from "../ui/textarea"; + +type TextareaFieldProps = Omit, "id" | "value" | "onChange" | "onBlur">; + +export const TextareaField = ({ title, required, className, ...props }: TextareaFieldProps) => { + const { name, state, handleChange, handleBlur } = useFieldContext(); + const isInvalid = !state.meta.isValid && state.meta.isTouched; + const id = useId(); + + return ( + + + {title} + + - {error &&

{error}

} - - ); -}; - -export default TextareaField; diff --git a/src/components/general/TimeField.tsx b/src/components/general/TimeField.tsx deleted file mode 100644 index 7b7a9fea..00000000 --- a/src/components/general/TimeField.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import { faAsterisk } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import clsx from "clsx"; -import { ChangeEventHandler, useId } from "react"; -import Flatpickr, { DateTimePickerProps } from "react-flatpickr"; - -interface PropTypes extends Omit { - size?: "sm" | "md"; - icon?: React.ReactNode; - error?: string; - onChange?: ChangeEventHandler; - type?: "date" | "number"; -} - -const TimeField = ({ size = "md", title, icon, error, className, type = "date", value, onChange, onBlur, ...props }: PropTypes) => { - const id = useId(); - - return ( -
- {title && ( - - )} -
- {icon &&
{icon}
} - { - onChange?.({ - target: { - name: props.name, - value: type === "number" ? convertDateToHours(dates[0]) : dates[0], - }, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - } as any); - }} - onClose={() => { - onBlur?.({ - target: { - name: props.name, - }, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - } as any); - }} - className={clsx("block w-full rounded-lg text-sm", "border border-field-border bg-field placeholder:text-field-placeholder", "focus:outline-none focus:ring-2 focus:ring-primary-focus", { - "border-red-500 text-red-900 placeholder:text-red-700 dark:border-red-500 dark:text-red-500 dark:placeholder:text-red-500": error !== undefined, - "pl-8": !!icon, - "p-1.5": size === "sm", - "p-2.5": size === "md", - })} - /> -
- {error &&

{error}

} -
- ); -}; - -const convertHoursToString = (hours: number) => { - const h = Math.floor(hours); - const m = Math.round((hours - h) * 60); - - return `${h}:${m}`; -}; - -const convertDateToHours = (date: Date) => { - return Number((date.getHours() + date.getMinutes() / 60).toFixed(2)); -}; - -export default TimeField; diff --git a/src/components/general/Toast.tsx b/src/components/general/Toast.tsx deleted file mode 100644 index 044f6947..00000000 --- a/src/components/general/Toast.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import clsx from "clsx"; - -type PropTypes = { - type: "success" | "error"; - message: string; - allowClose?: boolean; - autoClose?: number; - onClose?: () => void; -}; - -const Toast = ({ type, message, allowClose = true, autoClose, onClose }: PropTypes) => { - if (autoClose) setTimeout(() => onClose?.(), autoClose); - - return ( -
-
-
- {type === "success" && ( - - )} - {type === "error" && ( - - )} -
-
{message}
- {allowClose && ( - - )} -
-
- ); -}; - -export default Toast; diff --git a/src/components/general/Toggle.tsx b/src/components/general/Toggle.tsx deleted file mode 100644 index 2bc284d6..00000000 --- a/src/components/general/Toggle.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import clsx from "clsx"; -import { useId } from "react"; - -interface PropTypes extends Omit, "id" | "size" | "type"> { - size?: "sm" | "md" | "lg"; - onLabel?: string; - offLabel?: string; -} - -const Toggle = ({ size = "md", title, onLabel, offLabel, className, ...props }: PropTypes) => { - const id = useId(); - - return ( - - ); -}; - -export default Toggle; diff --git a/src/components/general/ToggleableCard.tsx b/src/components/general/ToggleableCard.tsx new file mode 100644 index 00000000..d23967b1 --- /dev/null +++ b/src/components/general/ToggleableCard.tsx @@ -0,0 +1,31 @@ +import { clsxm } from "@/utils/clsxm"; +import { ComponentProps, JSXElementConstructor } from "react"; + +interface PropTypes extends ComponentProps<"div"> { + as?: "div" | JSXElementConstructor>; + onToggle?: () => void; +} + +export const ToggleableCard = ({ as = "div", className, onToggle, ...props }: PropTypes) => { + const Comp = as; + return ( + { + if ((e.key === "Enter" || e.code === "Space") && e.currentTarget === document.activeElement) { + onToggle(); + e.preventDefault(); + e.stopPropagation(); + } + }, + })} + /> + ); +}; diff --git a/src/components/issue/AddIssueNotesModal.tsx b/src/components/issue/AddIssueNotesModal.tsx new file mode 100644 index 00000000..a9a3eed8 --- /dev/null +++ b/src/components/issue/AddIssueNotesModal.tsx @@ -0,0 +1,86 @@ +/* eslint-disable react/no-children-prop */ +import { redmineIssuesQueries } from "@/api/redmine/queries/issues"; +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { useIntl } from "react-intl"; +import { z } from "zod"; +import { TIssue, TUpdateIssue } from "../../api/redmine/types"; +import { useAppForm } from "../../hooks/useAppForm"; +import { useRedmineApi } from "../../provider/RedmineApiProvider"; +import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "../ui/dialog"; +import { Form, FormGrid } from "../ui/form"; +import { IssueTitle } from "./IssueTitle"; + +const addIssueNotesFormSchema = ({ formatMessage }: { formatMessage: ReturnType["formatMessage"] }) => + z.object({ + notes: z.string(formatMessage({ id: "issues.issue.field.notes.validation.required" })).nonempty(formatMessage({ id: "issues.issue.field.notes.validation.required" })), + private_notes: z.boolean().optional(), + }); + +type TAddIssueNotesForm = z.infer>; + +type PropTypes = { + issue: TIssue; + onClose: () => void; + onSuccess: () => void; +}; + +const AddIssueNotesModal = ({ issue, onClose, onSuccess }: PropTypes) => { + const { formatMessage } = useIntl(); + + const redmineApi = useRedmineApi(); + const queryClient = useQueryClient(); + + const updateIssueMutation = useMutation({ + mutationFn: (data: TUpdateIssue) => redmineApi.updateIssue(issue.id, data), + onSuccess: () => { + queryClient.invalidateQueries(redmineIssuesQueries); + onSuccess(); + }, + meta: { + successMessage: formatMessage({ id: "issues.modal.add-issue-notes.success" }), + }, + }); + + const form = useAppForm({ + defaultValues: { + notes: "", + private_notes: false, + } satisfies TAddIssueNotesForm as TAddIssueNotesForm, + validators: { + onChange: addIssueNotesFormSchema({ formatMessage }), + }, + onSubmit: async ({ value }) => updateIssueMutation.mutateAsync(value), + }); + + return ( + <> + + +
+ + {formatMessage({ id: "issues.modal.add-issue-notes.title" })} + + + + ( + + )} + /> + + } /> + + + + + + + +
+
+ + ); +}; + +export default AddIssueNotesModal; diff --git a/src/components/issue/CreateIssueModal.tsx b/src/components/issue/CreateIssueModal.tsx new file mode 100644 index 00000000..b8d2a678 --- /dev/null +++ b/src/components/issue/CreateIssueModal.tsx @@ -0,0 +1,43 @@ +import { redmineIssuesQueries } from "@/api/redmine/queries/issues"; +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { useIntl } from "react-intl"; +import { TCreateIssue } from "../../api/redmine/types"; +import { useRedmineApi } from "../../provider/RedmineApiProvider"; +import { Dialog, DialogContent, DialogHeader, DialogTitle } from "../ui/dialog"; +import { IssueForm } from "./form/IssueForm"; + +type PropTypes = { + projectId: number; + onClose: () => void; + onSuccess: () => void; +}; + +const CreateIssueModal = ({ projectId, onClose, onSuccess }: PropTypes) => { + const { formatMessage } = useIntl(); + const redmineApi = useRedmineApi(); + const queryClient = useQueryClient(); + + const createIssueMutation = useMutation({ + mutationFn: (issue: TCreateIssue) => redmineApi.createIssue(issue), + onSuccess: () => { + queryClient.invalidateQueries(redmineIssuesQueries); + onSuccess(); + }, + meta: { + successMessage: formatMessage({ id: "issues.modal.add-issue.success" }), + }, + }); + + return ( + + + + {formatMessage({ id: "issues.modal.add-issue.title" })} + + createIssueMutation.mutateAsync(data)} /> + + + ); +}; + +export default CreateIssueModal; diff --git a/src/components/issue/EditIssueModal.tsx b/src/components/issue/EditIssueModal.tsx new file mode 100644 index 00000000..8df4ce01 --- /dev/null +++ b/src/components/issue/EditIssueModal.tsx @@ -0,0 +1,53 @@ +import { useRedmineIssue } from "@/api/redmine/hooks/useRedmineIssue"; +import { redmineIssuesQueries } from "@/api/redmine/queries/issues"; +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { useIntl } from "react-intl"; +import { TIssue, TUpdateIssue } from "../../api/redmine/types"; +import { useRedmineApi } from "../../provider/RedmineApiProvider"; +import { Dialog, DialogContent, DialogHeader, DialogTitle } from "../ui/dialog"; +import { IssueForm } from "./form/IssueForm"; +import { IssueTitle } from "./IssueTitle"; + +type PropTypes = { + issue: TIssue; + onClose: () => void; + onSuccess: () => void; +}; + +const EditIssueModal = ({ issue: currentIssue, onClose, onSuccess }: PropTypes) => { + const { formatMessage } = useIntl(); + const redmineApi = useRedmineApi(); + const queryClient = useQueryClient(); + + const issueQuery = useRedmineIssue(currentIssue.id, { + staleTime: 0, + }); + const issue = issueQuery.data ?? currentIssue; + + const updateIssueMutation = useMutation({ + mutationFn: (data: TUpdateIssue) => redmineApi.updateIssue(issue.id, data), + onSuccess: () => { + queryClient.invalidateQueries(redmineIssuesQueries); + onSuccess(); + }, + meta: { + successMessage: formatMessage({ id: "issues.modal.edit-issue.success" }), + }, + }); + + return ( + <> + + + + {formatMessage({ id: "issues.modal.edit-issue.title" })} + + + updateIssueMutation.mutateAsync(data)} /> + + + + ); +}; + +export default EditIssueModal; diff --git a/src/components/issue/Filter.tsx b/src/components/issue/Filter.tsx new file mode 100644 index 00000000..d3d5aa49 --- /dev/null +++ b/src/components/issue/Filter.tsx @@ -0,0 +1,168 @@ +/* eslint-disable react/no-children-prop */ +import { useRedmineIssueStatuses } from "@/api/redmine/hooks/useRedmineIssueStatuses"; +import { useRedmineProjects } from "@/api/redmine/hooks/useRedmineProjects"; +import { TIssue } from "@/api/redmine/types"; +import { useAppForm } from "@/hooks/useAppForm"; +import deepmerge from "deepmerge"; +import { SlidersHorizontalIcon } from "lucide-react"; +import { createContext, PropsWithChildren, use } from "react"; +import { useIntl } from "react-intl"; +import { z } from "zod"; +import { useSuspenseStorage } from "../../hooks/useStorage"; +import { Button } from "../ui/button"; +import { FieldGroup, FieldSet } from "../ui/field"; +import { Form } from "../ui/form"; +import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover"; + +const filterSettingsSchema = z.object({ + projects: z.array(z.number()), + statuses: z.array(z.number()), + hideCompletedIssues: z.boolean(), +}); + +type FilterSettings = z.infer; + +const defaultFilterSettings: FilterSettings = { projects: [], statuses: [], hideCompletedIssues: false }; + +type FilterContextType = { + settings: FilterSettings; + setSettings: (settings: FilterSettings) => Promise; +}; + +const FilterContext = createContext(undefined); + +const FilterProvider = ({ children }: PropsWithChildren) => { + const { data: filterSettings, setData: setFilterSettings } = useSuspenseStorage("filter", defaultFilterSettings); + + return ( + + {children} + + ); +}; + +export const useFilter = () => { + const context = use(FilterContext); + if (!context) { + throw new Error("useFilter must be used within a FilterProvider component"); + } + return context; +}; + +const FilterButton = () => { + const { formatMessage } = useIntl(); + + return ( + + }> + + {formatMessage({ id: "issues.filter" })} + + + + + + ); +}; + +const FilterForm = () => { + const { formatMessage } = useIntl(); + const filter = useFilter(); + + const form = useAppForm({ + defaultValues: filter.settings, + validators: { + onChange: filterSettingsSchema, + }, + listeners: { + onChange: ({ formApi }) => { + if (formApi.state.isValid) { + formApi.handleSubmit(); + } + }, + }, + onSubmit: async ({ value }) => { + await filter.setSettings(value); + }, + }); + + const projectsQuery = useRedmineProjects(); + const statusesQuery = useRedmineIssueStatuses(); + + return ( +
+
+ + ( + ({ value: project.id, label: project.name })) ?? []} + isLoading={projectsQuery.isPending} + mode="multiple" + /> + )} + /> + ( + ({ + label: status.name, + value: status.id, + disabled: status.is_closed, + })) ?? [] + } + isLoading={statusesQuery.isPending} + mode="multiple" + /> + )} + /> + ( + + )} + /> + +
+
+ ); +}; + +export const filterIssues = (issues: TIssue[], settings: FilterSettings) => { + // projects + if (settings.projects.length > 0) { + issues = issues.filter((issue) => settings.projects.includes(issue.project.id)); + } + + // statuses + if (settings.statuses && settings.statuses.length > 0) { + issues = issues.filter((issue) => settings.statuses.includes(issue.status.id)); + } + + // hide completed issues (done_ratio = 100%) + if (settings.hideCompletedIssues) { + issues = issues.filter((issue) => issue.done_ratio !== 100); + } + + return issues; +}; + +const Filter = { + Provider: FilterProvider, + Button: FilterButton, +}; + +export default Filter; diff --git a/src/components/issue/Issue.tsx b/src/components/issue/Issue.tsx new file mode 100644 index 00000000..8489d19a --- /dev/null +++ b/src/components/issue/Issue.tsx @@ -0,0 +1,154 @@ +import { PriorityType } from "@/api/redmine/hooks/useRedmineIssuePriorities"; +import { IssueContextMenu } from "@/components/issue/IssueContextMenu"; +import { Badge } from "@/components/ui/badge"; +import { Skeleton } from "@/components/ui/skeleton"; +import { usePermissions } from "@/provider/PermissionsProvider"; +import clsx from "clsx"; +import { PinIcon, UserIcon } from "lucide-react"; +import { useState } from "react"; +import { useIntl } from "react-intl"; +import { TIssue } from "../../api/redmine/types"; +import { LocalIssue } from "../../hooks/useLocalIssues"; +import { Timer } from "../../hooks/useTimers"; +import { useSettings } from "../../provider/SettingsProvider"; +import { useTimerApi } from "../../provider/TimerApiProvider"; +import { clsxm } from "../../utils/clsxm"; +import HelpTooltip from "../general/HelpTooltip"; +import { ToggleableCard } from "../general/ToggleableCard"; +import { TimerComponents } from "../timer/timer"; +import { IssueTitle, IssueTitleSkeleton } from "./IssueTitle"; + +type PropTypes = { + issue: TIssue; + localIssue: LocalIssue; + priorityType: PriorityType; + assignedToMe: boolean; + timers: Timer[]; +}; + +const Issue = ({ issue, localIssue, priorityType, assignedToMe, timers }: PropTypes) => { + const { formatMessage } = useIntl(); + + const { settings } = useSettings(); + + const { hasProjectPermission } = usePermissions(); + const canLogTime = hasProjectPermission(issue.project.id, "log_time"); + + const timerApi = useTimerApi(); + + const primaryTimer = timers[0]!; + + const [areTimersExpanded, setAreTimersExpanded] = useState(false); + + return ( + + timerApi.toggleTimer(primaryTimer) })} + > + +
+
+ {settings.style.showIssueDoneRatio && ( +
+
+ {issue.done_ratio}% +
+
+ )} + {settings.style.showIssueStatus && ( + + {issue.status.name} + + )} +
+ {canLogTime && !areTimersExpanded && ( +
+ + + + + + + + {timers.length > 1 && ( + + )} +
+ )} +
+ {canLogTime && areTimersExpanded && ( +
+ {timers.map((timer) => ( + + + + + + + + + + + ))} +
+ )} +
+ {localIssue.pinned && ( + + + + )} + {!assignedToMe && ( + + + + )} +
+
+
+ ); +}; + +export const IssueSkeleton = () => { + const { settings } = useSettings(); + + return ( + + +
+
+ {settings.style.showIssueDoneRatio && } + {settings.style.showIssueStatus && } +
+
+ + + + + +
+
+
+ ); +}; + +export default Issue; diff --git a/src/components/issue/IssueContextMenu.tsx b/src/components/issue/IssueContextMenu.tsx new file mode 100644 index 00000000..d5de5c50 --- /dev/null +++ b/src/components/issue/IssueContextMenu.tsx @@ -0,0 +1,130 @@ +import { useRedmineCurrentUser } from "@/api/redmine/hooks/useRedmineCurrentUser"; +import { usePermissions } from "@/provider/PermissionsProvider"; +import { + BookmarkMinusIcon, + BookmarkPlusIcon, + CopyIcon, + NotebookPenIcon, + PencilIcon, + PinIcon, + PinOffIcon, + PlusIcon, + SquareArrowOutUpRightIcon, + TimerIcon, + TimerOffIcon, + TimerResetIcon, +} from "lucide-react"; +import { ReactElement, useState } from "react"; +import { useIntl } from "react-intl"; +import { toast } from "sonner"; +import { TIssue } from "../../api/redmine/types"; +import { LocalIssue } from "../../hooks/useLocalIssues"; +import { calculateTimerTotalElapsedTime, Timer } from "../../hooks/useTimers"; +import { useSettings } from "../../provider/SettingsProvider"; +import { useTimerApi } from "../../provider/TimerApiProvider"; +import { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuSeparator, ContextMenuTrigger } from "../ui/context-menu"; +import AddIssueNotesModal from "./AddIssueNotesModal"; +import EditIssueModal from "./EditIssueModal"; + +type PropTypes = { + issue: TIssue; + localIssue: LocalIssue; + primaryTimer: Timer; + assignedToMe: boolean; +}; + +export const IssueContextMenu = ({ children, ...props }: PropTypes & { children: ReactElement }) => { + const [editIssue, setEditIssue] = useState(false); + const [addNotes, setAddNotes] = useState(false); + + return ( + <> + + + + setEditIssue(true)} onAddNotes={() => setAddNotes(true)} /> + + + + {editIssue && setEditIssue(false)} onSuccess={() => setEditIssue(false)} />} + {addNotes && setAddNotes(false)} onSuccess={() => setAddNotes(false)} />} + + ); +}; + +const IssueContextMenuItems = ({ issue, localIssue, primaryTimer, assignedToMe, onEdit, onAddNotes }: PropTypes & { onEdit: () => void; onAddNotes: () => void }) => { + const { formatMessage } = useIntl(); + const { settings } = useSettings(); + const timerApi = useTimerApi(); + + const { data: me } = useRedmineCurrentUser(); + + const { hasProjectPermission } = usePermissions(); + const canEdit = hasProjectPermission(issue.project.id, "edit_issues") || (hasProjectPermission(issue.project.id, "edit_own_issues") && issue.author.id === me?.id); + const canLogTime = hasProjectPermission(issue.project.id, "log_time"); + const canAddNotes = hasProjectPermission(issue.project.id, "add_issue_notes"); + + return ( + <> + window.open(`${settings.redmineURL}/issues/${issue.id}`, "_blank")}> + + {formatMessage({ id: "issues.context-menu.open-in-redmine" })} + + { + navigator.clipboard.writeText(`#${issue.id}`); + toast.success(formatMessage({ id: "issues.id-copied-to-clipboard" }, { issueId: issue.id }), { + duration: 2000, + }); + }} + > + + {formatMessage({ id: "issues.context-menu.copy-id-to-clipboard" })} + + + + + {formatMessage({ id: "issues.context-menu.edit" })} + + + + {formatMessage({ id: "issues.context-menu.add-notes" })} + + + timerApi.pauseTimer(primaryTimer) : () => timerApi.startTimer(primaryTimer)} disabled={!canLogTime}> + {primaryTimer.activeSession ? : } + {formatMessage({ id: primaryTimer.activeSession ? "timer.context-menu.pause" : "timer.context-menu.start" })} + + timerApi.resetTimer(primaryTimer)} disabled={calculateTimerTotalElapsedTime(primaryTimer) === 0 || !canLogTime}> + + {formatMessage({ id: "timer.context-menu.reset" })} + + timerApi.addTimer(issue.id)} disabled={!canLogTime}> + + {formatMessage({ id: "timer.context-menu.add-timer" })} + + + localIssue.setLocalIssue({ pinned: true, remembered: !assignedToMe ? true : undefined })}> + + {formatMessage({ id: assignedToMe || localIssue.remembered ? "issues.context-menu.pin" : "issues.context-menu.pin-and-remember" })} + + localIssue.setLocalIssue({ pinned: false })}> + + {formatMessage({ id: "issues.context-menu.unpin" })} + + {!assignedToMe && ( + <> + + localIssue.setLocalIssue({ remembered: true })}> + + {formatMessage({ id: "issues.context-menu.remember" })} + + localIssue.setLocalIssue({ remembered: false })}> + + {formatMessage({ id: "issues.context-menu.forgot" })} + + + )} + + ); +}; diff --git a/src/components/issue/IssueInfoTooltip.tsx b/src/components/issue/IssueInfoTooltip.tsx new file mode 100644 index 00000000..1f147685 --- /dev/null +++ b/src/components/issue/IssueInfoTooltip.tsx @@ -0,0 +1,104 @@ +import { parseISO } from "date-fns"; +import { ReactElement } from "react"; +import { useIntl } from "react-intl"; +import { TIssue } from "../../api/redmine/types"; +import useFormatHours from "../../hooks/useFormatHours"; +import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"; + +type PropTypes = { + issue: TIssue; +}; + +export const IssueInfoTooltip = ({ children, ...props }: PropTypes & { children: ReactElement }) => { + return ( + + + + + + + ); +}; + +const IssueInfoTooltipContent = ({ issue }: PropTypes) => { + const { formatMessage, formatDate } = useIntl(); + const formatHours = useFormatHours(); + + return ( + <> +
+

+ {issue.tracker.name} #{issue.id} +

+

{issue.subject}

+
+ + + + + + + + + + + {issue.assigned_to && ( + + + + + )} + {issue.category && ( + + + + + )} + {issue.fixed_version && ( + + + + + )} + {issue.start_date && ( + + + + + )} + {issue.due_date && ( + + + + + )} + {issue.estimated_hours != null && ( + + + + + )} + {issue.spent_hours != null && ( + + + + + )} + {issue.custom_fields?.map((field) => { + if (!field.value) return null; + if (Array.isArray(field.value) && field.value.length === 0) return null; + + const value = Array.isArray(field.value) ? field.value.join(", ") : String(field.value); + return ( + + + + + ); + })} + +
{formatMessage({ id: "issues.issue.field.status" })}:{issue.status.name}
{formatMessage({ id: "issues.issue.field.priority" })}:{issue.priority.name}
{formatMessage({ id: "issues.issue.field.assignee" })}:{issue.assigned_to.name}
{formatMessage({ id: "issues.issue.field.category" })}:{issue.category.name}
{formatMessage({ id: "issues.issue.field.version" })}:{issue.fixed_version.name}
{formatMessage({ id: "issues.issue.field.start-date" })}:{formatDate(parseISO(issue.start_date))}
{formatMessage({ id: "issues.issue.field.due-date" })}:{formatDate(parseISO(issue.due_date))}
{formatMessage({ id: "issues.issue.field.estimated-hours" })}:{formatHours(issue.estimated_hours)}
{formatMessage({ id: "issues.issue.field.spent-time" })}:{formatHours(issue.spent_hours)}
{field.name}:{value}
+

{formatMessage({ id: "issues.issue-tooltip.open-in-redmine" })}

+ + ); +}; diff --git a/src/components/issue/IssueSearch.tsx b/src/components/issue/IssueSearch.tsx new file mode 100644 index 00000000..640fe354 --- /dev/null +++ b/src/components/issue/IssueSearch.tsx @@ -0,0 +1,336 @@ +/* eslint-disable react/no-children-prop */ +import useRedmineIssuesSearch from "@/api/redmine/hooks/useRedmineIssuesSearch"; +import { Skeleton } from "@/components/ui/skeleton"; +import { useAppForm } from "@/hooks/useAppForm"; +import { useSuspenseStorage } from "@/hooks/useStorage"; +import { clsxm } from "@/utils/clsxm"; +import { ChevronRightIcon, CloudIcon, ListTreeIcon, MoreHorizontalIcon, SearchIcon, XIcon } from "lucide-react"; +import { createContext, PropsWithChildren, use, useEffect, useRef, useState } from "react"; +import { useIntl } from "react-intl"; +import { z } from "zod"; +import { TIssue, TReference } from "../../api/redmine/types"; +import useDebounce from "../../hooks/useDebounce"; +import useHotKey from "../../hooks/useHotkey"; +import { useSettings } from "../../provider/SettingsProvider"; +import { Badge } from "../ui/badge"; +import { Button } from "../ui/button"; +import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../ui/dropdown-menu"; +import { FieldGroup, FieldLabel, FieldSet } from "../ui/field"; +import { Form, FormGrid } from "../ui/form"; +import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput } from "../ui/input-group"; +import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover"; +import { Separator } from "../ui/separator"; + +const searchSettingsSchema = z.object({ + mode: z.enum(["local", "remote"]), + remoteSearchOptions: z.object({ + titlesOnly: z.boolean(), + openIssuesOnly: z.boolean(), + assignedToMe: z.boolean(), + }), +}); + +type SearchSettingsSchema = z.infer; + +const defaultSearchSettings: SearchSettingsSchema = { + mode: "local", + remoteSearchOptions: { + titlesOnly: false, + openIssuesOnly: true, + assignedToMe: true, + }, +}; + +export type IssueSearchContext = { + isSearching: boolean; + query: string; + inProject?: TReference; + settings: SearchSettingsSchema; + searchInProject: (project: TReference) => void; +}; + +type IssueSearchInternalContext = IssueSearchContext & { + isSearchOpen: boolean; + rawQuery: string; + setRawQuery: (query: string) => void; + setInProject: (project: TReference | undefined) => void; + setSettings: (settings: SearchSettingsSchema) => Promise; + focusTrigger: number; +}; + +const SearchContext = createContext(undefined); + +const IssueSearchProvider = ({ children }: PropsWithChildren) => { + const { settings } = useSettings(); + + const [isSearchOpen, setIsSearchOpen] = useState(settings.style.displaySearchAlways); + const [query, setQuery] = useState(""); + const debouncedQuery = useDebounce(query, 300); + const [inProject, setInProject] = useState(undefined); + const [focusTrigger, setFocusTrigger] = useState(0); + + const { data: searchSettings, setData: setSearchSettings } = useSuspenseStorage("search", defaultSearchSettings); + + const requestFocus = () => setFocusTrigger((prev) => prev + 1); + + // hotkeys + useHotKey({ ctrl: true, key: "k" }, () => { + setIsSearchOpen(true); + requestFocus(); + }); + useHotKey({ ctrl: true, key: "f" }, () => { + setIsSearchOpen(true); + requestFocus(); + }); + useHotKey( + { key: "Escape" }, + () => { + if (!settings.style.displaySearchAlways) { + setIsSearchOpen(false); + } + setQuery(""); + setInProject(undefined); + }, + isSearchOpen + ); + + return ( + 0 : debouncedQuery.length >= 3), + query: searchSettings.mode === "local" ? query : debouncedQuery, + inProject, + setInProject, + settings: searchSettings, + setSettings: setSearchSettings, + isSearchOpen, + rawQuery: query, + setRawQuery: setQuery, + searchInProject: (project: TReference) => { + setInProject(project); + setIsSearchOpen(true); + requestFocus(); + }, + focusTrigger, + }} + > + {children} + + ); +}; + +const IssueSearchInput = ({ className }: { className?: string }) => { + const { formatMessage } = useIntl(); + const ctx = useIssueSearchInternal(); + + const settingsForm = useAppForm({ + defaultValues: ctx.settings, + validators: { + onChange: searchSettingsSchema, + }, + listeners: { + onChange: ({ formApi }) => { + if (formApi.state.isValid) { + formApi.handleSubmit(); + } + }, + }, + onSubmit: async ({ value }) => { + await ctx.setSettings(value); + }, + }); + + // Focus when requested by provider + const searchRef = useRef(null); + useEffect(() => { + if (ctx.focusTrigger > 0) { + searchRef.current?.focus(); + searchRef.current?.select(); + } + }, [ctx.focusTrigger]); + + // Toggle search mode hotkey + useHotKey( + { ctrl: true, key: "m" }, + () => { + settingsForm.setFieldValue("mode", (current) => (current === "local" ? "remote" : "local")); + settingsForm.handleSubmit(); + }, + ctx.isSearchOpen + ); + + if (!ctx.isSearchOpen) return null; + + return ( +
+
+ + ctx.setRawQuery(e.target.value)} autoFocus /> + + + + + ( + + }> + {field.state.value === "local" + ? formatMessage({ id: "issues.search.mode.local" }) + : field.state.value === "remote" + ? formatMessage({ id: "issues.search.mode.remote" }) + : "unknown"} + + + field.handleChange("local")}> + + {formatMessage({ id: "issues.search.mode.local" })} + + field.handleChange("remote")}> + + {formatMessage({ id: "issues.search.mode.remote" })} + + + + )} + /> + + ({ + mode: state.values.mode, + })} + children={({ mode }) => ( + + } disabled={mode !== "remote"}> + + + + +
+ {formatMessage({ id: "issues.search.remote-search-options.title" })} + + ( + + )} + /> + } + /> + } + /> + +
+
+
+
+ )} + /> +
+
+
+ {ctx.inProject && ( +
+ + {formatMessage( + { + id: "issues.search.search-in-project", + }, + { + projectName: ctx.inProject.name, + badge: (children) => ( + + {children} + + ), + } + )} +
+ ctx.setInProject(undefined)} /> +
+
+ )} +
+ ); +}; + +const IssueSearchLoadMore = ({ + hasNextPage, + isLoading, + fetchNextPage, + className, +}: Pick, "hasNextPage" | "isLoading" | "fetchNextPage"> & { + className?: string; +}) => { + const { formatMessage } = useIntl(); + const ctx = useIssueSearchInternal(); + + if (!(ctx.isSearching && ctx.settings.mode === "remote" && hasNextPage && !isLoading)) return null; + + return ( +
+ +
+ ); +}; + +const useIssueSearchInternal = () => { + const context = use(SearchContext); + if (!context) { + throw new Error("useIssueSearch must be used within a IssueSearch.Provider component"); + } + return context; +}; + +export const useIssueSearch = (): IssueSearchContext => { + const { isSearching, query, inProject, settings, searchInProject } = useIssueSearchInternal(); + return { isSearching, query, inProject, settings, searchInProject }; +}; + +export const filterIssuesByLocalSearch = (issues: TIssue[], search: IssueSearchContext) => { + if (search.isSearching && search.settings.mode === "local") { + // filter: project (search in project) + if (search.inProject) { + issues = issues.filter((issue) => issue.project.id === search.inProject!.id); + } + + // search: local search + if (search.query) { + issues = issues.filter((issue) => new RegExp(search.query, "i").test(`#${issue.id} ${issue.subject}`)); + } + } + + return issues; +}; + +const IssueSearchInputSkeleton = ({ className }: { className?: string }) => { + const { settings } = useSettings(); + + if (!settings.style.displaySearchAlways) return null; + + return ( +
+ +
+ ); +}; + +const IssueSearch = { + Provider: IssueSearchProvider, + Input: IssueSearchInput, + LoadMore: IssueSearchLoadMore, + Skeleton: { + Input: IssueSearchInputSkeleton, + }, +}; + +export default IssueSearch; diff --git a/src/components/issue/IssueTitle.tsx b/src/components/issue/IssueTitle.tsx new file mode 100644 index 00000000..3be39700 --- /dev/null +++ b/src/components/issue/IssueTitle.tsx @@ -0,0 +1,50 @@ +import { IssueInfoTooltip } from "@/components/issue/IssueInfoTooltip"; +import { Skeleton } from "@/components/ui/skeleton"; +import { randomElement } from "@/utils/random"; +import clsx from "clsx"; +import { ComponentProps } from "react"; +import { PriorityType } from "../../api/redmine/hooks/useRedmineIssuePriorities"; +import { TIssue } from "../../api/redmine/types"; +import { useSettings } from "../../provider/SettingsProvider"; +import { clsxm } from "../../utils/clsxm"; + +type PropTypes = { + issue: TIssue; + priorityType?: PriorityType; +} & Omit, "children">; + +export const IssueTitle = ({ issue, priorityType, className, ...props }: PropTypes) => { + const { settings } = useSettings(); + + return ( +

+ + + {issue.tracker.name} #{issue.id} + + {" "} + {issue.subject} +

+ ); +}; + +export const IssueTitleSkeleton = () => ; diff --git a/src/components/issue/ProjectIssuesGroup.tsx b/src/components/issue/ProjectIssuesGroup.tsx new file mode 100644 index 00000000..767f8921 --- /dev/null +++ b/src/components/issue/ProjectIssuesGroup.tsx @@ -0,0 +1,167 @@ +import { useRedmineCurrentUser } from "@/api/redmine/hooks/useRedmineCurrentUser"; +import { useRedmineIssuePriorities } from "@/api/redmine/hooks/useRedmineIssuePriorities"; +import { ProjectTooltip } from "@/components/issue/ProjectTooltip"; +import { VersionTooltip } from "@/components/issue/VersionTooltip"; +import { Skeleton } from "@/components/ui/skeleton"; +import { usePermissions } from "@/provider/PermissionsProvider"; +import { useSettings } from "@/provider/SettingsProvider"; +import { clsxm } from "@/utils/clsxm"; +import { ProjectIssuesGroup as ProjectIssuesGroupType } from "@/utils/groupIssues"; +import { randomElement } from "@/utils/random"; +import clsx from "clsx"; +import { PinIcon, PlusIcon, SearchIcon, SquareChartGanttIcon, SquareMousePointerIcon, TimerIcon } from "lucide-react"; +import { ComponentProps, Fragment, useState } from "react"; +import { FormattedMessage } from "react-intl"; +import { TReference, TVersion } from "../../api/redmine/types"; +import useLocalIssues from "../../hooks/useLocalIssues"; +import useTimers from "../../hooks/useTimers"; +import { Badge } from "../ui/badge"; +import CreateIssueModal from "./CreateIssueModal"; +import Issue, { IssueSkeleton } from "./Issue"; +import { useIssueSearch } from "./IssueSearch"; + +interface ProjectIssuesGroupProps extends ComponentProps<"div"> { + projectGroup: ProjectIssuesGroupType; + localIssues: ReturnType; + timers: ReturnType; +} + +export const ProjectIssuesGroup = ({ projectGroup, localIssues, timers, className, ...props }: ProjectIssuesGroupProps) => { + const { settings } = useSettings(); + + const { data: me } = useRedmineCurrentUser(); + const { getPriorityType } = useRedmineIssuePriorities({ enabled: settings.style.showIssuePriority }); + + return ( +
+ + {projectGroup.groups.map((issueGroup) => ( + + {["version", "no-version"].includes(issueGroup.type) && } + + {issueGroup.issues.map((issue) => ( + + ))} + + ))} +
+ ); +}; + +const IssueProject = ({ project, type }: { project: TReference; type: ProjectIssuesGroupType["type"] }) => { + const { settings } = useSettings(); + + return ( +
+ + + + {project.name} + + + +
+ + +
+
+ ); +}; + +export const ProjectGroupIcon = ({ type }: { type: ProjectIssuesGroupType["type"] }) => { + switch (type) { + case "active-tab": + return ; + case "tracked-issues": + return ; + case "pinned-issues": + return ; + case "project": + return ; + default: + return null; + } +}; + +const CreateIssueButton = ({ project }: { project: TReference }) => { + const { hasProjectPermission } = usePermissions(); + + const [createIssue, setCreateIssue] = useState(false); + + if (!hasProjectPermission(project.id, "add_issues")) return; + + return ( + <> + + + {createIssue && setCreateIssue(false)} onSuccess={() => setCreateIssue(false)} />} + + ); +}; + +const SearchInProjectButton = ({ project }: { project: TReference }) => { + const { searchInProject } = useIssueSearch(); + + return ( + + ); +}; + +const ProjectVersion = ({ version }: { version?: TVersion }) => { + const { settings } = useSettings(); + + return ( +
+ {version ? ( + + + + {version.name} + + + + ) : ( + + + + )} +
+ ); +}; + +export const ProjectIssuesGroupSkeleton = ({ groups }: { groups: number[] }) => ( +
+
+ + +
+ + +
+
+
+ {groups.map((key) => ( + + ))} +
+
+); diff --git a/src/components/issue/ProjectTooltip.tsx b/src/components/issue/ProjectTooltip.tsx new file mode 100644 index 00000000..a5adbbd9 --- /dev/null +++ b/src/components/issue/ProjectTooltip.tsx @@ -0,0 +1,69 @@ +import { useRedmineProject } from "@/api/redmine/hooks/useRedmineProject"; +import { ReactElement } from "react"; +import { useIntl } from "react-intl"; +import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"; + +type PropTypes = { + projectId: number; +}; + +export const ProjectTooltip = ({ children, ...props }: PropTypes & { children: ReactElement }) => { + return ( + + + + + + + ); +}; + +const ProjectTooltipContent = ({ projectId }: PropTypes) => { + const { formatMessage } = useIntl(); + + const { data: project } = useRedmineProject(projectId); + + return ( + <> + {project && ( + <> +
+

{project.name}

+ {project.description &&

{project.description}

} +
+ + + + + + + {project.homepage && ( + + + + + )} + + + + + {project.custom_fields?.map((field) => { + if (!field.value) return null; + if (Array.isArray(field.value) && field.value.length === 0) return null; + + const value = Array.isArray(field.value) ? field.value.join(", ") : String(field.value); + return ( + + + + + ); + })} + +
{formatMessage({ id: "issues.project.field.identifier" })}:{project.identifier}
{formatMessage({ id: "issues.project.field.homepage" })}:{project.homepage}
{formatMessage({ id: "issues.project.field.is-public" })}:{project.is_public ? formatMessage({ id: "general.yes" }) : formatMessage({ id: "general.no" })}
{field.name}:{value}
+ + )} +

{formatMessage({ id: "issues.project-tooltip.open-in-redmine" })}

+ + ); +}; diff --git a/src/components/issues/SpentVsEstimatedTime.tsx b/src/components/issue/SpentVsEstimatedTime.tsx similarity index 95% rename from src/components/issues/SpentVsEstimatedTime.tsx rename to src/components/issue/SpentVsEstimatedTime.tsx index 696d89e2..7e61c026 100644 --- a/src/components/issues/SpentVsEstimatedTime.tsx +++ b/src/components/issue/SpentVsEstimatedTime.tsx @@ -1,6 +1,6 @@ import clsx from "clsx"; +import { TIssue } from "../../api/redmine/types"; import useFormatHours from "../../hooks/useFormatHours"; -import { TIssue } from "../../types/redmine"; import { roundHours } from "../../utils/date"; interface PropTypes extends React.ComponentProps<"span"> { diff --git a/src/components/issue/VersionTooltip.tsx b/src/components/issue/VersionTooltip.tsx new file mode 100644 index 00000000..b7e74233 --- /dev/null +++ b/src/components/issue/VersionTooltip.tsx @@ -0,0 +1,62 @@ +import { differenceInDays, parseISO, startOfDay } from "date-fns"; +import { ReactElement } from "react"; +import { useIntl } from "react-intl"; +import { TVersion } from "../../api/redmine/types"; +import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"; + +type PropTypes = { + version: TVersion; +}; + +export const VersionTooltip = ({ children, ...props }: PropTypes & { children: ReactElement }) => { + return ( + + + + + + + ); +}; + +export const VersionTooltipContent = ({ version }: PropTypes) => { + const { formatMessage, formatDate, formatRelativeTime } = useIntl(); + + return ( + <> +
+

+ {version.name} {version.due_date && <>({formatRelativeTime(differenceInDays(parseISO(version.due_date), startOfDay(new Date())), "days")})} +

+ {version.description &&

{version.description}

} +
+ + + + + + + {version.due_date && ( + + + + + )} + {version.custom_fields?.map((field) => { + if (!field.value) return null; + if (Array.isArray(field.value) && field.value.length === 0) return null; + + const value = Array.isArray(field.value) ? field.value.join(", ") : String(field.value); + return ( + + + + + ); + })} + +
{formatMessage({ id: "issues.version.field.status" })}:{version.status}
{formatMessage({ id: "issues.version.field.due-date" })}:{formatDate(parseISO(version.due_date))}
{field.name}:{value}
+

{formatMessage({ id: "issues.version-tooltip.open-in-redmine" })}

+ + ); +}; diff --git a/src/components/issue/form/IssueForm.tsx b/src/components/issue/form/IssueForm.tsx new file mode 100644 index 00000000..d4bc3a5b --- /dev/null +++ b/src/components/issue/form/IssueForm.tsx @@ -0,0 +1,304 @@ +/* eslint-disable react/no-children-prop */ +import { useRedmineCurrentUser } from "@/api/redmine/hooks/useRedmineCurrentUser"; +import { useRedmineIssueAllowedStatuses } from "@/api/redmine/hooks/useRedmineIssueAllowedStatuses"; +import { useRedmineProject } from "@/api/redmine/hooks/useRedmineProject"; +import { DialogFooter } from "@/components/ui/dialog"; +import { Form, FormGrid } from "@/components/ui/form"; +import { parseISO } from "date-fns"; +import { useIntl } from "react-intl"; +import { z } from "zod"; +import { useRedmineIssuePriorities } from "../../../api/redmine/hooks/useRedmineIssuePriorities"; +import { useRedmineProjectIssueTrackers } from "../../../api/redmine/hooks/useRedmineProjectIssueTrackers"; +import { TIssue } from "../../../api/redmine/types"; +import { useAppForm } from "../../../hooks/useAppForm"; +import DismissibleWarning from "../../general/DismissableWarning"; +import AssigneeField from "./fields/AssigneeField"; +import CategoryField from "./fields/CategoryField"; +import DoneRatioField from "./fields/DoneRatioField"; +import PriorityField from "./fields/PriorityField"; +import VersionField from "./fields/VersionField"; + +type PropTypes = + | { + action: "create"; + projectId: number; + onSubmit: (data: TCreateOrEditIssueForm) => Promise; + } + | { + action: "edit"; + issue: TIssue; + onSubmit: (data: TCreateOrEditIssueForm) => Promise; + }; + +const createOrEditIssueFormSchema = ({ formatMessage }: { formatMessage: ReturnType["formatMessage"] }) => + z + .object({ + project_id: z.int(), + tracker_id: z.int(formatMessage({ id: "issues.issue.field.tracker.validation.required" })), + status_id: z.int(formatMessage({ id: "issues.issue.field.status.validation.required" })), + subject: z.string().nonempty(formatMessage({ id: "issues.issue.field.subject.validation.required" })), + description: z.string().nullable(), + priority_id: z.int(formatMessage({ id: "issues.issue.field.priority.validation.required" })), + assigned_to_id: z.int().nullable(), + category_id: z.int().nullable(), + fixed_version_id: z.int().nullable(), + start_date: z.date().nullable(), + due_date: z.date().nullable(), + estimated_hours: z.number().nullable(), + done_ratio: z.int().min(0).max(100), + }) + .check((ctx) => { + if (ctx.value.start_date && ctx.value.due_date && ctx.value.start_date > ctx.value.due_date) { + ctx.issues.push({ + code: "custom", + input: ctx.value.start_date, + path: ["due_date"], + message: formatMessage({ id: "issues.issue.field.due-date.validation.greater-than-start-date" }), + }); + } + }); + +type TCreateOrEditIssueForm = z.infer>; + +export const IssueForm = (props: PropTypes) => { + const { formatMessage } = useIntl(); + + const projectId = props.action === "create" ? props.projectId : props.issue.project.id; + + const { data: me } = useRedmineCurrentUser(); + const projectQuery = useRedmineProject(projectId); + const issueTrackers = useRedmineProjectIssueTrackers(projectId); + const issuePriorities = useRedmineIssuePriorities(); + const issueAllowedStatuses = useRedmineIssueAllowedStatuses(props.action === "edit" ? props.issue.id : 0, { + enabled: props.action === "edit", + staleTime: 0, + }); + + const form = useAppForm({ + defaultValues: + props.action === "create" + ? ({ + project_id: projectId, + tracker_id: issueTrackers.defaultTracker?.id, + status_id: issueTrackers.defaultTracker?.default_status?.id, + subject: "", + description: null, + priority_id: issuePriorities.defaultPriority?.id, + assigned_to_id: me?.id ?? null, + category_id: null, + fixed_version_id: projectQuery.data?.default_version?.id ?? null, + start_date: null, + due_date: null, + estimated_hours: null, + done_ratio: 0, + } satisfies Partial as TCreateOrEditIssueForm) + : ({ + project_id: props.issue.project.id, + tracker_id: props.issue.tracker.id, + status_id: props.issue.status.id, + subject: props.issue.subject, + description: props.issue.description ?? null, + priority_id: props.issue.priority.id, + assigned_to_id: props.issue.assigned_to?.id ?? null, + category_id: props.issue.category?.id ?? null, + fixed_version_id: props.issue.fixed_version?.id ?? null, + start_date: props.issue.start_date ? parseISO(props.issue.start_date) : null, + due_date: props.issue.due_date ? parseISO(props.issue.due_date) : null, + estimated_hours: props.issue.estimated_hours ?? null, + done_ratio: props.issue.done_ratio, + } satisfies TCreateOrEditIssueForm as TCreateOrEditIssueForm), + validators: { + onChange: createOrEditIssueFormSchema({ formatMessage }), + }, + onSubmit: async ({ value }) => { + await props.onSubmit(value); + }, + }); + + return ( +
+ { + const selectedTracker = issueTrackers.trackers?.find((tracker) => tracker.id === state.values.tracker_id); + const hasTrackerNoEnabledFields = selectedTracker && selectedTracker.enabled_standard_fields === undefined; + return { + selectedTracker, + hasTrackerNoEnabledFields, + }; + }} + children={({ selectedTracker, hasTrackerNoEnabledFields }) => ( + <> + + ( + ({ + label: tracker.name, + value: tracker.id, + })) ?? [] + } + isLoading={issueTrackers.isPending} + className="col-span-1" + /> + )} + listeners={{ + onChange: ({ value }) => { + if (props.action === "create") { + const selectedTracker = issueTrackers.trackers?.find((tracker) => tracker.id === value); + form.setFieldValue("status_id", selectedTracker?.default_status?.id ?? 0); + } + }, + }} + /> + + ( + ({ + label: status.name, + value: status.id, + })) ?? []) + } + className="col-span-1" + /> + )} + /> + + ( + + )} + /> + + {(hasTrackerNoEnabledFields || selectedTracker?.enabled_standard_fields?.includes("description")) && ( + ( + + )} + /> + )} + + + } /> + + {(hasTrackerNoEnabledFields || selectedTracker?.enabled_standard_fields?.includes("assigned_to_id")) && ( + } /> + )} + + {(hasTrackerNoEnabledFields || selectedTracker?.enabled_standard_fields?.includes("category_id")) && ( + } /> + )} + + {(hasTrackerNoEnabledFields || selectedTracker?.enabled_standard_fields?.includes("fixed_version_id")) && ( + } /> + )} + + + + {(hasTrackerNoEnabledFields || selectedTracker?.enabled_standard_fields?.includes("start_date")) && ( + ({ + due_date: state.values.due_date, + })} + children={({ due_date }) => ( + ( + + )} + /> + )} + /> + )} + + {(hasTrackerNoEnabledFields || selectedTracker?.enabled_standard_fields?.includes("due_date")) && ( + ({ + start_date: state.values.start_date, + })} + children={({ start_date }) => ( + ( + + )} + /> + )} + /> + )} + + {(hasTrackerNoEnabledFields || selectedTracker?.enabled_standard_fields?.includes("estimated_hours")) && ( + ( + + )} + /> + )} + + {hasTrackerNoEnabledFields || (selectedTracker?.enabled_standard_fields?.includes("done_ratio") && } />)} + + + + {props.action === "create" && issueAllowedStatuses.hasIssueNoAllowedStatuses && ( + {formatMessage({ id: "issues.modal.edit-issue.issue-with-no-allowed-statuses.warning" })} + )} + + {hasTrackerNoEnabledFields && ( + {formatMessage({ id: "issues.modal.add-issue.tracker-with-no-enabled-fields.warning" })} + )} + + {formatMessage({ id: "issues.modal.add-issue.unknown-workflow-permissions.warning" })} + + )} + /> + + + + + + + ); +}; diff --git a/src/components/issue/form/fields/ActivityField.tsx b/src/components/issue/form/fields/ActivityField.tsx new file mode 100644 index 00000000..84f53f85 --- /dev/null +++ b/src/components/issue/form/fields/ActivityField.tsx @@ -0,0 +1,31 @@ +import { useRedmineProjectTimeEntryActivities } from "@/api/redmine/hooks/useRedmineProjectTimeEntryActivities"; +import { ComboboxField } from "@/components/form/ComboboxField"; +import { ComponentProps } from "react"; +import { useIntl } from "react-intl"; + +type Props = { + projectId: number; +}; + +const ActivityField = ({ projectId, ...props }: Omit, "items" | "isLoading"> & Props) => { + const { formatMessage } = useIntl(); + + const timeEntryActivities = useRedmineProjectTimeEntryActivities(projectId); + + return ( + ({ + label: activity.name, + value: activity.id, + })) ?? [] + } + isLoading={timeEntryActivities.isPending} + /> + ); +}; + +export default ActivityField; diff --git a/src/components/issue/form/fields/AssigneeField.tsx b/src/components/issue/form/fields/AssigneeField.tsx new file mode 100644 index 00000000..d8a6210e --- /dev/null +++ b/src/components/issue/form/fields/AssigneeField.tsx @@ -0,0 +1,52 @@ +import { useRedmineCurrentUser } from "@/api/redmine/hooks/useRedmineCurrentUser"; +import { useRedmineProjectMembers } from "@/api/redmine/hooks/useRedmineProjectMembers"; +import { ComboboxField } from "@/components/form/ComboboxField"; +import { groupMembers } from "@/utils/groupMembers"; +import { ComponentProps, useMemo, useState } from "react"; +import { useIntl } from "react-intl"; + +type Props = { + projectId: number; +}; + +const AssigneeField = ({ projectId, ...props }: Omit, "items" | "isLoading"> & Props) => { + const { formatMessage } = useIntl(); + + const [fetchMembers, setFetchMembers] = useState(false); + + const { data: me } = useRedmineCurrentUser(); + const members = useRedmineProjectMembers(projectId, { + enabled: fetchMembers, + }); + const groupedMembers = useMemo(() => groupMembers(members.members), [members.members]); + + return ( + open && setFetchMembers(true)} + items={ + fetchMembers + ? groupedMembers.map(({ role, users }) => ({ + label: role.name, + items: users.map((user) => ({ + value: user.id, + label: user.id === me?.id ? `${user.name} <<${formatMessage({ id: "issues.issue.field.assignee.me" })}>>` : user.name, + })), + })) + : me + ? [ + { + value: me.id, + label: `${me.firstname} ${me.lastname} <<${formatMessage({ id: "issues.issue.field.assignee.me" })}>>`, + }, + ] + : [] + } + isLoading={fetchMembers && members.isPending} + /> + ); +}; + +export default AssigneeField; diff --git a/src/components/issue/form/fields/CategoryField.tsx b/src/components/issue/form/fields/CategoryField.tsx new file mode 100644 index 00000000..91484f12 --- /dev/null +++ b/src/components/issue/form/fields/CategoryField.tsx @@ -0,0 +1,33 @@ +import { useRedmineProject } from "@/api/redmine/hooks/useRedmineProject"; +import { ComboboxField } from "@/components/form/ComboboxField"; +import { ComponentProps } from "react"; +import { useIntl } from "react-intl"; + +type Props = { + projectId: number; +}; + +const CategoryField = ({ projectId, ...props }: Omit, "items" | "isLoading"> & Props) => { + const { formatMessage } = useIntl(); + + const projectQuery = useRedmineProject(projectId); + + if (projectQuery.data?.issue_categories?.length === 0) return null; + + return ( + ({ + label: category.name, + value: category.id, + })) ?? [] + } + isLoading={projectQuery.isPending} + /> + ); +}; + +export default CategoryField; diff --git a/src/components/issues/fields/DoneRatioField.tsx b/src/components/issue/form/fields/DoneRatioField.tsx similarity index 51% rename from src/components/issues/fields/DoneRatioField.tsx rename to src/components/issue/form/fields/DoneRatioField.tsx index b46d1932..7c92f7eb 100644 --- a/src/components/issues/fields/DoneRatioField.tsx +++ b/src/components/issue/form/fields/DoneRatioField.tsx @@ -1,18 +1,16 @@ import { ComponentProps } from "react"; import { useIntl } from "react-intl"; -import ReactSelectFormik from "../../general/ReactSelectFormik"; -import { Props } from "react-select"; +import { SelectField } from "../../../form/SelectField"; -const DoneRatioField = ({ ...props }: ComponentProps & Props) => { +const DoneRatioField = ({ ...props }: Omit, "items">) => { const { formatMessage } = useIntl(); return ( - formatMessage({ id: "general.no-options" })} - options={[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100].map((value) => ({ + items={[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100].map((value) => ({ label: `${value} %`, value, }))} diff --git a/src/components/issue/form/fields/DoneSliderField.tsx b/src/components/issue/form/fields/DoneSliderField.tsx new file mode 100644 index 00000000..38ca6f0c --- /dev/null +++ b/src/components/issue/form/fields/DoneSliderField.tsx @@ -0,0 +1,39 @@ +import { Field } from "@/components/ui/field"; +import clsx from "clsx"; +import { ComponentProps } from "react"; +import { useFieldContext } from "../../../../hooks/useAppForm"; + +const DoneSliderField = ({ className, ...props }: Omit, "type" | "value" | "onChange" | "onBlur" | "min" | "max" | "step">) => { + const { state, handleChange, handleBlur } = useFieldContext(); + + return ( + +
+ handleChange(e.target.valueAsNumber)} + onBlur={handleBlur} + min="0" + max="100" + step="10" + type="range" + className={clsx( + "h-5 w-20 cursor-pointer appearance-none overflow-hidden rounded-sm border-transparent", + "to-muted bg-linear-90 from-green-600/80 dark:from-green-600/60", + "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]" + )} + style={ + { + "--tw-gradient-from-position": `${state.value * 0.9 + 10}%`, + "--tw-gradient-to-position": `${state.value * 0.9 + 10}%`, + } as React.CSSProperties + } + /> +

{state.value}%

+
+
+ ); +}; + +export { DoneSliderField }; diff --git a/src/components/issue/form/fields/PriorityField.tsx b/src/components/issue/form/fields/PriorityField.tsx new file mode 100644 index 00000000..8a44c37d --- /dev/null +++ b/src/components/issue/form/fields/PriorityField.tsx @@ -0,0 +1,25 @@ +import { useRedmineIssuePriorities } from "@/api/redmine/hooks/useRedmineIssuePriorities"; +import { ComboboxField } from "@/components/form/ComboboxField"; +import { ComponentProps } from "react"; +import { useIntl } from "react-intl"; + +const PriorityField = (props: Omit, "items" | "isLoading">) => { + const { formatMessage } = useIntl(); + + const issuePriorities = useRedmineIssuePriorities(); + + return ( + ({ + label: priority.name, + value: priority.id, + }))} + isLoading={issuePriorities.isPending} + /> + ); +}; + +export default PriorityField; diff --git a/src/components/issue/form/fields/VersionField.tsx b/src/components/issue/form/fields/VersionField.tsx new file mode 100644 index 00000000..3f78e575 --- /dev/null +++ b/src/components/issue/form/fields/VersionField.tsx @@ -0,0 +1,35 @@ +import { useRedmineProjectVersions } from "@/api/redmine/hooks/useRedmineProjectVersions"; +import { ComboboxField } from "@/components/form/ComboboxField"; +import { ComponentProps } from "react"; +import { useIntl } from "react-intl"; + +type Props = { + projectId: number; +}; + +const VersionField = ({ projectId, ...props }: Omit, "items" | "isLoading"> & Props) => { + const { formatMessage } = useIntl(); + + const projectVersionsQuery = useRedmineProjectVersions(projectId); + + if (projectVersionsQuery.data?.length === 0) return null; + + return ( + version.status === "open") + .map((version) => ({ + label: version.name, + value: version.id, + })) ?? [] + } + isLoading={projectVersionsQuery.isPending} + /> + ); +}; + +export default VersionField; diff --git a/src/components/issues/AddIssueNotesModal.tsx b/src/components/issues/AddIssueNotesModal.tsx deleted file mode 100644 index 20c86a06..00000000 --- a/src/components/issues/AddIssueNotesModal.tsx +++ /dev/null @@ -1,105 +0,0 @@ -import { useMutation, useQueryClient } from "@tanstack/react-query"; -import { AxiosError, isAxiosError } from "axios"; -import { FastField, Form, Formik, FormikProps } from "formik"; -import { useRef } from "react"; -import { FormattedMessage, useIntl } from "react-intl"; -import * as Yup from "yup"; -import { useRedmineApi } from "../../provider/RedmineApiProvider"; -import { useSettings } from "../../provider/SettingsProvider"; -import { TIssue, TRedmineError, TUpdateIssue } from "../../types/redmine"; -import Button from "../general/Button"; -import LoadingSpinner from "../general/LoadingSpinner"; -import Modal from "../general/Modal"; -import TextareaField from "../general/TextareaField"; -import Toast from "../general/Toast"; -import Toggle from "../general/Toggle"; - -type PropTypes = { - issue: TIssue; - onClose: () => void; - onSuccess: () => void; -}; - -const AddIssueNotesModal = ({ issue, onClose, onSuccess }: PropTypes) => { - const { formatMessage } = useIntl(); - const { settings } = useSettings(); - const redmineApi = useRedmineApi(); - const queryClient = useQueryClient(); - - const formik = useRef>(null); - - const updateIssueMutation = useMutation({ - mutationFn: (data: TUpdateIssue) => redmineApi.updateIssue(issue.id, data), - onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["issues"] }); - onSuccess(); - }, - }); - - return ( - <> - - - innerRef={formik} - initialValues={{ - notes: "", - private_notes: false, - }} - validationSchema={Yup.object({ - notes: Yup.string().required(formatMessage({ id: "issues.issue.field.notes.validation.required" })), - private_notes: Yup.boolean(), - })} - onSubmit={async (values, { setSubmitting }) => { - await updateIssueMutation.mutateAsync(values); - setSubmitting(false); - }} - > - {({ isSubmitting, touched, errors }) => { - return ( -
-
-

- - {issue.tracker.name} #{issue.id} - {" "} - {issue.subject} -

- - - - - - -
-
- ); - }} - -
- {updateIssueMutation.isError && ( - ).response?.data?.errors?.join(", ") ?? (updateIssueMutation.error as AxiosError).message) - : (updateIssueMutation.error as Error).message - } - /> - )} - - ); -}; - -export default AddIssueNotesModal; diff --git a/src/components/issues/CreateIssueModal.tsx b/src/components/issues/CreateIssueModal.tsx deleted file mode 100644 index 4f8ed960..00000000 --- a/src/components/issues/CreateIssueModal.tsx +++ /dev/null @@ -1,327 +0,0 @@ -import { useMutation, useQueryClient } from "@tanstack/react-query"; -import { AxiosError, isAxiosError } from "axios"; -import { FastField, Field, Form, Formik, FormikProps } from "formik"; -import { useEffect, useRef } from "react"; -import { FormattedMessage, useIntl } from "react-intl"; -import * as Yup from "yup"; -import useIssuePriorities from "../../hooks/useIssuePriorities"; -import useIssueTrackers from "../../hooks/useIssueTrackers"; -import useMyUser from "../../hooks/useMyUser"; -import useProject from "../../hooks/useProject"; -import { useRedmineApi } from "../../provider/RedmineApiProvider"; -import { useSettings } from "../../provider/SettingsProvider"; -import { TCreateIssue, TRedmineError } from "../../types/redmine"; -import Button from "../general/Button"; -import DateField, { shouldUpdate as shouldUpdateDateField } from "../general/DateField"; -import DismissibleWarning from "../general/DismissableWarning"; -import InputField from "../general/InputField"; -import LoadingSpinner from "../general/LoadingSpinner"; -import Modal from "../general/Modal"; -import ReactSelectFormik, { shouldUpdate as shouldUpdateReactSelect } from "../general/ReactSelectFormik"; -import TextareaField from "../general/TextareaField"; -import TimeField from "../general/TimeField"; -import Toast from "../general/Toast"; -import AssigneeField from "./fields/AssigneeField"; -import CategoryField from "./fields/CategoryField"; -import DoneRatioField from "./fields/DoneRatioField"; -import PriorityField from "./fields/PriorityField"; -import VersionField from "./fields/VersionField"; - -type PropTypes = { - projectId: number; - onClose: () => void; - onSuccess: () => void; -}; - -const CreateIssueModal = ({ projectId, onClose, onSuccess }: PropTypes) => { - const { formatMessage } = useIntl(); - const { settings } = useSettings(); - const redmineApi = useRedmineApi(); - const queryClient = useQueryClient(); - - const formik = useRef>(null); - - const myUser = useMyUser(); - const project = useProject(projectId); - const issueTrackers = useIssueTrackers(projectId); - const issuePriorities = useIssuePriorities(); - - useEffect(() => { - formik.current?.setFieldValue("tracker_id", issueTrackers.defaultTracker?.id); - }, [issueTrackers.defaultTracker]); - - useEffect(() => { - formik.current?.setFieldValue("priority_id", issuePriorities.defaultPriority?.id); - }, [issuePriorities.defaultPriority]); - - useEffect(() => { - formik.current?.setFieldValue("assigned_to_id", myUser.data?.id); - }, [myUser.data?.id]); - - useEffect(() => { - formik.current?.setFieldValue("fixed_version_id", project.data?.default_version?.id); - }, [project.data?.default_version?.id]); - - const createIssueMutation = useMutation({ - mutationFn: (issue: TCreateIssue) => redmineApi.createIssue(issue), - onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["issues"] }); - onSuccess(); - }, - }); - - return ( - <> - - - innerRef={formik} - initialValues={ - { - project_id: projectId, - } satisfies Partial as TCreateIssue - } - validationSchema={Yup.object({ - tracker_id: Yup.number().required(formatMessage({ id: "issues.issue.field.tracker.validation.required" })), - status_id: Yup.number().required(formatMessage({ id: "issues.issue.field.status.validation.required" })), - subject: Yup.string().required(formatMessage({ id: "issues.issue.field.subject.validation.required" })), - description: Yup.string(), - priority_id: Yup.number().required(formatMessage({ id: "issues.issue.field.priority.validation.required" })), - assigned_to_id: Yup.number().nullable(), - category_id: Yup.number().nullable(), - fixed_version_id: Yup.number().nullable(), - start_date: Yup.date().nullable(), - due_date: Yup.date() - .nullable() - .when("start_date", ([start_date], schema) => (start_date ? schema.min(start_date, formatMessage({ id: "issues.issue.field.due-date.validation.greater-than-start-date" })) : schema)), - estimated_hours: Yup.number() - .nullable() - .min(0.01, formatMessage({ id: "issues.issue.field.estimated-hours.validation.greater-than-zero" })), - done_ratio: Yup.number().nullable().min(0).max(100), - })} - onSubmit={async (values, { setSubmitting }) => { - await createIssueMutation.mutateAsync(values); - setSubmitting(false); - }} - > - {({ isSubmitting, values, touched, errors, setFieldValue }) => { - const selectedTracker = issueTrackers.data?.find((tracker) => tracker.id === values.tracker_id); - const hasTrackerNoEnabledFields = selectedTracker && selectedTracker.enabled_standard_fields === undefined; - if (selectedTracker && values.status_id !== selectedTracker.default_status?.id) { - setFieldValue("status_id", selectedTracker.default_status?.id); - } - return ( -
-
-
- formatMessage({ id: "general.no-options" })} - error={touched.tracker_id && errors.tracker_id} - required - as={ReactSelectFormik} - size="sm" - options={issueTrackers.data?.map((tracker) => ({ - label: tracker.name, - value: tracker.id, - }))} - isLoading={issueTrackers.isLoading} - shouldUpdate={shouldUpdateReactSelect} - /> - - formatMessage({ id: "general.no-options" })} - error={touched.status_id && errors.status_id} - required - isDisabled - as={ReactSelectFormik} - size="sm" - options={ - selectedTracker?.default_status - ? [ - { - label: selectedTracker.default_status.name, - value: selectedTracker.default_status.id, - }, - ] - : [] - } - shouldUpdate={shouldUpdateReactSelect} - /> -
- - - - {(hasTrackerNoEnabledFields || selectedTracker?.enabled_standard_fields?.includes("description")) && ( - - )} - -
-
- - - {(hasTrackerNoEnabledFields || selectedTracker?.enabled_standard_fields?.includes("assigned_to_id")) && ( - - )} - - {(hasTrackerNoEnabledFields || selectedTracker?.enabled_standard_fields?.includes("category_id")) && ( - - )} - - {(hasTrackerNoEnabledFields || selectedTracker?.enabled_standard_fields?.includes("fixed_version_id")) && ( - - )} -
-
- {(hasTrackerNoEnabledFields || selectedTracker?.enabled_standard_fields?.includes("start_date")) && ( - - )} - - {(hasTrackerNoEnabledFields || selectedTracker?.enabled_standard_fields?.includes("due_date")) && ( - - )} - - {(hasTrackerNoEnabledFields || selectedTracker?.enabled_standard_fields?.includes("estimated_hours")) && - (settings.style.timeFormat === "decimal" ? ( - - ) : ( - - ))} - - {hasTrackerNoEnabledFields || - (selectedTracker?.enabled_standard_fields?.includes("done_ratio") && ( - - ))} -
-
- - {hasTrackerNoEnabledFields && ( - - - - )} - - - - - - -
-
- ); - }} - -
- {createIssueMutation.isError && ( - ).response?.data?.errors?.join(", ") ?? (createIssueMutation.error as AxiosError).message) - : (createIssueMutation.error as Error).message - } - /> - )} - - ); -}; - -export default CreateIssueModal; diff --git a/src/components/issues/CreateTimeEntryModal.tsx b/src/components/issues/CreateTimeEntryModal.tsx deleted file mode 100644 index 7e06989e..00000000 --- a/src/components/issues/CreateTimeEntryModal.tsx +++ /dev/null @@ -1,351 +0,0 @@ -import { useMutation, useQueryClient } from "@tanstack/react-query"; -import { AxiosError, isAxiosError } from "axios"; -import { startOfDay } from "date-fns"; -import { FastField, Form, Formik, FormikProps } from "formik"; -import { useEffect, useRef } from "react"; -import { FormattedMessage, useIntl } from "react-intl"; -import * as Yup from "yup"; -import useMyProjectRoles from "../../hooks/useMyProjectRoles"; -import useMyUser from "../../hooks/useMyUser"; -import useProject from "../../hooks/useProject"; -import useStorage from "../../hooks/useStorage"; -import useTimeEntryActivities from "../../hooks/useTimeEntryActivities"; -import { useRedmineApi } from "../../provider/RedmineApiProvider"; -import { useSettings } from "../../provider/SettingsProvider"; -import { TCreateTimeEntry, TIssue, TRedmineError, TUpdateIssue } from "../../types/redmine"; -import { clsxm } from "../../utils/clsxm"; -import { formatHoursUsually } from "../../utils/date"; -import Button from "../general/Button"; -import DateField from "../general/DateField"; -import Fieldset from "../general/Fieldset"; -import InputField from "../general/InputField"; -import LoadingSpinner from "../general/LoadingSpinner"; -import Modal from "../general/Modal"; -import ReactSelectFormik, { shouldUpdate } from "../general/ReactSelectFormik"; -import TextareaField from "../general/TextareaField"; -import TimeField from "../general/TimeField"; -import Toast from "../general/Toast"; -import Toggle from "../general/Toggle"; -import TimeEntryPreview from "../time/TimeEntryPreview"; -import DoneSlider from "./DoneSlider"; -import SpentVsEstimatedTime from "./SpentVsEstimatedTime"; -import TimeEntryUsersField from "./fields/TimeEntryUsersField"; - -type PropTypes = { - issue: TIssue; - time: number; - onClose: () => void; - onSuccess: () => void; -}; - -type TCreateTimeEntryForm = Omit & - Pick & { - user_id?: number[]; - add_notes?: boolean; - }; - -const _defaultCachedComments = {}; - -const CreateTimeEntryModal = ({ issue, time, onClose, onSuccess }: PropTypes) => { - const { formatMessage } = useIntl(); - const { settings } = useSettings(); - const redmineApi = useRedmineApi(); - const queryClient = useQueryClient(); - - const formik = useRef>(null); - - const myUser = useMyUser(); - const project = useProject(issue.project.id); - const projectRoles = useMyProjectRoles([issue.project.id]); - const timeEntryActivities = useTimeEntryActivities(issue.project.id); - - const cachedComments = useStorage>("cachedComments", _defaultCachedComments); - - useEffect(() => { - formik.current?.setFieldValue("activity_id", timeEntryActivities.defaultActivity?.id); - }, [timeEntryActivities.defaultActivity]); - - useEffect(() => { - if (myUser.data?.id) { - formik.current?.setFieldValue("user_id", [myUser.data.id]); - } - }, [myUser.data?.id]); - - useEffect(() => { - if (!settings.features.cacheComments) return; - // load cached comment to formik - const comments = cachedComments.data[issue.id]; - if (comments) { - formik.current?.setFieldValue("comments", comments); - } - }, [settings.features.cacheComments, issue.id, cachedComments.data]); - - const createTimeEntryMutation = useMutation({ - mutationFn: (entry: TCreateTimeEntry) => redmineApi.createTimeEntry(entry), - onSuccess: (_, entry) => { - // if entry created for me => invalidate query - if (!entry.user_id || entry.user_id === myUser.data?.id) { - queryClient.invalidateQueries({ - queryKey: ["timeEntries"], - }); - } - }, - }); - - const updateIssueMutation = useMutation({ - mutationFn: (data: TUpdateIssue) => redmineApi.updateIssue(issue.id, data), - onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["issues"] }); - }, - }); - - return ( - <> - { - if (settings.features.cacheComments) { - // if comment or already cached => save/update comment - const comments = formik.current?.values.comments; - if (comments || cachedComments.data[issue.id]) { - cachedComments.setData({ ...cachedComments.data, [issue.id]: comments }); - } - } - onClose(); - }} - > - - innerRef={formik} - initialValues={ - { - issue_id: issue.id, - done_ratio: issue.done_ratio, - hours: Number((time / 1000 / 60 / 60).toFixed(2)), - spent_on: new Date(), - user_id: undefined, - comments: "", - activity_id: undefined, - add_notes: false, - notes: "", - } satisfies Partial as unknown as TCreateTimeEntryForm - } - validationSchema={Yup.object({ - done_ratio: Yup.number().min(0).max(100), - hours: Yup.number() - .required(formatMessage({ id: "time.time-entry.field.hours.validation.required" })) - .min(0.01, formatMessage({ id: "time.time-entry.field.hours.validation.greater-than-zero" })) - .max(24, formatMessage({ id: "time.time-entry.field.hours.validation.less-than-24" })), - spent_on: Yup.date() - .required(formatMessage({ id: "time.time-entry.field.spent-on.validation.required" })) - .max(new Date(), formatMessage({ id: "time.time-entry.field.spent-on.validation.in-future" })), - user_id: Yup.array(Yup.number()), - comments: Yup.string(), - activity_id: Yup.number().required(formatMessage({ id: "time.time-entry.field.activity.validation.required" })), - add_notes: Yup.boolean(), - notes: Yup.string(), - })} - onSubmit={async (originalValues, { setSubmitting }) => { - const values = { ...originalValues }; - if (values.done_ratio !== issue.done_ratio || (values.add_notes && values.notes)) { - await updateIssueMutation.mutateAsync({ done_ratio: values.done_ratio !== issue.done_ratio ? values.done_ratio : undefined, notes: values.add_notes ? values.notes : undefined }); - } - delete values.done_ratio; - delete values.add_notes; - delete values.notes; - if (values.user_id && Array.isArray(values.user_id) && values.user_id.length > 0) { - // create for multiple users - for (const userId of values.user_id) { - await createTimeEntryMutation.mutateAsync({ ...values, user_id: userId }); - } - } else { - // create for me - await createTimeEntryMutation.mutateAsync({ ...values, user_id: undefined as never }); - } - setSubmitting(false); - if (!createTimeEntryMutation.isError) { - if (settings.features.cacheComments) { - // if has cached comment => remove it - if (cachedComments.data[issue.id]) { - cachedComments.setData({ ...cachedComments.data, [issue.id]: undefined }); - } - } - onSuccess(); - } - }} - > - {({ isSubmitting, touched, errors, values }) => ( -
-
-

- - {issue.tracker.name} #{issue.id} - {" "} - {issue.subject} -

- -
- - - -
- - {values.spent_on && } - -
-
- {settings.style.timeFormat === "decimal" ? ( - = 0 && values.hours <= 24 - ? formatMessage( - { id: "format.hours" }, - { - hours: formatHoursUsually(values.hours), - } - ) - : undefined - } - autoComplete="off" - className="col-span-3" - /> - ) : ( - - )} - - -
- - {projectRoles.hasProjectPermission(project.data ?? issue.project, "log_time_for_other_users") && ( - - )} - - - - formatMessage({ id: "general.no-options" })} - error={touched.activity_id && errors.activity_id} - required - as={ReactSelectFormik} - size="sm" - options={timeEntryActivities.data?.map((activity) => ({ - label: activity.name, - value: activity.id, - }))} - isLoading={timeEntryActivities.isLoading} - shouldUpdate={shouldUpdate} - /> -
- - {settings.features.addNotes && - projectRoles.hasProjectPermission(project.data ?? issue.project, "add_issue_notes") && - (!values.add_notes ? ( - - ) : ( -
- - - {values.add_notes && ( - - )} -
- ))} - - -
-
- )} - -
- {createTimeEntryMutation.isError && ( - ).response?.data?.errors?.join(", ") ?? (createTimeEntryMutation.error as AxiosError).message) - : (createTimeEntryMutation.error as Error).message - } - /> - )} - {updateIssueMutation.isError && ( - ).response?.data?.errors?.join(", ") ?? (updateIssueMutation.error as AxiosError).message) - : (updateIssueMutation.error as Error).message - } - /> - )} - - ); -}; - -export default CreateTimeEntryModal; diff --git a/src/components/issues/CurrentIssueTimer.tsx b/src/components/issues/CurrentIssueTimer.tsx deleted file mode 100644 index 4624ad84..00000000 --- a/src/components/issues/CurrentIssueTimer.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import useIssue from "../../hooks/useIssue"; -import useMyProjectRoles from "../../hooks/useMyProjectRoles"; -import useRedmineUrl from "../../hooks/useRedmineUrl"; -import useTimers from "../../hooks/useTimers"; -import IssueTimer from "./IssueTimer"; - -type PropTypes = { - issueId: number; -}; - -const CurrentIssueTimer = ({ issueId }: PropTypes) => { - const timers = useTimers(); - - const { data: issue } = useIssue(issueId); - const projectRoles = useMyProjectRoles(issue ? [issue.project.id] : []); - if (!issue || !projectRoles.hasProjectPermission(issue.project, "log_time")) return; - - const timer = timers.getTimer(issue.id); - - return ( -
- -
- ); -}; - -const CurrentIssueTimerWrapper = () => { - const currentUrl = useRedmineUrl(); - const issueId = currentUrl?.data?.type === "issue" ? currentUrl?.data?.id : undefined; - - if (!issueId) return null; - - return ; -}; - -export default CurrentIssueTimerWrapper; diff --git a/src/components/issues/DoneSlider.tsx b/src/components/issues/DoneSlider.tsx deleted file mode 100644 index ab860e72..00000000 --- a/src/components/issues/DoneSlider.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import clsx from "clsx"; - -interface PropTypes extends Omit, "value"> { - value: number; -} -const DoneSlider = ({ value, className, ...props }: PropTypes) => { - return ( -
- -

{value}%

-
- ); -}; - -export default DoneSlider; diff --git a/src/components/issues/EditIssueModal.tsx b/src/components/issues/EditIssueModal.tsx deleted file mode 100644 index d7fc8faa..00000000 --- a/src/components/issues/EditIssueModal.tsx +++ /dev/null @@ -1,349 +0,0 @@ -import { useMutation, useQueryClient } from "@tanstack/react-query"; -import { AxiosError, isAxiosError } from "axios"; -import { parseISO } from "date-fns"; -import { FastField, Field, Form, Formik, FormikProps } from "formik"; -import { useEffect, useRef } from "react"; -import { FormattedMessage, useIntl } from "react-intl"; -import * as Yup from "yup"; -import useIssue from "../../hooks/useIssue"; -import useIssueStatuses from "../../hooks/useIssueStatuses"; -import useIssueTrackers from "../../hooks/useIssueTrackers"; -import { useRedmineApi } from "../../provider/RedmineApiProvider"; -import { useSettings } from "../../provider/SettingsProvider"; -import { TCreateIssue, TIssue, TRedmineError, TUpdateIssue } from "../../types/redmine"; -import Button from "../general/Button"; -import DateField, { shouldUpdate as shouldUpdateDateField } from "../general/DateField"; -import DismissibleWarning from "../general/DismissableWarning"; -import InputField from "../general/InputField"; -import LoadingSpinner from "../general/LoadingSpinner"; -import Modal from "../general/Modal"; -import ReactSelectFormik, { shouldUpdate as shouldUpdateReactSelect } from "../general/ReactSelectFormik"; -import TextareaField from "../general/TextareaField"; -import TimeField from "../general/TimeField"; -import Toast from "../general/Toast"; -import AssigneeField from "./fields/AssigneeField"; -import CategoryField from "./fields/CategoryField"; -import DoneRatioField from "./fields/DoneRatioField"; -import PriorityField from "./fields/PriorityField"; -import VersionField from "./fields/VersionField"; - -type PropTypes = { - issue: TIssue; - onClose: () => void; - onSuccess: () => void; -}; - -const EditIssueModal = ({ issue: currentIssue, onClose, onSuccess }: PropTypes) => { - const { formatMessage } = useIntl(); - const { settings } = useSettings(); - const redmineApi = useRedmineApi(); - const queryClient = useQueryClient(); - - const formik = useRef>(null); - - const issueQuery = useIssue(currentIssue.id, { staleTime: 0 }); - const issueTrackers = useIssueTrackers(currentIssue.project.id); - const issueStatuses = useIssueStatuses(currentIssue.id, { - issueStaleTime: 0, - }); - - const issue = issueQuery.data ?? currentIssue; - - useEffect(() => { - if (!issue) return; - formik.current?.setValues( - { - tracker_id: issue.tracker.id, - status_id: issue.status.id, - subject: issue.subject, - description: issue.description, - priority_id: issue.priority.id, - assigned_to_id: issue.assigned_to?.id, - category_id: issue.category?.id, - fixed_version_id: issue.fixed_version?.id, - start_date: issue.start_date ? parseISO(issue.start_date) : undefined, - due_date: issue.due_date ? parseISO(issue.due_date) : undefined, - estimated_hours: issue.estimated_hours, - done_ratio: issue.done_ratio, - }, - false - ); - }, [issue]); - - const updateIssueMutation = useMutation({ - mutationFn: (data: TUpdateIssue) => redmineApi.updateIssue(issue.id, data), - onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["issues"] }); - onSuccess(); - }, - }); - - return ( - <> - - - innerRef={formik} - initialValues={{ - tracker_id: issue.tracker.id, - status_id: issue.status.id, - subject: issue.subject, - description: issue.description, - priority_id: issue.priority.id, - assigned_to_id: issue.assigned_to?.id, - category_id: issue.category?.id, - fixed_version_id: issue.fixed_version?.id, - start_date: issue.start_date ? parseISO(issue.start_date) : undefined, - due_date: issue.due_date ? parseISO(issue.due_date) : undefined, - estimated_hours: issue.estimated_hours, - done_ratio: issue.done_ratio, - }} - validationSchema={Yup.object({ - tracker_id: Yup.number().required(formatMessage({ id: "issues.issue.field.tracker.validation.required" })), - status_id: Yup.number().required(formatMessage({ id: "issues.issue.field.status.validation.required" })), - subject: Yup.string().required(formatMessage({ id: "issues.issue.field.subject.validation.required" })), - description: Yup.string().nullable(), - priority_id: Yup.number().required(formatMessage({ id: "issues.issue.field.priority.validation.required" })), - assigned_to_id: Yup.number().nullable(), - category_id: Yup.number().nullable(), - fixed_version_id: Yup.number().nullable(), - start_date: Yup.date().nullable(), - due_date: Yup.date() - .nullable() - .when("start_date", ([start_date], schema) => (start_date ? schema.min(start_date, formatMessage({ id: "issues.issue.field.due-date.validation.greater-than-start-date" })) : schema)), - estimated_hours: Yup.number() - .nullable() - .min(0.01, formatMessage({ id: "issues.issue.field.estimated-hours.validation.greater-than-zero" })), - done_ratio: Yup.number().nullable().min(0).max(100), - })} - onSubmit={async (values, { setSubmitting }) => { - await updateIssueMutation.mutateAsync(values as unknown as TCreateIssue); - setSubmitting(false); - }} - > - {({ isSubmitting, values, touched, errors }) => { - const selectedTracker = issueTrackers.data?.find((tracker) => tracker.id === values.tracker_id); - const hasTrackerNoEnabledFields = selectedTracker && selectedTracker.enabled_standard_fields === undefined; - return ( -
-
-

- - {issue.tracker.name} #{issue.id} - {" "} - {issue.subject} -

- -
- formatMessage({ id: "general.no-options" })} - error={touched.tracker_id && errors.tracker_id} - required - as={ReactSelectFormik} - size="sm" - options={issueTrackers.data?.map((tracker) => ({ - label: tracker.name, - value: tracker.id, - }))} - isLoading={issueTrackers.isLoading} - shouldUpdate={shouldUpdateReactSelect} - /> - - formatMessage({ id: "general.no-options" })} - error={touched.status_id && errors.status_id} - required - isDisabled={issue.allowed_statuses?.length === 0} - as={ReactSelectFormik} - size="sm" - options={issueStatuses.data?.map((status) => ({ - label: status.name, - value: status.id, - }))} - isLoading={issueQuery.isLoading || issueStatuses.isLoading} - shouldUpdate={shouldUpdateReactSelect} - /> -
- - - - {(hasTrackerNoEnabledFields || selectedTracker?.enabled_standard_fields?.includes("description")) && ( - - )} - -
-
- - - {(hasTrackerNoEnabledFields || selectedTracker?.enabled_standard_fields?.includes("assigned_to_id")) && ( - - )} - - {(hasTrackerNoEnabledFields || selectedTracker?.enabled_standard_fields?.includes("category_id")) && ( - - )} - - {(hasTrackerNoEnabledFields || selectedTracker?.enabled_standard_fields?.includes("fixed_version_id")) && ( - - )} -
-
- {(hasTrackerNoEnabledFields || selectedTracker?.enabled_standard_fields?.includes("start_date")) && ( - - )} - - {(hasTrackerNoEnabledFields || selectedTracker?.enabled_standard_fields?.includes("due_date")) && ( - - )} - - {(hasTrackerNoEnabledFields || selectedTracker?.enabled_standard_fields?.includes("estimated_hours")) && - (settings.style.timeFormat === "decimal" ? ( - - ) : ( - - ))} - - {hasTrackerNoEnabledFields || - (selectedTracker?.enabled_standard_fields?.includes("done_ratio") && ( - - ))} -
-
- - {issueStatuses.hasIssueNoAllowedStatuses && ( - - - - )} - - {hasTrackerNoEnabledFields && ( - - - - )} - - - - - - -
-
- ); - }} - -
- {updateIssueMutation.isError && ( - ).response?.data?.errors?.join(", ") ?? (updateIssueMutation.error as AxiosError).message) - : (updateIssueMutation.error as Error).message - } - /> - )} - - ); -}; - -export default EditIssueModal; diff --git a/src/components/issues/EditTimer.tsx b/src/components/issues/EditTimer.tsx deleted file mode 100644 index ffc71226..00000000 --- a/src/components/issues/EditTimer.tsx +++ /dev/null @@ -1,156 +0,0 @@ -import clsx from "clsx"; -import { FocusEvent, useState } from "react"; -import { FormattedMessage, useIntl } from "react-intl"; -import useHotKey from "../../hooks/useHotkey"; -import Button from "../general/Button"; -import Modal from "../general/Modal"; - -type PropTypes = { - initTime: number; - onOverrideTime: (time: number) => void; - onCancel: () => void; -}; - -const EditTimer = ({ initTime, onOverrideTime, onCancel: onConfirmCancel }: PropTypes) => { - const { formatMessage } = useIntl(); - - const [h, setH] = useState(Math.floor(initTime / 1000 / 60 / 60).toString()); - const [m, setM] = useState(to2Digit(Math.floor((initTime / 1000 / 60) % 60))); - const [s, setS] = useState(to2Digit(Math.floor((initTime / 1000) % 60))); - const updatedTime = (Number(h) * 60 * 60 + Number(m) * 60 + Number(s)) * 1000; - - const [confirmCancelModal, setConfirmCancelModal] = useState(false); - const onCancel = () => setConfirmCancelModal(true); - /** - * On "Escape" => cancel - */ - useHotKey(onConfirmCancel, { key: "Escape" }); - - return ( - <> -
- 0 ? "text-yellow-500" : "text-gray-700 dark:text-gray-500" - )} - /** - * auto focus & select input on focus - */ - autoFocus - onFocus={(e) => e.target.select()} - onChange={(e) => { - const { value, min, max } = e.target; - setH(Math.max(Number(min), Math.min(Number(max), Number(value))).toString()); - }} - /** - * On "Enter" => override time - */ - onKeyDown={(e) => { - if (e.key === "Enter") { - onOverrideTime(updatedTime); - e.preventDefault(); - } - }} - /** - * On loose focus, check if next target not a number input => cancel - */ - onBlur={(e) => { - if (!(e.relatedTarget?.localName === "input" && (e as FocusEvent).relatedTarget?.type === "number")) onCancel(); - }} - /> - : - 0 ? "text-yellow-500" : "text-gray-700 dark:text-gray-500" - )} - onChange={(e) => { - const { value, min, max } = e.target; - setM(to2Digit(Math.max(Number(min), Math.min(Number(max), Number(value))))); - }} - /** - * On "Enter" => override time - */ - onKeyDown={(e) => { - if (e.key === "Enter") { - onOverrideTime(updatedTime); - e.preventDefault(); - } - }} - /** - * On loose focus, check if next target not a number input => cancel - */ - onBlur={(e) => { - if (!(e.relatedTarget?.localName === "input" && (e as FocusEvent).relatedTarget?.type === "number")) onCancel(); - }} - /> - : - 0 ? "text-yellow-500" : "text-gray-700 dark:text-gray-500" - )} - onChange={(e) => { - const { value, min, max } = e.target; - setS(to2Digit(Math.max(Number(min), Math.min(Number(max), Number(value))))); - }} - /** - * On "Enter" => override time - */ - onKeyDown={(e) => { - if (e.key === "Enter") { - onOverrideTime(updatedTime); - e.preventDefault(); - } - }} - /** - * On loose focus, check if next target not a number input => cancel - */ - onBlur={(e) => { - if (!(e.relatedTarget?.localName === "input" && (e as FocusEvent).relatedTarget?.type === "number")) onCancel(); - }} - /> -
- {confirmCancelModal && ( - -

- -

-
- - -
-
- )} - - ); -}; - -const to2Digit = (val: number) => { - return `${val < 10 ? "0" : ""}${val}`; -}; - -export default EditTimer; diff --git a/src/components/issues/Filter.tsx b/src/components/issues/Filter.tsx deleted file mode 100644 index 5eca461b..00000000 --- a/src/components/issues/Filter.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import { faSliders, faX } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { MouseEventHandler, ReactNode, useState } from "react"; -import { FormattedMessage, useIntl } from "react-intl"; -import useHotKey from "../../hooks/useHotkey"; -import useMyProjects from "../../hooks/useMyProjects"; -import useStorage from "../../hooks/useStorage"; -import CheckBox from "../general/CheckBox"; -import ReactSelect from "../general/ReactSelect"; - -export type FilterQuery = { - projects: number[]; - hideCompletedIssues: boolean; -}; - -const defaultFilter: FilterQuery = { projects: [], hideCompletedIssues: false }; - -type PropTypes = { - children: (state: { filter: FilterQuery; isLoading: boolean }) => ReactNode; -}; - -const Filter = ({ children }: PropTypes) => { - const { formatMessage } = useIntl(); - - const [showFilter, setShowFilter] = useState(false); - - // On "Escape" => close filter - useHotKey(() => setShowFilter(false), { key: "Escape" }); - - const { data: projects, isLoading: isLoadingProjects } = useMyProjects({ - enabled: showFilter, - }); - - const { data: filter, setData: setFilter, isLoading } = useStorage("filter", defaultFilter); - - return ( - <> - {(!showFilter && ( -
- setShowFilter((show) => !show)} /> -
- )) || ( -
- setShowFilter((show) => !show)}> - - - -
- formatMessage({ id: "issues.filter.projects.no-options" })} - options={projects.map((project) => ({ value: project.id, label: project.name }))} - isLoading={isLoadingProjects} - value={filter.projects.map((id) => ({ value: id, label: projects.find((p) => p.id === id)?.name ?? "..." }))} - onChange={(selected) => { - setFilter({ - ...filter, - projects: selected.map((v) => v.value), - }); - }} - isMulti - isClearable - closeMenuOnSelect={false} - menuPortalTarget={document.body} - /> - setFilter({ ...filter, hideCompletedIssues: e.target.checked })} - /> -
-
- )} - {children({ filter, isLoading })} - - ); -}; - -const FilterButton = ({ onClick }: { onClick?: MouseEventHandler }) => { - return ( - - ); -}; - -export default Filter; diff --git a/src/components/issues/Issue.tsx b/src/components/issues/Issue.tsx deleted file mode 100644 index c06bd3c3..00000000 --- a/src/components/issues/Issue.tsx +++ /dev/null @@ -1,266 +0,0 @@ -import { faCopy } from "@fortawesome/free-regular-svg-icons"; -import { faArrowUpRightFromSquare, faBan, faBookmark, faCircleUser, faNoteSticky, faPause, faPen, faPlay, faStop, faThumbTack, faXmark } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import clsx from "clsx"; -import { useRef, useState } from "react"; -import { FormattedMessage, PrimitiveType, useIntl } from "react-intl"; -import { Tooltip } from "react-tooltip"; -import { Timer } from "../../hooks/useTimers"; -import { useSettings } from "../../provider/SettingsProvider"; -import { TIssue } from "../../types/redmine"; -import { clsxm } from "../../utils/clsxm"; -import ContextMenu from "../general/ContextMenu"; -import KBD from "../general/KBD"; -import Toast from "../general/Toast"; -import AddIssueNotesModal from "./AddIssueNotesModal"; -import CreateTimeEntryModal from "./CreateTimeEntryModal"; -import EditIssueModal from "./EditIssueModal"; -import IssueInfoTooltip from "./IssueInfoTooltip"; -import IssueTimer, { TimerRef } from "./IssueTimer"; - -type PropTypes = { - issue: TIssue; - priorityType: PrimitiveType; - assignedToMe: boolean; - canEdit: boolean; - canLogTime: boolean; - canAddNotes: boolean; - timer: Timer; -}; - -const Issue = ({ issue, priorityType, assignedToMe, canEdit, canLogTime, canAddNotes, timer }: PropTypes) => { - const { formatMessage } = useIntl(); - - const { settings } = useSettings(); - - const timerRef = useRef(null); - - const [createTimeEntry, setCreateTimeEntry] = useState(undefined); - const [copiedIdToClipboard, setCopiedIdToClipboard] = useState(false); - const [editIssue, setEditIssue] = useState(false); - const [addNotes, setAddNotes] = useState(false); - - return ( - <> - , - onClick: () => { - window.open(`${settings.redmineURL}/issues/${issue.id}`, "_blank"); - }, - }, - ], - [ - { - name: formatMessage({ id: "issues.context-menu.copy-id-to-clipboard" }), - icon: , - onClick: () => { - navigator.clipboard.writeText(`#${issue.id}`); - setCopiedIdToClipboard(true); - }, - }, - ], - [ - { - name: formatMessage({ id: "issues.context-menu.edit" }), - icon: , - onClick: () => setEditIssue(true), - disabled: !canEdit, - }, - { - name: formatMessage({ id: "issues.context-menu.add-notes" }), - icon: , - onClick: () => setAddNotes(true), - disabled: !canAddNotes, - }, - ], - [ - { - name: formatMessage({ id: "issues.context-menu.timer.start" }), - icon: , - disabled: timer.active || !canLogTime, - onClick: timer.startTimer, - }, - { - name: formatMessage({ id: "issues.context-menu.timer.pause" }), - icon: , - disabled: !timer.active || !canLogTime, - onClick: timer.pauseTimer, - }, - { - name: formatMessage({ id: "issues.context-menu.timer.reset" }), - icon: , - disabled: timer.getCurrentTime() === 0 || !canLogTime, - onClick: timer.resetTimer, - }, - { - name: formatMessage({ id: "issues.context-menu.timer.edit" }), - icon: , - disabled: timer.getCurrentTime() === 0 || !canLogTime, - onClick: () => timerRef.current?.editTimer(), - }, - ], - [ - { - name: formatMessage({ id: assignedToMe || timer.remembered ? "issues.context-menu.pin" : "issues.context-menu.pin-and-remember" }), - icon: , - disabled: timer.pinned, - onClick: () => (assignedToMe || timer.remembered ? timer.setPinned(true) : timer.setRememberedAndPinned(true, true)), - }, - { - name: formatMessage({ id: "issues.context-menu.unpin" }), - icon: , - disabled: !timer.pinned, - onClick: () => timer.setPinned(false), - }, - ], - ...(!assignedToMe - ? [ - [ - { - name: formatMessage({ id: "issues.context-menu.remember" }), - icon: , - disabled: timer.remembered, - onClick: () => timer.setRemembered(true), - }, - { - name: formatMessage({ id: "issues.context-menu.forgot" }), - icon: , - disabled: !timer.remembered, - onClick: () => timer.setRemembered(false), - }, - ], - ] - : []), - ]} - > -
toggle timer - */ - onKeyDown={(e) => { - if (e.key === "Enter" || e.code === "Space") { - // ignore in edit mode - if (timerRef.current?.isInEditMode) return; - - if (!canLogTime) return; - - if (timer.active) { - timer.pauseTimer(); - } else { - timer.startTimer(); - } - e.preventDefault(); - } - }} - data-tooltip-id={`tooltip-toggle-timer-${issue.id}`} - > -

- - #{issue.id} - {" "} - {issue.subject} -

- -
-
-
-
- {issue.done_ratio}% -
-
-
- {canLogTime && ( -
- -
- )} -
-
- {timer.pinned && ( - <> - {settings.style.showTooltips && } - - - )} - {!assignedToMe && ( - <> - {settings.style.showTooltips && ( - - )} - - - )} -
-
-
- {settings.style.showTooltips && ( - - {children}, - }} - /> - - )} - {createTimeEntry !== undefined && ( - setCreateTimeEntry(undefined)} - onSuccess={() => { - setCreateTimeEntry(undefined); - timer.resetTimer(); - }} - /> - )} - {editIssue && setEditIssue(false)} onSuccess={() => setEditIssue(false)} />} - {addNotes && setAddNotes(false)} onSuccess={() => setAddNotes(false)} />} - {copiedIdToClipboard && ( - setCopiedIdToClipboard(false)} /> - )} - - ); -}; - -export default Issue; diff --git a/src/components/issues/IssueInfoTooltip.tsx b/src/components/issues/IssueInfoTooltip.tsx deleted file mode 100644 index 0119c289..00000000 --- a/src/components/issues/IssueInfoTooltip.tsx +++ /dev/null @@ -1,102 +0,0 @@ -import { parseISO } from "date-fns"; -import { FormattedMessage, useIntl } from "react-intl"; -import { Tooltip } from "react-tooltip"; -import useFormatHours from "../../hooks/useFormatHours"; -import { TIssue } from "../../types/redmine"; - -type PropTypes = { - issue: TIssue; -}; - -const IssueInfoTooltip = ({ issue }: PropTypes) => { - const { formatDate } = useIntl(); - const formatHours = useFormatHours(); - - return ( - -
-

- {issue.tracker.name} #{issue.id} -

{issue.subject}

-

- - - - - - - - - - - {issue.assigned_to && ( - - - - - )} - {issue.category && ( - - - - - )} - {issue.fixed_version && ( - - - - - )} - {issue.start_date && ( - - - - - )} - {issue.due_date && ( - - - - - )} - {issue.estimated_hours != null && ( - - - - - )} - {issue.spent_hours != null && ( - - - - - )} - -
- : - {issue.status.name}
- : - {issue.priority.name}
- : - {issue.assigned_to.name}
- : - {issue.category.name}
- : - {issue.fixed_version.name}
- : - {formatDate(parseISO(issue.start_date))}
- : - {formatDate(parseISO(issue.due_date))}
- : - {formatHours(issue.estimated_hours)}
- : - {formatHours(issue.spent_hours)}
-
-

- -

-
- ); -}; - -export default IssueInfoTooltip; diff --git a/src/components/issues/IssueTimer.tsx b/src/components/issues/IssueTimer.tsx deleted file mode 100644 index 53b47f78..00000000 --- a/src/components/issues/IssueTimer.tsx +++ /dev/null @@ -1,184 +0,0 @@ -import { faCircleCheck } from "@fortawesome/free-regular-svg-icons"; -import { faPause, faPlay, faStop } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import clsx from "clsx"; -import { Ref, useEffect, useImperativeHandle, useState } from "react"; -import { FormattedMessage, useIntl } from "react-intl"; -import { Tooltip } from "react-tooltip"; -import { Timer } from "../../hooks/useTimers"; -import { useSettings } from "../../provider/SettingsProvider"; -import { TIssue } from "../../types/redmine"; -import { formatTimer, roundTimeNearestInterval } from "../../utils/date"; -import Button from "../general/Button"; -import Modal from "../general/Modal"; -import EditTimer from "./EditTimer"; - -type PropTypes = { - issue: TIssue; - timer: Timer; - onDoneTimer?: (time: number) => void; - ref?: Ref; -}; - -export type TimerRef = { - isInEditMode: boolean; - editTimer: () => void; -}; - -const IssueTimer = ({ issue, timer, onDoneTimer, ref }: PropTypes) => { - const { formatMessage } = useIntl(); - const { settings } = useSettings(); - - const [editMode, setEditMode] = useState(false); - - const [currenTime, setCurrentTime] = useState(timer.getCurrentTime()); - - useEffect(() => { - setCurrentTime(timer.getCurrentTime()); - if (timer.active && timer.start) { - const timerInterval = setInterval(() => { - setCurrentTime(timer.getCurrentTime()); - }, 1000); - return () => clearInterval(timerInterval); - } - }, [timer]); - - useImperativeHandle( - ref, - () => - ({ - isInEditMode: editMode, - editTimer: () => { - setEditMode(true); - }, - }) satisfies TimerRef, - [editMode] - ); - - const [confirmResetModal, setConfirmResetModal] = useState(false); - - return ( - <> -
- {(editMode && ( - { - setEditMode(false); - timer.setTimer(time); - }} - onCancel={() => setEditMode(false)} - /> - )) || ( - <> - {settings.style.showTooltips && ( - - )} - 0 ? "text-yellow-500" : "text-gray-700 dark:text-gray-500", timer.active && "font-bold")} - onDoubleClick={() => setEditMode(true)} - data-tooltip-id={`tooltip-edit-timer-${issue.id}`} - > - {formatTimer(currenTime)} - - - )} - - {!timer.active ? ( - <> - {settings.style.showTooltips && ( - - - - )} - - - ) : ( - <> - {settings.style.showTooltips && ( - - - - )} - - - )} - - {settings.style.showTooltips && ( - - )} - setConfirmResetModal(true)} - data-tooltip-id={`tooltip-reset-timer-${issue.id}`} - tabIndex={-1} - /> - - {onDoneTimer && ( - <> - {settings.style.showTooltips && ( - - )} - onDoneTimer(settings.features.roundToNearestInterval ? roundTimeNearestInterval(currenTime, settings.features.roundingInterval) : currenTime)} - data-tooltip-id={`tooltip-done-timer-${issue.id}`} - tabIndex={-1} - /> - - )} -
- - {confirmResetModal && ( - setConfirmResetModal(false)}> -

- -

-
- - -
-
- )} - - ); -}; - -export default IssueTimer; diff --git a/src/components/issues/IssuesList.tsx b/src/components/issues/IssuesList.tsx deleted file mode 100644 index cd138aa1..00000000 --- a/src/components/issues/IssuesList.tsx +++ /dev/null @@ -1,131 +0,0 @@ -import { faMagnifyingGlass, faPlus } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import clsx from "clsx"; -import { Fragment, useState } from "react"; -import { FormattedMessage } from "react-intl"; -import useActiveRedmineTab from "../../hooks/useActiveRedmineTab"; -import useIssuePriorities from "../../hooks/useIssuePriorities"; -import useMyProjectRoles from "../../hooks/useMyProjectRoles"; -import useMyProjects from "../../hooks/useMyProjects"; -import useMyUser from "../../hooks/useMyUser"; -import useProjectVersions from "../../hooks/useProjectVersions"; -import useTimers from "../../hooks/useTimers"; -import { useSettings } from "../../provider/SettingsProvider"; -import { TIssue, TProject, TReference } from "../../types/redmine"; -import { getGroupedIssues, getSortedIssues } from "../../utils/issue"; -import CreateIssueModal from "./CreateIssueModal"; -import Issue from "./Issue"; -import VersionTooltip from "./VersionTooltip"; - -type PropTypes = { - issues: TIssue[]; - issuePriorities: ReturnType; - projectVersions?: ReturnType; - timers: ReturnType; - onSearchInProject?: (project: TReference) => void; -}; - -const IssuesList = ({ issues: rawIssues, issuePriorities, projectVersions, timers, onSearchInProject }: PropTypes) => { - const { settings } = useSettings(); - - const activeTab = useActiveRedmineTab(); - - const myUser = useMyUser(); - const projects = useMyProjects(); - const projectRoles = useMyProjectRoles([...new Set(rawIssues.map((i) => i.project.id))]); - const groupedIssues = getGroupedIssues({ - issues: getSortedIssues(rawIssues, settings.style.sortIssuesByPriority ? issuePriorities.data : [], timers.timers), - projectVersions: projectVersions?.data ?? {}, - timersData: timers.timers, - settings, - activeTabIssueId: activeTab?.data?.type === "issue" ? activeTab?.data?.id : undefined, - }); - - const [createIssue, setCreateIssue] = useState(undefined); - - return ( - <> - {groupedIssues.map(({ id, project: projectRef, versions, groups }) => { - const project: TProject | TReference | undefined = projects.data?.find((p) => p.id === projectRef?.id) ?? projectRef; - return ( - - {project && ( -
- - {project.name} - - -
- {projectRoles?.hasProjectPermission(project, "add_issues") && ( - - )} - {onSearchInProject && ( - - )} -
-
- )} - {groups.map(({ type, version, issues }) => ( - - {settings.style.groupIssuesByVersion && versions.length > 0 && ["version", "no-version"].includes(type) && ( - <> - {version && } -
- - {type === "version" && version && ( - - {version.name} - - )} - {type === "no-version" && } - -
- - )} - - {issues.map((issue) => { - const timer = timers.getTimer(issue.id); - - return ( - - ); - })} -
- ))} -
- ); - })} - {groupedIssues.length === 0 && ( -

- -

- )} - {createIssue !== undefined && setCreateIssue(undefined)} onSuccess={() => setCreateIssue(undefined)} />} - - ); -}; - -export default IssuesList; diff --git a/src/components/issues/IssuesListSkeleton.tsx b/src/components/issues/IssuesListSkeleton.tsx deleted file mode 100644 index 85dea050..00000000 --- a/src/components/issues/IssuesListSkeleton.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import clsx from "clsx"; -import { Fragment } from "react"; - -const IssuesListSkeleton = () => { - return ( - <> - {[...Array(Math.floor(Math.random() * 2 + 2)).keys()].map((i) => ( - -
- {[...Array(Math.floor(Math.random() * 5 + 1)).keys()].map((_, i) => { - return ( -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ); - })} - - ))} - - ); -}; - -export default IssuesListSkeleton; diff --git a/src/components/issues/Search.tsx b/src/components/issues/Search.tsx deleted file mode 100644 index 46360921..00000000 --- a/src/components/issues/Search.tsx +++ /dev/null @@ -1,120 +0,0 @@ -import { faChevronRight, faSearch, faX } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { ReactNode, Ref, useImperativeHandle, useRef, useState } from "react"; -import { FormattedMessage, useIntl } from "react-intl"; -import useDebounce from "../../hooks/useDebounce"; -import useHotKey from "../../hooks/useHotkey"; -import { useSettings } from "../../provider/SettingsProvider"; -import { TReference } from "../../types/redmine"; -import InputField from "../general/InputField"; - -export type SearchQuery = { - searching: boolean; - query: string; - debouncedQuery?: string; - inProject?: TReference; -}; - -const defaultSearchQuery: SearchQuery = { searching: false, query: "" }; - -type PropTypes = { - children: (state: { search: SearchQuery }) => ReactNode; - ref: Ref; -}; - -export type SearchRef = { - searchInProject: (project: TReference) => void; -}; - -const Search = ({ children, ref }: PropTypes) => { - const { formatMessage } = useIntl(); - const { settings } = useSettings(); - - const searchRef = useRef(null); - const [searching, setSearching] = useState(defaultSearchQuery.searching); - const [query, setQuery] = useState(defaultSearchQuery.query); - const debouncedQuery = useDebounce(query, 300); - const [inProject, setInProject] = useState(defaultSearchQuery.inProject); - const isSearching = searching || settings.style.displaySearchAlways; - - useImperativeHandle(ref, () => ({ - searchInProject(project: TReference) { - setInProject(project); - setSearching(true); - searchRef.current?.focus(); - searchRef.current?.select(); - }, - })); - - // hotkeys - useHotKey( - () => { - setSearching(true); - searchRef.current?.focus(); - searchRef.current?.select(); - }, - { ctrl: true, code: "KeyK" } - ); - useHotKey( - () => { - setSearching(true); - searchRef.current?.focus(); - searchRef.current?.select(); - }, - { ctrl: true, code: "KeyF" } - ); - useHotKey( - () => { - setSearching(false); - setQuery(""); - setInProject(undefined); - }, - { key: "Escape" }, - searching - ); - - return ( - <> - {isSearching && ( -
- } - type="search" - name="query" - placeholder={formatMessage({ id: "issues.search" })} - value={query} - onChange={(e) => setQuery(e.target.value)} - autoFocus - autoComplete="off" - /> - {inProject && ( -
- - {children}, - }} - /> -
- setInProject(undefined)} /> -
-
- )} -
- )} - {children({ - search: { - searching: isSearching, - query, - debouncedQuery, - inProject, - }, - })} - - ); -}; - -export default Search; diff --git a/src/components/issues/VersionTooltip.tsx b/src/components/issues/VersionTooltip.tsx deleted file mode 100644 index 45d2b6d3..00000000 --- a/src/components/issues/VersionTooltip.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { differenceInDays, parseISO, startOfDay } from "date-fns"; -import { FormattedMessage, useIntl } from "react-intl"; -import { Tooltip } from "react-tooltip"; -import { TVersion } from "../../types/redmine"; - -type PropTypes = { - version: TVersion; -}; - -const VersionTooltip = ({ version }: PropTypes) => { - const { formatDate, formatRelativeTime } = useIntl(); - - return ( - -
-

- {version.name} {version.due_date && <>({formatRelativeTime(differenceInDays(parseISO(version.due_date), startOfDay(new Date())), "days")})} - {version.description &&

{version.description}

} -

- - - - - - - {version.due_date && ( - - - - - )} - -
- : - {version.status}
- : - {formatDate(parseISO(version.due_date))}
-
-

- -

-
- ); -}; - -export default VersionTooltip; diff --git a/src/components/issues/fields/AssigneeField.tsx b/src/components/issues/fields/AssigneeField.tsx deleted file mode 100644 index 22071a2c..00000000 --- a/src/components/issues/fields/AssigneeField.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { ComponentProps, useMemo, useState } from "react"; -import { useIntl } from "react-intl"; -import useMyUser from "../../../hooks/useMyUser"; -import useProjectUsers from "../../../hooks/useProjectUsers"; -import { getGroupedUsers } from "../../../utils/user"; -import ReactSelectFormik from "../../general/ReactSelectFormik"; - -type Props = { - projectId: number; -}; - -const AssigneeField = ({ projectId, ...props }: ComponentProps & Props) => { - const { formatMessage } = useIntl(); - - const [loadUsers, setLoadUsers] = useState(false); - - const myUser = useMyUser(); - const users = useProjectUsers(projectId, { - enabled: loadUsers, - }); - const groupedUsers = useMemo(() => getGroupedUsers(users.data), [users.data]); - - return ( - formatMessage({ id: "general.no-options" })} - onFocus={() => setLoadUsers(true)} - options={ - loadUsers - ? groupedUsers.map(({ role, users }) => ({ - label: role.name, - options: users.map((user) => ({ - value: user.id, - label: user.id === myUser.data?.id ? `${user.name} <<${formatMessage({ id: "issues.issue.field.assignee.me" })}>>` : user.name, - })), - })) - : myUser.data - ? [ - { - value: myUser.data.id, - label: `${myUser.data.firstname} ${myUser.data.lastname} <<${formatMessage({ id: "issues.issue.field.assignee.me" })}>>`, - }, - ] - : [] - } - isLoading={users.isLoading} - /> - ); -}; - -export default AssigneeField; diff --git a/src/components/issues/fields/CategoryField.tsx b/src/components/issues/fields/CategoryField.tsx deleted file mode 100644 index 6f5a504e..00000000 --- a/src/components/issues/fields/CategoryField.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { ComponentProps } from "react"; -import { useIntl } from "react-intl"; -import useProject from "../../../hooks/useProject"; -import ReactSelectFormik from "../../general/ReactSelectFormik"; - -type Props = { - projectId: number; -}; - -const CategoryField = ({ projectId, ...props }: ComponentProps & Props) => { - const { formatMessage } = useIntl(); - - const project = useProject(projectId); - - if (project.data?.issue_categories?.length === 0) return null; - - return ( - formatMessage({ id: "general.no-options" })} - options={project.data?.issue_categories?.map((category) => ({ - label: category.name, - value: category.id, - }))} - isLoading={project.isLoading} - /> - ); -}; - -export default CategoryField; diff --git a/src/components/issues/fields/PriorityField.tsx b/src/components/issues/fields/PriorityField.tsx deleted file mode 100644 index 348ec6a1..00000000 --- a/src/components/issues/fields/PriorityField.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { ComponentProps } from "react"; -import { useIntl } from "react-intl"; -import useIssuePriorities from "../../../hooks/useIssuePriorities"; -import ReactSelectFormik from "../../general/ReactSelectFormik"; - -const PriorityField = (props: ComponentProps) => { - const { formatMessage } = useIntl(); - - const issuePriorities = useIssuePriorities(); - - return ( - formatMessage({ id: "general.no-options" })} - options={issuePriorities.data?.map((priority) => ({ - label: priority.name, - value: priority.id, - }))} - isLoading={issuePriorities.isLoading} - /> - ); -}; - -export default PriorityField; diff --git a/src/components/issues/fields/TimeEntryUsersField.tsx b/src/components/issues/fields/TimeEntryUsersField.tsx deleted file mode 100644 index d7bdd35d..00000000 --- a/src/components/issues/fields/TimeEntryUsersField.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { ComponentProps, useMemo, useState } from "react"; -import { useIntl } from "react-intl"; -import useMyUser from "../../../hooks/useMyUser"; -import useProjectUsers from "../../../hooks/useProjectUsers"; -import { getGroupedUsers } from "../../../utils/user"; -import ReactSelectFormik from "../../general/ReactSelectFormik"; - -type Props = { - projectId: number; -}; - -const TimeEntryUsersField = ({ projectId, ...props }: ComponentProps & Props) => { - const { formatMessage } = useIntl(); - - const [loadUsers, setLoadUsers] = useState(false); - - const myUser = useMyUser(); - const users = useProjectUsers(projectId, { - enabled: loadUsers, - }); - const groupedUsers = useMemo(() => getGroupedUsers(users.data), [users.data]); - - return ( - formatMessage({ id: "time.time-entry.field.user.no-options" })} - onFocus={() => setLoadUsers(true)} - options={ - loadUsers - ? groupedUsers.map(({ role, users }) => ({ - label: role.name, - options: users.map((user) => ({ - value: user.id, - label: user.id === myUser.data?.id ? `${user.name} <<${formatMessage({ id: "issues.issue.field.assignee.me" })}>>` : user.name, - })), - })) - : myUser.data - ? [ - { - value: myUser.data.id, - label: `${myUser.data.firstname} ${myUser.data.lastname} <<${formatMessage({ id: "issues.issue.field.assignee.me" })}>>`, - }, - ] - : [] - } - isLoading={users.isLoading} - /> - ); -}; - -export default TimeEntryUsersField; diff --git a/src/components/issues/fields/VersionField.tsx b/src/components/issues/fields/VersionField.tsx deleted file mode 100644 index d15a8fb1..00000000 --- a/src/components/issues/fields/VersionField.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { ComponentProps } from "react"; -import { useIntl } from "react-intl"; -import useProjectVersions from "../../../hooks/useProjectVersions"; -import ReactSelectFormik from "../../general/ReactSelectFormik"; - -type Props = { - projectId: number; -}; - -const VersionField = ({ projectId, ...props }: ComponentProps & Props) => { - const { formatMessage } = useIntl(); - - const projectVersions = useProjectVersions([projectId]); - - if (projectVersions.data[projectId]?.length === 0) return null; - - return ( - formatMessage({ id: "general.no-options" })} - options={projectVersions.data[projectId] - ?.filter((version) => version.status === "open") - .map((version) => ({ - label: version.name, - value: version.id, - }))} - isLoading={projectVersions.isLoading} - /> - ); -}; - -export default VersionField; diff --git a/src/components/time-entry/CreateTimeEntryModal.tsx b/src/components/time-entry/CreateTimeEntryModal.tsx new file mode 100644 index 00000000..a7d74cd8 --- /dev/null +++ b/src/components/time-entry/CreateTimeEntryModal.tsx @@ -0,0 +1,262 @@ +/* eslint-disable react/no-children-prop */ +import { useRedmineCurrentUser } from "@/api/redmine/hooks/useRedmineCurrentUser"; +import { useRedmineProjectTimeEntryActivities } from "@/api/redmine/hooks/useRedmineProjectTimeEntryActivities"; +import { redmineIssuesQueries } from "@/api/redmine/queries/issues"; +import { redmineTimeEntriesQueries } from "@/api/redmine/queries/timeEntries"; +import { usePersistentComments } from "@/hooks/usePersistentComments"; +import { Timer } from "@/hooks/useTimers"; +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { startOfDay } from "date-fns"; +import { useIntl } from "react-intl"; +import { z } from "zod"; +import { TCreateTimeEntry, TIssue, TUpdateIssue } from "../../api/redmine/types"; +import { useAppForm } from "../../hooks/useAppForm"; +import { usePermissions } from "../../provider/PermissionsProvider"; +import { useRedmineApi } from "../../provider/RedmineApiProvider"; +import { useSettings } from "../../provider/SettingsProvider"; +import ActivityField from "../issue/form/fields/ActivityField"; +import { DoneSliderField } from "../issue/form/fields/DoneSliderField"; +import { IssueTitle } from "../issue/IssueTitle"; +import SpentVsEstimatedTime from "../issue/SpentVsEstimatedTime"; +import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "../ui/dialog"; +import { Form, FormFieldset, FormGrid } from "../ui/form"; +import UserField from "./form/fields/UserField"; +import TimeEntryPreview from "./TimeEntryPreview"; + +type PropTypes = { + timer: Timer; + issue: TIssue; + initialValues: Partial; + onClose: () => void; + onSuccess: () => void; +}; + +const createTimeEntryFormSchema = ({ formatMessage }: { formatMessage?: ReturnType["formatMessage"] }) => + z.object({ + issue_id: z.int(), + user_id: z.array(z.int()), + hours: z + .number(formatMessage?.({ id: "time.time-entry.field.hours.validation.required" })) + .min(0.01, formatMessage?.({ id: "time.time-entry.field.hours.validation.greater-than-zero" })) + .max(24, formatMessage?.({ id: "time.time-entry.field.hours.validation.less-than-24" })), + spent_on: z.date(formatMessage?.({ id: "time.time-entry.field.spent-on.validation.required" })).max(new Date(), formatMessage?.({ id: "time.time-entry.field.spent-on.validation.in-future" })), + comments: z.string().nullable(), + activity_id: z.int(formatMessage?.({ id: "time.time-entry.field.activity.validation.required" })), + issue: z.object({ + done_ratio: z.number().min(0).max(100), + _add_notes: z.boolean(), + notes: z.string().nullable(), + }), + }); + +type TCreateTimeEntryForm = z.infer>; + +const CreateTimeEntryModal = ({ timer, issue, initialValues, onClose, onSuccess }: PropTypes) => { + const { formatMessage } = useIntl(); + const { settings } = useSettings(); + const redmineApi = useRedmineApi(); + const queryClient = useQueryClient(); + + const { data: me } = useRedmineCurrentUser(); + const timeEntryActivities = useRedmineProjectTimeEntryActivities(issue.project.id); + + const { hasProjectPermission } = usePermissions(); + + const createTimeEntryMutation = useMutation({ + mutationFn: (entry: TCreateTimeEntry) => redmineApi.createTimeEntry(entry), + onSuccess: (_, entry) => { + // if entry created for me => invalidate query + if (!entry.user_id || entry.user_id === me?.id) { + queryClient.invalidateQueries(redmineTimeEntriesQueries); + } + }, + meta: { + successMessage: formatMessage({ id: "issues.modal.add-spent-time.success" }), + }, + }); + + const updateIssueMutation = useMutation({ + mutationFn: (data: TUpdateIssue) => redmineApi.updateIssue(issue.id, data), + onSuccess: () => { + queryClient.invalidateQueries(redmineIssuesQueries); + }, + }); + + const persistentComments = usePersistentComments({ + identifier: timer.id, + enabled: settings.features.persistentComments, + }); + + const form = useAppForm({ + defaultValues: { + issue_id: issue.id, + user_id: me?.id ? [me.id] : [], + hours: 0, + spent_on: new Date(), + comments: null, + activity_id: timeEntryActivities.defaultActivity?.id, + issue: { + done_ratio: issue.done_ratio, + _add_notes: false, + notes: null, + }, + ...initialValues, + ...(persistentComments.isEnabled && + persistentComments.isPersisted && { + comments: persistentComments.comment, + }), + } satisfies Partial as TCreateTimeEntryForm, + validators: { + onChange: createTimeEntryFormSchema({ formatMessage }), + }, + onSubmit: async ({ value: originalValue }) => { + const { issue: updateIssue, ...value } = { ...originalValue }; + + // Update issue done_ratio and notes + const updatedDoneRatio = updateIssue.done_ratio !== issue.done_ratio ? updateIssue.done_ratio : undefined; + const addNotes = updateIssue._add_notes && updateIssue.notes ? updateIssue.notes : undefined; + if (updatedDoneRatio !== undefined || addNotes) { + await updateIssueMutation.mutateAsync({ + done_ratio: updatedDoneRatio, + notes: addNotes, + }); + } + + // Create time entry + if (Array.isArray(value.user_id) && value.user_id.length > 0) { + // create for multiple users + for (const userId of value.user_id) { + try { + await createTimeEntryMutation.mutateAsync({ ...value, user_id: userId }); + } catch (_) { + continue; // continue on other users + } + } + } else { + // create for me + await createTimeEntryMutation.mutateAsync({ ...value, user_id: undefined }); + } + + if (!createTimeEntryMutation.isError) { + if (persistentComments.isEnabled && persistentComments.isPersisted) { + persistentComments.removeComment(); + } + + onSuccess(); + } + }, + }); + + return ( + <> + { + const comment = form.state.values.comments; + if (persistentComments.isEnabled && ((comment && comment != initialValues.comments) || persistentComments.isPersisted)) { + persistentComments.saveComment(comment ?? undefined); + } + + onClose(); + }} + > + +
+ + {formatMessage({ id: "issues.modal.add-spent-time.title" })} + + + + } /> + + state.values.hours} children={(hours) => } /> + + ({ + hours: state.values.hours, + spent_on: state.values.spent_on, + })} + children={({ hours, spent_on }) => } + /> + + + + ( + + )} + /> + + ( + + )} + /> + + {hasProjectPermission(issue.project.id, "log_time_for_other_users") && } />} + + ( + 0} + /> + )} + /> + + } /> + + + + {hasProjectPermission(issue.project.id, "add_issue_notes") && ( + state.values.issue._add_notes} + children={(add_notes) => + !add_notes ? ( + } /> + ) : ( + + + } /> + } /> + + + ) + } + /> + )} + + + + + + + +
+
+ + ); +}; + +export default CreateTimeEntryModal; diff --git a/src/components/time-entry/EditTimeEntryModal.tsx b/src/components/time-entry/EditTimeEntryModal.tsx new file mode 100644 index 00000000..c7ead0ef --- /dev/null +++ b/src/components/time-entry/EditTimeEntryModal.tsx @@ -0,0 +1,149 @@ +/* eslint-disable react/no-children-prop */ +import { useRedmineIssue } from "@/api/redmine/hooks/useRedmineIssue"; +import { redmineTimeEntriesQueries } from "@/api/redmine/queries/timeEntries"; +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { parseISO } from "date-fns"; +import { useIntl } from "react-intl"; +import { z } from "zod"; +import { TTimeEntry, TUpdateTimeEntry } from "../../api/redmine/types"; +import { useAppForm } from "../../hooks/useAppForm"; +import { useRedmineApi } from "../../provider/RedmineApiProvider"; +import { useSettings } from "../../provider/SettingsProvider"; +import ActivityField from "../issue/form/fields/ActivityField"; +import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "../ui/dialog"; +import { Field, FieldLabel } from "../ui/field"; +import { Form, FormGrid } from "../ui/form"; +import { Input } from "../ui/input"; + +type PropTypes = { + entry: TTimeEntry; + onClose: () => void; + onSuccess: () => void; +}; + +const editTimeEntryFormSchema = ({ formatMessage }: { formatMessage: ReturnType["formatMessage"] }) => + z.object({ + hours: z + .number(formatMessage({ id: "time.time-entry.field.hours.validation.required" })) + .min(0.01, formatMessage({ id: "time.time-entry.field.hours.validation.greater-than-zero" })) + .max(24, formatMessage({ id: "time.time-entry.field.hours.validation.less-than-24" })), + spent_on: z.date(formatMessage({ id: "time.time-entry.field.spent-on.validation.required" })).max(new Date(), formatMessage({ id: "time.time-entry.field.spent-on.validation.in-future" })), + comments: z.string().nullable(), + activity_id: z.int(formatMessage({ id: "time.time-entry.field.activity.validation.required" })), + }); + +type TEditTimeEntryForm = z.infer>; + +const EditTimeEntryModal = ({ entry, onClose, onSuccess }: PropTypes) => { + const { formatMessage } = useIntl(); + const { settings } = useSettings(); + const redmineApi = useRedmineApi(); + const queryClient = useQueryClient(); + + const issueQuery = useRedmineIssue(entry.issue?.id ?? 0, { + enabled: !!entry.issue, + }); + + const updateTimeEntryMutation = useMutation({ + mutationFn: (data: TUpdateTimeEntry) => redmineApi.updateTimeEntry(entry.id, data), + onSuccess: () => { + queryClient.invalidateQueries(redmineTimeEntriesQueries); + }, + meta: { + successMessage: formatMessage({ id: "time.modal.edit-time-entry.success" }), + }, + }); + + const form = useAppForm({ + defaultValues: { + hours: entry.hours, + spent_on: parseISO(entry.spent_on), + comments: entry.comments, + activity_id: entry.activity.id, + } satisfies TEditTimeEntryForm as TEditTimeEntryForm, + validators: { + onChange: editTimeEntryFormSchema({ formatMessage }), + }, + onSubmit: async ({ value }) => { + await updateTimeEntryMutation.mutateAsync(value); + if (!updateTimeEntryMutation.isError) { + onSuccess(); + } + }, + }); + + return ( + + +
+ + {formatMessage({ id: "time.modal.edit-time-entry.title" })} + + + + {formatMessage({ id: "time.time-entry.field.project" })} + + + + {issueQuery.data && ( + + {formatMessage({ id: "time.time-entry.field.issue" })} + + + )} + + ( + + )} + /> + + ( + + )} + /> + + } + /> + + } /> + + + + + + +
+
+
+ ); +}; + +export default EditTimeEntryModal; diff --git a/src/components/time-entry/TimeEntry.tsx b/src/components/time-entry/TimeEntry.tsx new file mode 100644 index 00000000..a8f4d83a --- /dev/null +++ b/src/components/time-entry/TimeEntry.tsx @@ -0,0 +1,75 @@ +import { TimeEntryContextMenu } from "@/components/time-entry/TimeEntryContextMenu"; +import { Fragment } from "react"; +import { TTimeEntry } from "../../api/redmine/types"; +import useFormatHours from "../../hooks/useFormatHours"; +import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"; +import TimeEntryTooltip from "./TimeEntryTooltip"; + +type PropTypes = { + entries: TTimeEntry[]; + previewHours?: number; + maxDayHours?: number; + withContextMenu?: boolean; +}; + +const TimeEntry = ({ entries, previewHours, maxDayHours = 24, withContextMenu = false }: PropTypes) => { + const formatHours = useFormatHours(); + + const sumHours = entries.reduce((sum, entry) => sum + entry.hours, 0); + + return ( +
+ {entries.map((entry) => { + const entryElement = ( + +
+ + ); + return ( + + {withContextMenu ? ( + +
{entryElement}
+
+ ) : ( + entryElement + )} +
+ ); + })} + {!!previewHours && ( + + + } + /> + +

{formatHours(previewHours)}

+
+
+ )} +
+
+ ); +}; + +export default TimeEntry; diff --git a/src/components/time-entry/TimeEntryContextMenu.tsx b/src/components/time-entry/TimeEntryContextMenu.tsx new file mode 100644 index 00000000..da02acda --- /dev/null +++ b/src/components/time-entry/TimeEntryContextMenu.tsx @@ -0,0 +1,53 @@ +import { usePermissions } from "@/provider/PermissionsProvider"; +import { PencilIcon, SquareArrowOutUpRightIcon } from "lucide-react"; +import { ReactElement, useState } from "react"; +import { useIntl } from "react-intl"; +import { TTimeEntry } from "../../api/redmine/types"; +import { useSettings } from "../../provider/SettingsProvider"; +import { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuSeparator, ContextMenuTrigger } from "../ui/context-menu"; +import EditTimeEntryModal from "./EditTimeEntryModal"; + +type PropTypes = { + entry: TTimeEntry; +}; + +export const TimeEntryContextMenu = ({ children, ...props }: PropTypes & { children: ReactElement }) => { + const [edit, setEdit] = useState(false); + return ( + <> + + + + setEdit(true)} /> + + + {edit && setEdit(false)} onSuccess={() => setEdit(false)} />} + + ); +}; + +const TimeEntryContextMenuItems = ({ entry, onEdit }: PropTypes & { onEdit: () => void }) => { + const { formatMessage } = useIntl(); + const { settings } = useSettings(); + + const { hasProjectPermission } = usePermissions(); + const canEdit = hasProjectPermission(entry.project.id, "edit_own_time_entries"); + + return ( + <> + { + window.open(`${settings.redmineURL}/time_entries/${entry.id}/edit`, "_blank"); + }} + > + + {formatMessage({ id: "time.time-entry.context-menu.open-in-redmine" })} + + + + + {formatMessage({ id: "time.time-entry.context-menu.edit" })} + + + ); +}; diff --git a/src/components/time-entry/TimeEntryPreview.tsx b/src/components/time-entry/TimeEntryPreview.tsx new file mode 100644 index 00000000..59ab2d09 --- /dev/null +++ b/src/components/time-entry/TimeEntryPreview.tsx @@ -0,0 +1,35 @@ +import { useRedmineTimeEntries } from "@/api/redmine/hooks/useRedmineTimeEntries"; +import clsx from "clsx"; +import useFormatHours from "../../hooks/useFormatHours"; +import { roundHours } from "../../utils/date"; +import TimeEntry from "./TimeEntry"; + +type PropTypes = { + date: Date; + previewHours: number; + className?: string; +}; + +const TimeEntryPreview = ({ date, previewHours, className }: PropTypes) => { + const formatHours = useFormatHours(); + + const myTimeEntriesQuery = useRedmineTimeEntries({ + userId: "me", + from: date, + to: date, + }); + const timeEntries = myTimeEntriesQuery.data ?? []; + + const sumHours = timeEntries.reduce((sum, entry) => sum + entry.hours, 0) + previewHours; + + return ( +
+

{formatHours(roundHours(sumHours))}

+
+ 12 ? sumHours : 12} /> +
+
+ ); +}; + +export default TimeEntryPreview; diff --git a/src/components/time-entry/TimeEntryTooltip.tsx b/src/components/time-entry/TimeEntryTooltip.tsx new file mode 100644 index 00000000..3ff1f9f0 --- /dev/null +++ b/src/components/time-entry/TimeEntryTooltip.tsx @@ -0,0 +1,61 @@ +import { ReactElement } from "react"; +import { useIntl } from "react-intl"; +import { TTimeEntry } from "../../api/redmine/types"; +import useFormatHours from "../../hooks/useFormatHours"; +import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"; + +type PropTypes = { + entry: TTimeEntry; + children: ReactElement; +}; + +const TimeEntryTooltip = ({ entry, children }: PropTypes) => { + const { formatMessage } = useIntl(); + const formatHours = useFormatHours(); + + return ( + + + +

{formatHours(entry.hours)}

+ {entry.comments &&

{entry.comments}

} + + + + + + + {entry.issue && ( + + + + + )} + + + + + + + + + {entry.custom_fields?.map((field) => { + if (!field.value) return null; + if (Array.isArray(field.value) && field.value.length === 0) return null; + + const value = Array.isArray(field.value) ? field.value.join(", ") : String(field.value); + return ( + + + + + ); + })} + +
{formatMessage({ id: "time.time-entry.field.project" })}:{entry.project.name}
{formatMessage({ id: "time.time-entry.field.issue" })}:#{entry.issue.id}
{formatMessage({ id: "time.time-entry.field.activity" })}:{entry.activity.name}
{formatMessage({ id: "time.time-entry.field.hours" })}:{formatHours(entry.hours)}
{field.name}:{value}
+
+
+ ); +}; + +export default TimeEntryTooltip; diff --git a/src/components/time-entry/TimeEntryWeekOverview.tsx b/src/components/time-entry/TimeEntryWeekOverview.tsx new file mode 100644 index 00000000..761dc7be --- /dev/null +++ b/src/components/time-entry/TimeEntryWeekOverview.tsx @@ -0,0 +1,102 @@ +import { Skeleton } from "@/components/ui/skeleton"; +import { addDays, format, formatISO, isFuture, isWeekend } from "date-fns"; +import { ClockIcon } from "lucide-react"; +import { useIntl } from "react-intl"; +import { TTimeEntry } from "../../api/redmine/types"; +import useFormatHours from "../../hooks/useFormatHours"; +import { roundHours } from "../../utils/date"; +import { Badge } from "../ui/badge"; +import { Card, CardAction, CardContent, CardHeader, CardTitle } from "../ui/card"; +import TimeEntry from "./TimeEntry"; + +type PropTypes = { + startOfWeek: Date; + groupedTimeEntries: Map; + maxDayHours: number; +}; + +export type GroupedTimeEntries = { + date: Date; + entries: TTimeEntry[]; + hours: number; +}; + +export const TimeEntryWeekOverview = ({ startOfWeek, groupedTimeEntries, maxDayHours }: PropTypes) => { + const { formatDate } = useIntl(); + const formatHours = useFormatHours(); + + const days = Array(7) + .fill(startOfWeek) + .map((startOfWeek: Date, i) => { + const date = addDays(startOfWeek, i); + return ( + groupedTimeEntries.get(formatISO(date, { representation: "date" })) ?? + ({ + date, + entries: [], + hours: 0, + } satisfies GroupedTimeEntries) + ); + }); + + const summedHours = days.reduce((sum, day) => sum + day.hours, 0); + + return ( + + + + {formatDate(days[0]!.date)} – {formatDate(days[6]!.date)} + + + + + {formatHours(roundHours(summedHours))} + + + + + {days.toReversed().map(({ date, entries, hours }) => { + if (isFuture(date)) return; + if (isWeekend(date) && entries.length === 0) return; + return ( +
+ {format(date, "EEE")} + {formatHours(roundHours(hours))} +
+ +
+
+ ); + })} +
+
+ ); +}; + +export const TimeEntryWeekOverviewSkeleton = () => { + return ( + + + + + + + + + + + {[...Array(5).keys()].map((e) => ( +
+ + + + +
+ +
+
+ ))} +
+
+ ); +}; diff --git a/src/components/time-entry/form/fields/UserField.tsx b/src/components/time-entry/form/fields/UserField.tsx new file mode 100644 index 00000000..53b5fdff --- /dev/null +++ b/src/components/time-entry/form/fields/UserField.tsx @@ -0,0 +1,53 @@ +import { useRedmineCurrentUser } from "@/api/redmine/hooks/useRedmineCurrentUser"; +import { useRedmineProjectMembers } from "@/api/redmine/hooks/useRedmineProjectMembers"; +import { ComboboxField } from "@/components/form/ComboboxField"; +import { groupMembers } from "@/utils/groupMembers"; +import { ComponentProps, useMemo, useState } from "react"; +import { useIntl } from "react-intl"; + +type Props = { + projectId: number; +}; + +const UserField = ({ projectId, ...props }: Omit, "items" | "isLoading"> & Props) => { + const { formatMessage } = useIntl(); + + const [fetchMembers, setFetchMembers] = useState(false); + + const { data: me } = useRedmineCurrentUser(); + const members = useRedmineProjectMembers(projectId, { + enabled: fetchMembers, + }); + const groupedMembers = useMemo(() => groupMembers(members.members), [members.members]); + + return ( + open && setFetchMembers(true)} + items={ + fetchMembers + ? groupedMembers.map(({ role, users }) => ({ + label: role.name, + items: users.map((user) => ({ + value: user.id, + label: user.id === me?.id ? `${user.name} <<${formatMessage({ id: "issues.issue.field.assignee.me" })}>>` : user.name, + })), + })) + : me + ? [ + { + value: me.id, + label: `${me.firstname} ${me.lastname} <<${formatMessage({ id: "issues.issue.field.assignee.me" })}>>`, + }, + ] + : [] + } + isLoading={fetchMembers && members.isPending} + /> + ); +}; + +export default UserField; diff --git a/src/components/time/EditTimeEntryModal.tsx b/src/components/time/EditTimeEntryModal.tsx deleted file mode 100644 index 6dec278b..00000000 --- a/src/components/time/EditTimeEntryModal.tsx +++ /dev/null @@ -1,227 +0,0 @@ -import { useMutation, useQueryClient } from "@tanstack/react-query"; -import { AxiosError, isAxiosError } from "axios"; -import { parseISO } from "date-fns"; -import { FastField, Form, Formik, FormikProps } from "formik"; -import { useRef } from "react"; -import { FormattedMessage, useIntl } from "react-intl"; -import * as Yup from "yup"; -import useIssue from "../../hooks/useIssue"; -import useTimeEntryActivities from "../../hooks/useTimeEntryActivities"; -import { useRedmineApi } from "../../provider/RedmineApiProvider"; -import { useSettings } from "../../provider/SettingsProvider"; -import { TRedmineError, TTimeEntry, TUpdateTimeEntry } from "../../types/redmine"; -import { clsxm } from "../../utils/clsxm"; -import { formatHoursUsually } from "../../utils/date"; -import Button from "../general/Button"; -import DateField from "../general/DateField"; -import InputField from "../general/InputField"; -import LoadingSpinner from "../general/LoadingSpinner"; -import Modal from "../general/Modal"; -import ReactSelectFormik, { shouldUpdate } from "../general/ReactSelectFormik"; -import TimeField from "../general/TimeField"; -import Toast from "../general/Toast"; - -type PropTypes = { - entry: TTimeEntry; - onClose: () => void; - onSuccess: () => void; -}; - -type TUpdateTimeEntryForm = Required>; - -const EditTimeEntryModal = ({ entry, onClose, onSuccess }: PropTypes) => { - const { formatMessage } = useIntl(); - const { settings } = useSettings(); - const redmineApi = useRedmineApi(); - const queryClient = useQueryClient(); - - const formik = useRef>(null); - - const issue = useIssue(entry.issue?.id ?? 0, { - enabled: !!entry.issue, - }); - const timeEntryActivities = useTimeEntryActivities(entry.project.id); - - const updateTimeEntryMutation = useMutation({ - mutationFn: (data: TUpdateTimeEntry) => redmineApi.updateTimeEntry(entry.id, data), - onSuccess: () => { - queryClient.invalidateQueries({ - queryKey: ["timeEntries"], - }); - }, - }); - - return ( - <> - - - innerRef={formik} - initialValues={ - { - hours: entry.hours, - spent_on: parseISO(entry.spent_on), - comments: entry.comments, - activity_id: entry.activity.id, - } satisfies TUpdateTimeEntryForm - } - validationSchema={Yup.object({ - hours: Yup.number() - .required(formatMessage({ id: "time.time-entry.field.hours.validation.required" })) - .min(0.01, formatMessage({ id: "time.time-entry.field.hours.validation.greater-than-zero" })) - .max(24, formatMessage({ id: "time.time-entry.field.hours.validation.less-than-24" })), - spent_on: Yup.date() - .required(formatMessage({ id: "time.time-entry.field.spent-on.validation.required" })) - .max(new Date(), formatMessage({ id: "time.time-entry.field.spent-on.validation.in-future" })), - comments: Yup.string(), - activity_id: Yup.number().required(formatMessage({ id: "time.time-entry.field.activity.validation.required" })), - })} - onSubmit={async (values, { setSubmitting }) => { - await updateTimeEntryMutation.mutateAsync(values); - setSubmitting(false); - if (!updateTimeEntryMutation.isError) { - onSuccess(); - } - }} - > - {({ isSubmitting, touched, errors, values }) => ( -
-
- - - {issue.data && ( - - )} - -
- {settings.style.timeFormat === "decimal" ? ( - = 0 && values.hours <= 24 - ? formatMessage( - { id: "format.hours" }, - { - hours: formatHoursUsually(values.hours), - } - ) - : undefined - } - autoComplete="off" - className="col-span-3" - /> - ) : ( - - )} - - -
- - - - formatMessage({ id: "general.no-options" })} - error={touched.activity_id && errors.activity_id} - required - as={ReactSelectFormik} - size="sm" - options={timeEntryActivities.data?.map((activity) => ({ - label: activity.name, - value: activity.id, - }))} - isLoading={timeEntryActivities.isLoading} - shouldUpdate={shouldUpdate} - /> - - -
-
- )} - -
- {updateTimeEntryMutation.isError && ( - ).response?.data?.errors?.join(", ") ?? (updateTimeEntryMutation.error as AxiosError).message) - : (updateTimeEntryMutation.error as Error).message - } - /> - )} - - ); -}; - -export default EditTimeEntryModal; diff --git a/src/components/time/TimeEntry.tsx b/src/components/time/TimeEntry.tsx deleted file mode 100644 index 97263c5f..00000000 --- a/src/components/time/TimeEntry.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import { Fragment } from "react"; -import { Tooltip } from "react-tooltip"; -import useFormatHours from "../../hooks/useFormatHours"; -import useMyProjectRoles from "../../hooks/useMyProjectRoles"; -import { TTimeEntry } from "../../types/redmine"; -import TimeEntryContextMenu from "./TimeEntryContextMenu"; -import TimeEntryTooltip from "./TimeEntryTooltip"; - -type PropTypes = { - entries: TTimeEntry[]; - previewHours?: number; - maxHours?: number; - withContextMenu?: boolean; -}; - -const TimeEntry = ({ entries, previewHours, maxHours = 24, withContextMenu = false }: PropTypes) => { - const formatHours = useFormatHours(); - - const sumHours = entries.reduce((sum, entry) => sum + entry.hours, 0); - - const projectRoles = useMyProjectRoles([...new Set(entries.map((e) => e.project.id))]); - - return ( -
- {entries.map((entry) => ( - - - {withContextMenu ? ( - - ) : ( -
- )} - - ))} - {(previewHours && ( - <> - -

{formatHours(previewHours)}

-
-
- - )) || - undefined} -
-
- ); -}; - -export default TimeEntry; diff --git a/src/components/time/TimeEntryContextMenu.tsx b/src/components/time/TimeEntryContextMenu.tsx deleted file mode 100644 index 8eaad3fa..00000000 --- a/src/components/time/TimeEntryContextMenu.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import { faArrowUpRightFromSquare, faPen } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { ComponentProps, useState } from "react"; -import { useIntl } from "react-intl"; -import useMyProjectRoles from "../../hooks/useMyProjectRoles"; -import { useSettings } from "../../provider/SettingsProvider"; -import { TTimeEntry } from "../../types/redmine"; -import ContextMenu from "../general/ContextMenu"; -import EditTimeEntryModal from "./EditTimeEntryModal"; - -type PropTypes = { - entry: TTimeEntry; - projectRoles: ReturnType; -} & Omit, "menu">; - -function TimeEntryContextMenu({ entry, projectRoles, children, ...props }: PropTypes) { - const { formatMessage } = useIntl(); - - const { settings } = useSettings(); - - const [edit, setEdit] = useState(false); - - return ( - <> - , - onClick: () => { - window.open(`${settings.redmineURL}/time_entries/${entry.id}/edit`, "_blank"); - }, - }, - ], - [ - { - name: formatMessage({ id: "time.time-entry.context-menu.edit" }), - icon: , - disabled: !projectRoles.hasProjectPermission(entry.project, "edit_own_time_entries"), - onClick: () => setEdit(true), - }, - ], - ]} - > - {children} - - {edit && setEdit(false)} onSuccess={() => setEdit(false)} />} - - ); -} - -export default TimeEntryContextMenu; diff --git a/src/components/time/TimeEntryList.tsx b/src/components/time/TimeEntryList.tsx deleted file mode 100644 index 271cbbb8..00000000 --- a/src/components/time/TimeEntryList.tsx +++ /dev/null @@ -1,97 +0,0 @@ -import { addDays, format, isFuture, isMonday, isWeekend, parseISO, previousMonday, startOfDay, subWeeks } from "date-fns"; -import { useIntl } from "react-intl"; -import useFormatHours from "../../hooks/useFormatHours"; -import { TTimeEntry } from "../../types/redmine"; -import { roundHours } from "../../utils/date"; -import TimeEntry from "./TimeEntry"; - -type PropTypes = { - entries: TTimeEntry[]; -}; - -type GroupedEntries = { - date: Date; - hours: number; - entries: TTimeEntry[]; -}; - -const TimeEntryList = ({ entries }: PropTypes) => { - const { formatDate } = useIntl(); - const formatHours = useFormatHours(); - - const groupedEntries = Object.values( - entries.reduce((result: Record, entry) => { - if (!(entry.spent_on in result)) { - result[entry.spent_on] = { - date: parseISO(entry.spent_on), - hours: 0, - entries: [], - }; - } - result[entry.spent_on].entries.push(entry); - return result; - }, {}) - ).map((group) => { - group.entries.sort((a, b) => b.hours - a.hours); - group.hours = group.entries.reduce((sum, entry) => sum + entry.hours, 0); - return group; - }); - - const maxHours = Math.max(...groupedEntries.map(({ hours }) => hours)); - - const today = startOfDay(new Date()); - const monday = isMonday(today) ? today : previousMonday(today); - - return ( - <> - {Array(2) - .fill(monday) - .map((d, i) => subWeeks(d, i)) - .map((monday, i) => { - const days = Array(7) - .fill(monday) - .map((d, i) => addDays(d, 6 - i)); - const summedHours = groupedEntries.filter((entries) => days.find((d) => d.getTime() === entries.date.getTime())).reduce((sum, entry) => sum + entry.hours, 0); - return ( -
-
-

- {formatDate(monday)} - {formatDate(addDays(monday, 6))} -

- - - {formatHours(roundHours(summedHours))} - -
- {days.map((d, i) => { - if (isFuture(d)) return; - const { - date, - hours, - entries: groupEntries, - } = groupedEntries.find((entries) => entries.date.getTime() === d.getTime()) ?? { - date: d, - hours: 0, - entries: [], - }; - if (isWeekend(date) && hours === 0) return; - return ( -
-

{format(date, "EEE")}

-

{formatHours(roundHours(hours))}

-
- 0 ? maxHours : undefined} withContextMenu /> -
-
- ); - })} -
- ); - })} - - ); -}; - -export default TimeEntryList; diff --git a/src/components/time/TimeEntryListSkeleton.tsx b/src/components/time/TimeEntryListSkeleton.tsx deleted file mode 100644 index 0ea5fca6..00000000 --- a/src/components/time/TimeEntryListSkeleton.tsx +++ /dev/null @@ -1,39 +0,0 @@ -const TimeEntryListSkeleton = () => { - return ( - <> - {[...Array(2).keys()].map((i) => { - return ( -
-
-

- -
- {[...Array(5).keys()].map((i) => { - return ( -
-

-

-
-
- {[...Array(Math.floor(Math.random() * 4 + 1)).keys()].map((i) => ( -
- ))} -
-
-
- ); - })} -
- ); - })} - - ); -}; - -export default TimeEntryListSkeleton; diff --git a/src/components/time/TimeEntryPreview.tsx b/src/components/time/TimeEntryPreview.tsx deleted file mode 100644 index 0316df0d..00000000 --- a/src/components/time/TimeEntryPreview.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import useFormatHours from "../../hooks/useFormatHours"; -import useMyTimeEntries from "../../hooks/useMyTimeEntries"; -import { roundHours } from "../../utils/date"; -import TimeEntry from "./TimeEntry"; - -type PropTypes = { - date: Date; - previewHours: number; -}; - -const TimeEntryPreview = ({ date, previewHours }: PropTypes) => { - const formatHours = useFormatHours(); - - const myTimeEntriesQuery = useMyTimeEntries(date, date); - - const sumHours = myTimeEntriesQuery.data.reduce((sum, entry) => sum + entry.hours, 0) + previewHours; - - return ( -
-

{formatHours(roundHours(sumHours))}

-
- 12 ? sumHours : 12} /> -
-
- ); -}; - -export default TimeEntryPreview; diff --git a/src/components/time/TimeEntryTooltip.tsx b/src/components/time/TimeEntryTooltip.tsx deleted file mode 100644 index 3e59cedd..00000000 --- a/src/components/time/TimeEntryTooltip.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { FormattedMessage } from "react-intl"; -import { Tooltip } from "react-tooltip"; -import useFormatHours from "../../hooks/useFormatHours"; -import { TTimeEntry } from "../../types/redmine"; - -type PropTypes = { - entry: TTimeEntry; -}; - -const TimeEntryTooltip = ({ entry }: PropTypes) => { - const formatHours = useFormatHours(); - - return ( - -
-

- {formatHours(entry.hours)} - {entry.comments &&

{entry.comments}

} -

- - - - - - - {entry.issue && ( - - - - - )} - - - - - - - - - -
- : - {entry.project.name}
- : - #{entry.issue.id}
- : - {entry.activity.name}
- : - {formatHours(entry.hours)}
-
-
- ); -}; - -export default TimeEntryTooltip; diff --git a/src/components/timer/CurrentIssueTimer.tsx b/src/components/timer/CurrentIssueTimer.tsx new file mode 100644 index 00000000..81781164 --- /dev/null +++ b/src/components/timer/CurrentIssueTimer.tsx @@ -0,0 +1,45 @@ +import { useRedmineIssue } from "@/api/redmine/hooks/useRedmineIssue"; +import { usePermissions } from "@/provider/PermissionsProvider"; +import useRedmineUrl from "../../hooks/useRedmineUrl"; +import useTimers, { calculateTimerTotalElapsedTime } from "../../hooks/useTimers"; +import { TimerComponents } from "./timer"; + +type PropTypes = { + issueId: number; +}; + +const CurrentIssueTimerInner = ({ issueId }: PropTypes) => { + const timers = useTimers(); + const { data: issue } = useRedmineIssue(issueId); + const { hasProjectPermission } = usePermissions(); + + if (!issue) return; + + const canLogTime = hasProjectPermission(issue.project.id, "log_time"); + + const issueTimers = timers.getTimersByIssue(issue.id); + const primaryTimer = issueTimers[0]!; + + if (!canLogTime && calculateTimerTotalElapsedTime(primaryTimer) === 0) return; + + return ( + + + + + + + + + + ); +}; + +export const CurrentIssueTimer = () => { + const currentUrl = useRedmineUrl(); + const issueId = currentUrl?.data?.type === "issue" ? currentUrl?.data?.id : undefined; + + if (!issueId) return; + + return ; +}; diff --git a/src/components/timer/ProjectTimersGroup.tsx b/src/components/timer/ProjectTimersGroup.tsx new file mode 100644 index 00000000..d96fc74b --- /dev/null +++ b/src/components/timer/ProjectTimersGroup.tsx @@ -0,0 +1,100 @@ +import { useRedmineIssuePriorities } from "@/api/redmine/hooks/useRedmineIssuePriorities"; +import { ToggleableCard } from "@/components/general/ToggleableCard"; +import { IssueTitle, IssueTitleSkeleton } from "@/components/issue/IssueTitle"; +import { TimerComponents } from "@/components/timer/timer"; +import { Skeleton } from "@/components/ui/skeleton"; +import { usePermissions } from "@/provider/PermissionsProvider"; +import { useSettings } from "@/provider/SettingsProvider"; +import { useTimerApi } from "@/provider/TimerApiProvider"; +import { clsxm } from "@/utils/clsxm"; +import { ProjectTimersGroup as ProjectTimersGroupType } from "@/utils/groupTimers"; +import { randomElement } from "@/utils/random"; +import clsx from "clsx"; +import { SquareChartGanttIcon } from "lucide-react"; +import { ComponentProps } from "react"; +import { FormattedMessage } from "react-intl"; +import { TReference } from "../../api/redmine/types"; + +interface ProjectTimersGroupProps extends ComponentProps<"div"> { + projectGroup: ProjectTimersGroupType; +} + +export const ProjectTimersGroup = ({ projectGroup, className, ...props }: ProjectTimersGroupProps) => { + const { settings } = useSettings(); + + const timerApi = useTimerApi(); + + const { hasProjectPermission } = usePermissions(); + + const { getPriorityType } = useRedmineIssuePriorities({ enabled: settings.style.showIssuePriority }); + + return ( +
+ + {projectGroup.items.map(({ timer, issue }) => ( + + + timerApi.toggleTimer(timer)}> + {issue ? :

#{timer.issueId}

} + + + + + + + {settings.style.showSessions && } +
+
+
+ ))} +
+ ); +}; + +const TimerProject = ({ project, type }: { project?: TReference; type: ProjectTimersGroupType["type"] }) => { + const { settings } = useSettings(); + + return ( +
+ + + {project && ( + + {project.name} + + )} + + {type === "unknown-project" && } +
+ ); +}; + +export const ProjectTimersGroupSkeleton = ({ groups }: { groups: number[] }) => { + const { settings } = useSettings(); + + return ( +
+
+ +
+
+ {groups.map((key) => ( + + + + + + + + + {settings.style.showSessions && } + + ))} +
+
+ ); +}; diff --git a/src/components/timer/TimerSearch.tsx b/src/components/timer/TimerSearch.tsx new file mode 100644 index 00000000..b9cb13e1 --- /dev/null +++ b/src/components/timer/TimerSearch.tsx @@ -0,0 +1,127 @@ +import { Skeleton } from "@/components/ui/skeleton"; +import { clsxm } from "@/utils/clsxm"; +import { SearchIcon } from "lucide-react"; +import { createContext, PropsWithChildren, use, useEffect, useRef, useState } from "react"; +import { useIntl } from "react-intl"; +import useHotKey from "../../hooks/useHotkey"; +import { useSettings } from "../../provider/SettingsProvider"; +import { InputGroup, InputGroupAddon, InputGroupInput } from "../ui/input-group"; + +export type TimerSearchContext = { + isSearching: boolean; + query: string; +}; + +type TimerSearchInternalContext = TimerSearchContext & { + isSearchOpen: boolean; + rawQuery: string; + setRawQuery: (query: string) => void; + focusTrigger: number; +}; + +const SearchContext = createContext(undefined); + +const TimerSearchProvider = ({ children }: PropsWithChildren) => { + const { settings } = useSettings(); + + const [isSearchOpen, setIsSearchOpen] = useState(settings.style.displaySearchAlways); + const [query, setQuery] = useState(""); + const [focusTrigger, setFocusTrigger] = useState(0); + + const requestFocus = () => setFocusTrigger((prev) => prev + 1); + + // hotkeys + useHotKey({ ctrl: true, key: "k" }, () => { + setIsSearchOpen(true); + requestFocus(); + }); + useHotKey({ ctrl: true, key: "f" }, () => { + setIsSearchOpen(true); + requestFocus(); + }); + useHotKey( + { key: "Escape" }, + () => { + if (!settings.style.displaySearchAlways) { + setIsSearchOpen(false); + } + setQuery(""); + }, + isSearchOpen + ); + + return ( + 0, + query, + isSearchOpen, + rawQuery: query, + setRawQuery: setQuery, + focusTrigger, + }} + > + {children} + + ); +}; + +const TimerSearchInput = ({ className }: { className?: string }) => { + const { formatMessage } = useIntl(); + const ctx = useTimerSearchInternal(); + + const searchRef = useRef(null); + useEffect(() => { + if (ctx.focusTrigger > 0) { + searchRef.current?.focus(); + searchRef.current?.select(); + } + }, [ctx.focusTrigger]); + + if (!ctx.isSearchOpen) return null; + + return ( +
+ + ctx.setRawQuery(e.target.value)} autoFocus /> + + + + +
+ ); +}; + +const useTimerSearchInternal = () => { + const context = use(SearchContext); + if (!context) { + throw new Error("useTimerSearch must be used within a TimerSearch.Provider component"); + } + return context; +}; + +export const useTimerSearch = (): TimerSearchContext => { + const { isSearching, query } = useTimerSearchInternal(); + return { isSearching, query }; +}; + +const TimerSearchInputSkeleton = ({ className }: { className?: string }) => { + const { settings } = useSettings(); + + if (!settings.style.displaySearchAlways) return null; + + return ( +
+ +
+ ); +}; +const TimerSearch = { + Provider: TimerSearchProvider, + Input: TimerSearchInput, + Skeleton: { + Input: TimerSearchInputSkeleton, + }, +}; + +export default TimerSearch; diff --git a/src/components/timer/TimersBadge.tsx b/src/components/timer/TimersBadge.tsx new file mode 100644 index 00000000..845da51e --- /dev/null +++ b/src/components/timer/TimersBadge.tsx @@ -0,0 +1,11 @@ +import BrowserNotificationBadge from "../general/BrowserNotificationBadge"; + +type PropTypes = { + activeTimerCount: number; +}; + +const TimersBadge = ({ activeTimerCount }: PropTypes) => { + return 0 ? activeTimerCount.toString() : ""} />; +}; + +export default TimersBadge; diff --git a/src/components/timer/timer/TimerContextMenu.tsx b/src/components/timer/timer/TimerContextMenu.tsx new file mode 100644 index 00000000..3118e42b --- /dev/null +++ b/src/components/timer/timer/TimerContextMenu.tsx @@ -0,0 +1,44 @@ +import { useTimerApi } from "@/provider/TimerApiProvider"; +import { PencilIcon, TimerIcon, TimerOffIcon, TimerResetIcon, TrashIcon } from "lucide-react"; +import { ReactElement } from "react"; +import { useIntl } from "react-intl"; +import { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuTrigger } from "../../ui/context-menu"; +import { useTimerContext } from "./TimerRoot"; + +export const TimerContextMenu = ({ children }: { children: ReactElement }) => { + return ( + + + + + + + ); +}; + +const TimerContextMenuItems = () => { + const { formatMessage } = useIntl(); + const timerApi = useTimerApi(); + const { timer, totalElapsedTime, setIsEditing } = useTimerContext(); + + return ( + <> + timerApi.pauseTimer(timer) : () => timerApi.startTimer(timer)}> + {timer.activeSession ? : } + {formatMessage({ id: timer.activeSession ? "timer.context-menu.pause" : "timer.context-menu.start" })} + + setIsEditing(true)}> + + {formatMessage({ id: "timer.context-menu.edit" })} + + timerApi.resetTimer(timer)} disabled={totalElapsedTime === 0}> + + {formatMessage({ id: "timer.context-menu.reset" })} + + timerApi.deleteTimer(timer)}> + + {formatMessage({ id: "timer.context-menu.delete" })} + + + ); +}; diff --git a/src/components/timer/timer/TimerCounter.tsx b/src/components/timer/timer/TimerCounter.tsx new file mode 100644 index 00000000..0f8d34d3 --- /dev/null +++ b/src/components/timer/timer/TimerCounter.tsx @@ -0,0 +1,176 @@ +import HelpTooltip from "@/components/general/HelpTooltip"; +import { Skeleton } from "@/components/ui/skeleton"; +import { useTimerApi } from "@/provider/TimerApiProvider"; +import { formatTimer } from "@/utils/date"; +import clsx from "clsx"; +import { FocusEvent, useState } from "react"; +import { useIntl } from "react-intl"; +import useHotKey from "../../../hooks/useHotkey"; +import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "../../ui/alert-dialog"; +import { Input } from "../../ui/input"; +import { useTimerContext } from "./TimerRoot"; + +export const TimerCounter = () => { + const { formatMessage } = useIntl(); + + const { timer, totalElapsedTime, isEditing, setIsEditing } = useTimerContext(); + + if (isEditing) { + return ; + } + + return ( + + 0 })} + onDoubleClick={() => setIsEditing(true)} + > + {formatTimer(totalElapsedTime)} + + + ); +}; + +export const EditTimer = () => { + const { formatMessage } = useIntl(); + + const timerApi = useTimerApi(); + const { timer, totalElapsedTime, setIsEditing } = useTimerContext(); + + const [h, setH] = useState(() => Math.floor(totalElapsedTime / 1000 / 60 / 60).toString()); + const [m, setM] = useState(() => to2Digit(Math.floor((totalElapsedTime / 1000 / 60) % 60))); + const [s, setS] = useState(() => to2Digit(Math.floor((totalElapsedTime / 1000) % 60))); + const updatedTime = (Number(h) * 60 * 60 + Number(m) * 60 + Number(s)) * 1000; + + const onOverrideTime = () => { + setIsEditing(false); + timerApi.setTotalElapsedTime(timer, updatedTime); + }; + + const [confirmCancelModal, setConfirmCancelModal] = useState(false); + const onCancel = () => setConfirmCancelModal(true); + const onConfirmCancel = () => setIsEditing(false); + + useHotKey({ key: "Escape" }, onConfirmCancel); + + return ( + <> +
+ 0 ? "text-yellow-500" : "text-muted-foreground", { + "w-4": h.length === 1, + "w-6": h.length === 2, + "w-8": h.length >= 3, + })} + /** + * auto focus & select input on focus + */ + autoFocus + onFocus={(e) => e.target.select()} + onChange={(e) => { + const { value, min } = e.target; + setH(Math.max(Number(min), Number(value)).toString()); + }} + /** + * On "Enter" => override time + */ + onKeyDown={(e) => { + if (e.key === "Enter") { + onOverrideTime(); + e.preventDefault(); + e.stopPropagation(); + } + }} + /** + * On loose focus, check if next target not a number input => cancel + */ + onBlur={(e) => { + if (!(e.relatedTarget?.localName === "input" && (e as FocusEvent).relatedTarget?.type === "number")) onCancel(); + }} + /> + : + 0 ? "text-yellow-500" : "text-muted-foreground")} + onChange={(e) => { + const { value, min, max } = e.target; + setM(to2Digit(Math.max(Number(min), Math.min(Number(max), Number(value))))); + }} + /** + * On "Enter" => override time + */ + onKeyDown={(e) => { + if (e.key === "Enter") { + onOverrideTime(); + e.preventDefault(); + e.stopPropagation(); + } + }} + /** + * On loose focus, check if next target not a number input => cancel + */ + onBlur={(e) => { + if (!(e.relatedTarget?.localName === "input" && (e as FocusEvent).relatedTarget?.type === "number")) onCancel(); + }} + /> + : + 0 ? "text-yellow-500" : "text-muted-foreground")} + onChange={(e) => { + const { value, min, max } = e.target; + setS(to2Digit(Math.max(Number(min), Math.min(Number(max), Number(value))))); + }} + /** + * On "Enter" => override time + */ + onKeyDown={(e) => { + if (e.key === "Enter") { + onOverrideTime(); + e.preventDefault(); + e.stopPropagation(); + } + }} + /** + * On loose focus, check if next target not a number input => cancel + */ + onBlur={(e) => { + if (!(e.relatedTarget?.localName === "input" && (e as FocusEvent).relatedTarget?.type === "number")) onCancel(); + }} + /> +
+ + {confirmCancelModal && ( + + + + {formatMessage({ id: "issues.modal.save-changes.title" })} + {formatMessage({ id: "issues.modal.save-changes.message" })} + + + {formatMessage({ id: "issues.modal.save-changes.cancel" })} + onOverrideTime()}>{formatMessage({ id: "issues.modal.save-changes.save" })} + + + + )} + + ); +}; + +const to2Digit = (val: number) => { + return `${val < 10 ? "0" : ""}${val}`; +}; + +export const TimerCounterSkeleton = () => { + return ; +}; diff --git a/src/components/timer/timer/TimerDoneButton.tsx b/src/components/timer/timer/TimerDoneButton.tsx new file mode 100644 index 00000000..6d89d6e3 --- /dev/null +++ b/src/components/timer/timer/TimerDoneButton.tsx @@ -0,0 +1,59 @@ +import HelpTooltip from "@/components/general/HelpTooltip"; +import CreateTimeEntryModal from "@/components/time-entry/CreateTimeEntryModal"; +import { Skeleton } from "@/components/ui/skeleton"; +import { useSettings } from "@/provider/SettingsProvider"; +import { useTimerApi } from "@/provider/TimerApiProvider"; +import { roundMillisecondsToInterval } from "@/utils/date"; +import { BadgeCheckIcon } from "lucide-react"; +import { useState } from "react"; +import { useIntl } from "react-intl"; +import { useTimerContext } from "./TimerRoot"; + +export const TimerDoneButton = ({ canLogTime }: { canLogTime: boolean }) => { + const { formatMessage } = useIntl(); + const { settings } = useSettings(); + + const timerApi = useTimerApi(); + const { timer, issue, totalElapsedTime } = useTimerContext(); + + const isDisabled = !canLogTime || !issue; + const [createTimeEntryHours, setCreateTimeEntryHours] = useState(undefined); + + return ( + <> + + { + if (isDisabled) return; + const time = settings.features.roundToInterval ? roundMillisecondsToInterval(totalElapsedTime, settings.features.roundingInterval, settings.features.roundingMode) : totalElapsedTime; + const hours = Number((time / 1000 / 60 / 60).toFixed(2)); + setCreateTimeEntryHours(hours); + }} + tabIndex={-1} + /> + + + {createTimeEntryHours !== undefined && issue && ( + setCreateTimeEntryHours(undefined)} + onSuccess={() => { + setCreateTimeEntryHours(undefined); + timerApi.deleteTimer(timer); + }} + /> + )} + + ); +}; + +export const TimerDoneButtonSkeleton = () => ; diff --git a/src/components/timer/timer/TimerNameField.tsx b/src/components/timer/timer/TimerNameField.tsx new file mode 100644 index 00000000..1689afd3 --- /dev/null +++ b/src/components/timer/timer/TimerNameField.tsx @@ -0,0 +1,33 @@ +import { Skeleton } from "@/components/ui/skeleton"; +import { useTimerApi } from "@/provider/TimerApiProvider"; +import { useEffect, useEffectEvent, useState } from "react"; +import { useIntl } from "react-intl"; +import { useTimerContext } from "./TimerRoot"; + +export const TimerNameField = () => { + const { formatMessage } = useIntl(); + const timerApi = useTimerApi(); + const { timer } = useTimerContext(); + + const [name, setName] = useState(timer.name); + const updateName = useEffectEvent(setName); + useEffect(() => updateName(timer.name), [timer.name]); + + return ( + setName(e.target.value)} + onBlur={() => timerApi.setName(timer, name)} + /> + ); +}; + +export const TimerNameFieldSkeleton = () => ( +
+ +
+); diff --git a/src/components/timer/timer/TimerRoot.tsx b/src/components/timer/timer/TimerRoot.tsx new file mode 100644 index 00000000..72d0993a --- /dev/null +++ b/src/components/timer/timer/TimerRoot.tsx @@ -0,0 +1,53 @@ +import { TIssue } from "@/api/redmine/types"; +import { calculateTimerTotalElapsedTime, Timer } from "@/hooks/useTimers"; +import { createContext, PropsWithChildren, use, useEffect, useEffectEvent, useState } from "react"; +import { useInterval } from "usehooks-ts"; + +type TimerContextType = { + timer: Timer; + issue?: TIssue; + totalElapsedTime: number; + isEditing: boolean; + setIsEditing: React.Dispatch>; +}; + +const TimerContext = createContext(undefined); + +type TimerRootProps = PropsWithChildren & { + timer: Timer; + issue?: TIssue; +}; + +export const TimerRoot = ({ timer, issue, children }: TimerRootProps) => { + const [totalElapsedTime, setTotalElapsedTime] = useState(() => calculateTimerTotalElapsedTime(timer)); + + const updateTimer = useEffectEvent(() => setTotalElapsedTime(calculateTimerTotalElapsedTime(timer))); + // eslint-disable-next-line react-hooks/set-state-in-effect + useEffect(() => updateTimer(), [timer.elapsedTime, timer.activeSession]); + + useInterval(() => setTotalElapsedTime(calculateTimerTotalElapsedTime(timer)), timer.activeSession ? 1000 : null); + + const [isEditing, setIsEditing] = useState(false); + + return ( + + {children} + + ); +}; + +export const useTimerContext = () => { + const context = use(TimerContext); + if (!context) { + throw new Error("useTimerContext must be used within a TimerComponents.Root component"); + } + return context; +}; diff --git a/src/components/timer/timer/TimerSessions.tsx b/src/components/timer/timer/TimerSessions.tsx new file mode 100644 index 00000000..40fa15a3 --- /dev/null +++ b/src/components/timer/timer/TimerSessions.tsx @@ -0,0 +1,145 @@ +import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@/components/ui/alert-dialog"; +import { Button } from "@/components/ui/button"; +import { Skeleton } from "@/components/ui/skeleton"; +import { calculateActiveSessionElapsedTime } from "@/hooks/useTimers"; +import { useTimerApi } from "@/provider/TimerApiProvider"; +import { formatTimer } from "@/utils/date"; +import { randomInt } from "@/utils/random"; +import clsx from "clsx"; +import { isToday } from "date-fns"; +import { ChevronDownIcon, ChevronUpIcon, TrashIcon } from "lucide-react"; +import { useMemo, useState } from "react"; +import { useIntl } from "react-intl"; +import { useInterval } from "usehooks-ts"; +import { useTimerContext } from "./TimerRoot"; + +export const TimerSessions = () => { + const { formatDateTimeRange, formatMessage } = useIntl(); + const { timer } = useTimerContext(); + + const [removingSessionId, setRemovingSessionId] = useState(null); + const [expanded, setExpanded] = useState(false); + + if (!timer.activeSession && timer.sessions.length === 0) return null; + + const allSessions = [...(timer.activeSession ? [{ id: "active", start: timer.activeSession.start, end: timer.activeSession.start }] : []), ...timer.sessions.toReversed()]; + const visibleSessions = expanded ? allSessions : allSessions.slice(0, 3); + const hiddenCount = allSessions.length - 3; + + return ( + <> +
+ {visibleSessions.map((session) => ( +
+ + {formatDateTimeRange(session.start, session.end, { + dateStyle: isToday(session.start) ? undefined : "short", + timeStyle: "medium", + })} + + + {session.id === "active" ? : formatTimer(session.end - session.start)} + + +
+ ))} + {hiddenCount > 0 && ( + + )} +
+ + {removingSessionId && setRemovingSessionId(null)} />} + + ); +}; + +const ActiveSessionElapsedTime = () => { + const { timer } = useTimerContext(); + + const [elapsedTime, setElapsedTime] = useState(() => calculateActiveSessionElapsedTime(timer)); + useInterval(() => setElapsedTime(calculateActiveSessionElapsedTime(timer)), timer.activeSession ? 1000 : null); + + return formatTimer(elapsedTime); +}; + +const RemoveSessionDialog = ({ sessionId, onClose }: { sessionId: string; onClose: () => void }) => { + const { formatDateTimeRange, formatMessage } = useIntl(); + const timerApi = useTimerApi(); + const { timer, totalElapsedTime } = useTimerContext(); + + // eslint-disable-next-line react-hooks/purity + const session = sessionId === "active" ? (timer.activeSession ? { id: "active", start: timer.activeSession.start, end: Date.now() } : undefined) : timer.sessions.find((s) => s.id === sessionId); + if (!session) return null; + + const duration = session.end - session.start; + const resultingTimer = Math.max(0, totalElapsedTime - duration); + + return ( + onClose()}> + + + {formatMessage({ id: "timer.modal.remove-session.title" })} + + +
+
+ {formatMessage({ id: "timer.modal.remove-session.current" })} + {formatTimer(totalElapsedTime)} +
+
+ + {formatDateTimeRange(session.start, session.end, { + dateStyle: isToday(session.start) ? undefined : "short", + timeStyle: "medium", + })} + + -{formatTimer(duration)} +
+
+ {formatMessage({ id: "timer.modal.remove-session.result" })} + {formatTimer(resultingTimer)} +
+
+ + + {formatMessage({ id: "timer.modal.remove-session.cancel" })} + { + await timerApi.removeTimerSession(timer, sessionId); + }} + > + {formatMessage({ id: "timer.modal.remove-session.submit" })} + + +
+
+ ); +}; + +export const TimerSessionsSkeleton = () => { + const sessions = useMemo(() => [...Array(randomInt(1, 3)).keys()], []); + + return ( +
+ {sessions.map((key) => ( +
+
+ +
+ + +
+ ))} +
+ ); +}; diff --git a/src/components/timer/timer/TimerToggleButton.tsx b/src/components/timer/timer/TimerToggleButton.tsx new file mode 100644 index 00000000..d182a5b9 --- /dev/null +++ b/src/components/timer/timer/TimerToggleButton.tsx @@ -0,0 +1,41 @@ +import HelpTooltip from "@/components/general/HelpTooltip"; +import { Skeleton } from "@/components/ui/skeleton"; +import { useTimerApi } from "@/provider/TimerApiProvider"; +import { TimerIcon, TimerOffIcon } from "lucide-react"; +import { useIntl } from "react-intl"; +import { useTimerContext } from "./TimerRoot"; + +export const TimerToggleButton = () => { + const { formatMessage } = useIntl(); + + const timerApi = useTimerApi(); + const { timer } = useTimerContext(); + + if (!timer.activeSession) { + return ( + + timerApi.startTimer(timer)} + tabIndex={-1} + /> + + ); + } else { + return ( + + timerApi.pauseTimer(timer)} + tabIndex={-1} + /> + + ); + } +}; + +export const TimerToggleButtonSkeleton = () => ; diff --git a/src/components/timer/timer/TimerWrapper.tsx b/src/components/timer/timer/TimerWrapper.tsx new file mode 100644 index 00000000..debd3c59 --- /dev/null +++ b/src/components/timer/timer/TimerWrapper.tsx @@ -0,0 +1,21 @@ +import { ToggleableCard } from "@/components/general/ToggleableCard"; +import { useTimerApi } from "@/provider/TimerApiProvider"; +import { clsxm } from "@/utils/clsxm"; +import clsx from "clsx"; +import { ComponentProps } from "react"; +import { useTimerContext } from "./TimerRoot"; + +export const TimerWrapper = ({ className, children, ...props }: ComponentProps<"div">) => { + return ( +
+ {children} +
+ ); +}; + +export const TimerWrapperCard = ({ className, ...props }: ComponentProps) => { + const timerApi = useTimerApi(); + const { timer } = useTimerContext(); + + return timerApi.toggleTimer(timer)} />; +}; diff --git a/src/components/timer/timer/index.ts b/src/components/timer/timer/index.ts new file mode 100644 index 00000000..075e6e63 --- /dev/null +++ b/src/components/timer/timer/index.ts @@ -0,0 +1,27 @@ +import { TimerContextMenu } from "./TimerContextMenu"; +import { TimerCounter, TimerCounterSkeleton } from "./TimerCounter"; +import { TimerDoneButton, TimerDoneButtonSkeleton } from "./TimerDoneButton"; +import { TimerNameField, TimerNameFieldSkeleton } from "./TimerNameField"; +import { TimerRoot } from "./TimerRoot"; +import { TimerSessions, TimerSessionsSkeleton } from "./TimerSessions"; +import { TimerToggleButton, TimerToggleButtonSkeleton } from "./TimerToggleButton"; +import { TimerWrapper, TimerWrapperCard } from "./TimerWrapper"; + +export const TimerComponents = { + Root: TimerRoot, + ContextMenu: TimerContextMenu, + Wrapper: TimerWrapper, + WrapperCard: TimerWrapperCard, + NameField: TimerNameField, + Counter: TimerCounter, + ToggleButton: TimerToggleButton, + DoneButton: TimerDoneButton, + Sessions: TimerSessions, + Skeleton: { + NameField: TimerNameFieldSkeleton, + Counter: TimerCounterSkeleton, + ToggleButton: TimerToggleButtonSkeleton, + DoneButton: TimerDoneButtonSkeleton, + Sessions: TimerSessionsSkeleton, + }, +}; diff --git a/src/components/ui/alert-dialog.tsx b/src/components/ui/alert-dialog.tsx new file mode 100644 index 00000000..bd27c6e9 --- /dev/null +++ b/src/components/ui/alert-dialog.tsx @@ -0,0 +1,136 @@ +import { AlertDialog as AlertDialogPrimitive } from "@base-ui/react/alert-dialog"; +import * as React from "react"; + +import { Button } from "@/components/ui/button"; +import { cn } from "@/lib/utils"; + +function AlertDialog({ ...props }: AlertDialogPrimitive.Root.Props) { + return ; +} + +function AlertDialogTrigger({ ...props }: AlertDialogPrimitive.Trigger.Props) { + return ; +} + +function AlertDialogPortal({ ...props }: AlertDialogPrimitive.Portal.Props) { + return ; +} + +function AlertDialogOverlay({ className, ...props }: AlertDialogPrimitive.Backdrop.Props) { + return ( + + ); +} + +function AlertDialogContent({ + className, + size = "default", + ...props +}: AlertDialogPrimitive.Popup.Props & { + size?: "default" | "sm"; +}) { + return ( + + + + + ); +} + +function AlertDialogHeader({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} + +function AlertDialogFooter({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} + +function AlertDialogMedia({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} + +function AlertDialogTitle({ className, ...props }: React.ComponentProps) { + return ( + + ); +} + +function AlertDialogDescription({ className, ...props }: React.ComponentProps) { + return ( + + ); +} + +function AlertDialogAction({ className, ...props }: React.ComponentProps) { + return