diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml index 1e67b0b92..2d2fab65c 100644 --- a/.github/release-drafter.yml +++ b/.github/release-drafter.yml @@ -10,6 +10,7 @@ version-resolver: - 'breaking-change' minor: labels: + - 'minor' - 'enhancement' - 'feature' patch: diff --git a/.github/workflows/crowdin.yml b/.github/workflows/crowdin.yml index 7b2bba31f..bb06499c9 100644 --- a/.github/workflows/crowdin.yml +++ b/.github/workflows/crowdin.yml @@ -10,6 +10,10 @@ on: ] branches: [ dev ] +permissions: + contents: write + pull-requests: write + jobs: synchronize-with-crowdin: name: Crowdin Sync @@ -19,7 +23,7 @@ jobs: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: crowdin action - uses: crowdin/github-action@c7af9bc98b01694653031fef2a0dc6c7888ce9bc # v2 + uses: crowdin/github-action@8f01d54f70f1713ee3f09d82c2bbb2daeac28689 # v2 with: upload_translations: false download_translations: true diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index ac351d2e3..21740a3e4 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -17,6 +17,8 @@ on: env: IMAGE_NAME: ${{ github.repository }} +permissions: {} + jobs: @@ -27,7 +29,6 @@ jobs: permissions: contents: read packages: write - id-token: write steps: - name: Checkout repository @@ -101,7 +102,7 @@ jobs: uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4.2.0 - name: Setup Docker buildx - uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4 + uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4 - name: Build and push Docker image id: build-and-push diff --git a/.github/workflows/docs-publish.yml b/.github/workflows/docs-publish.yml index d062b6125..1698d2a3c 100644 --- a/.github/workflows/docs-publish.yml +++ b/.github/workflows/docs-publish.yml @@ -10,8 +10,6 @@ on: permissions: contents: read - pages: write - id-token: write jobs: @@ -25,7 +23,7 @@ jobs: with: python-version-file: ".python-version" - name: Install uv - uses: astral-sh/setup-uv@ae62891fec2bb8e7d6c99fc78c9fec3a63790f8d # v10.0.0 + uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1 - run: sudo apt-get install pngquant - name: Test Docs Build run: uv run --frozen zensical build --clean @@ -33,6 +31,10 @@ jobs: name: Build & Deploy Docs if: github.repository == 'gethomepage/homepage' && github.event_name != 'pull_request' && github.ref == 'refs/heads/main' runs-on: ubuntu-latest + permissions: + contents: read + pages: write + id-token: write environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} @@ -43,7 +45,7 @@ jobs: with: python-version-file: ".python-version" - name: Install uv - uses: astral-sh/setup-uv@ae62891fec2bb8e7d6c99fc78c9fec3a63790f8d # v10.0.0 + uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1 - run: sudo apt-get install pngquant - name: Build Docs run: uv run --frozen zensical build --clean diff --git a/.github/workflows/issue-triage.yml b/.github/workflows/issue-triage.yml index 3baf335d0..8dc01d944 100644 --- a/.github/workflows/issue-triage.yml +++ b/.github/workflows/issue-triage.yml @@ -6,15 +6,15 @@ on: discussion: types: [labeled] -permissions: - discussions: write - issues: write +permissions: {} jobs: close-needs-discussion: name: Issues Need Discussion if: github.event_name == 'issues' && github.event.label.name == 'needs-discussion' runs-on: ubuntu-latest + permissions: + issues: write steps: - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: @@ -49,6 +49,8 @@ jobs: name: Discussions Need Information if: github.event_name == 'discussion' && github.event.label.name == 'needs-information' runs-on: ubuntu-latest + permissions: + discussions: write steps: - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 0d4e95132..2c731055a 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -6,6 +6,9 @@ on: workflow_dispatch: merge_group: +permissions: + contents: read + jobs: lint: name: Linting Checks diff --git a/.github/workflows/pr-quality.yml b/.github/workflows/pr-quality.yml index d1931a762..751b802b9 100644 --- a/.github/workflows/pr-quality.yml +++ b/.github/workflows/pr-quality.yml @@ -2,7 +2,6 @@ name: PR Quality permissions: contents: read - issues: read pull-requests: write on: diff --git a/.github/workflows/pr-triage.yml b/.github/workflows/pr-triage.yml index ee659cc2c..93278a061 100644 --- a/.github/workflows/pr-triage.yml +++ b/.github/workflows/pr-triage.yml @@ -5,7 +5,6 @@ on: types: [labeled] permissions: - issues: write pull-requests: write jobs: diff --git a/.github/workflows/repo-maintenance.yml b/.github/workflows/repo-maintenance.yml index 330fc0152..50030aa3b 100644 --- a/.github/workflows/repo-maintenance.yml +++ b/.github/workflows/repo-maintenance.yml @@ -5,10 +5,7 @@ on: - cron: '0 3 * * *' workflow_dispatch: -permissions: - issues: write - pull-requests: write - discussions: write +permissions: {} concurrency: group: lock @@ -17,6 +14,9 @@ jobs: stale: name: 'Stale' runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write steps: - uses: actions/stale@1e223db275d687790206a7acac4d1a11bd6fe629 # v10 with: @@ -31,6 +31,10 @@ jobs: lock-threads: name: 'Lock Old Threads' runs-on: ubuntu-latest + permissions: + discussions: write + issues: write + pull-requests: write steps: - uses: dessant/lock-threads@89ae32b08ed1a541efecbab17912962a5e38981c # v6.0.2 with: @@ -56,6 +60,8 @@ jobs: close-answered-discussions: name: 'Close Answered Discussions' runs-on: ubuntu-latest + permissions: + discussions: write steps: - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: @@ -112,6 +118,8 @@ jobs: close-outdated-discussions: name: 'Close Outdated Discussions' runs-on: ubuntu-latest + permissions: + discussions: write steps: - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: @@ -203,6 +211,8 @@ jobs: close-unsupported-feature-requests: name: 'Close Unsupported Feature Requests' runs-on: ubuntu-latest + permissions: + discussions: write steps: - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 887c68b51..8c24d6a26 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -5,6 +5,9 @@ on: push: workflow_dispatch: +permissions: + contents: read + jobs: vitest: runs-on: ubuntu-latest diff --git a/docs/widgets/authoring/getting-started.md b/docs/widgets/authoring/getting-started.md index d93b01862..27fbb0570 100644 --- a/docs/widgets/authoring/getting-started.md +++ b/docs/widgets/authoring/getting-started.md @@ -85,6 +85,7 @@ To ensure cohesiveness of various widgets, the following should be used as a gui - Note that we reserve the right to decline widgets for projects that are very young (eg < ~1y) or those with a small reach (eg low GitHub stars). Again, this is in an effort to keep overall widget maintenance under control. - Widgets should be only one row of blocks - Widgets should be no more than 4 blocks wide and generally conform to the styling / design choices of other widgets +- Use `withWidgetFields(service, defaultFields)` from `utils/widget-fields` to apply default fields and cap configured fields without mutating the service. The helper limits widgets to 4 fields. - Minimize the number of API calls - Avoid the use of custom proxy unless absolutely necessary - Widgets should be 'read-only', as in they should not make write changes using the relevant tool's API. Homepage widgets are designed to surface information, not to be a (usually worse) replacement for the tool itself. diff --git a/docs/widgets/services/crowdsec.md b/docs/widgets/services/crowdsec.md index 977b0adb4..fdf03a77e 100644 --- a/docs/widgets/services/crowdsec.md +++ b/docs/widgets/services/crowdsec.md @@ -9,7 +9,9 @@ See the [crowdsec docs](https://docs.crowdsec.net/docs/local_api/intro/#machines in most instances you can use the default credentials (`/etc/crowdsec/local_api_credentials.yaml`). !!! note -Without the `limit24h` option, the widget will fetch all alerts which is limited to 100 by the API to avoid performance issues. + + `alerts` counts alerts raised by your own engine in the last 24 hours. Alerts originating from the + CrowdSec community blocklist are excluded. Allowed fields: `["alerts", "bans"]`. @@ -19,5 +21,4 @@ widget: url: http://crowdsechostorip:port username: localhost # machine_id in crowdsec password: password - limit24h: true # optional, limits alerts to last 24h. Default: false ``` diff --git a/docs/widgets/services/proxmoxbackupserver.md b/docs/widgets/services/proxmoxbackupserver.md index e3281337c..e48c56cc2 100644 --- a/docs/widgets/services/proxmoxbackupserver.md +++ b/docs/widgets/services/proxmoxbackupserver.md @@ -15,5 +15,5 @@ widget: url: https://proxmoxbackupserver.host:port username: api_token_id password: api_token_secret - datastore: datastore_name #optional; if ommitted, will display a combination of all datastores used / total + datastore: datastore_name #optional; if omitted, will display a combination of all datastores used / total ``` diff --git a/eslint.config.mjs b/eslint.config.mjs index 929077cfb..5e046287e 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,30 +1,13 @@ -import path from "node:path"; -import { fileURLToPath } from "node:url"; - -import { fixupConfigRules } from "@eslint/compat"; -import { FlatCompat } from "@eslint/eslintrc"; -import js from "@eslint/js"; -import prettier from "eslint-plugin-prettier"; +import nextCoreWebVitals from "eslint-config-next/core-web-vitals"; +import prettierConfig from "eslint-config-prettier/flat"; import { defineConfig, globalIgnores } from "eslint/config"; -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); -const compat = new FlatCompat({ - baseDirectory: __dirname, - recommendedConfig: js.configs.recommended, - allConfig: js.configs.all, -}); - export default defineConfig([ + ...nextCoreWebVitals, + prettierConfig, { files: ["**/*.{js,mjs,cjs,jsx}"], - extends: fixupConfigRules(compat.extends("next/core-web-vitals", "prettier", "plugin:react-hooks/recommended")), - - plugins: { - prettier, - }, - languageOptions: { ecmaVersion: 6, sourceType: "module", @@ -65,24 +48,6 @@ export default defineConfig([ allowElseIf: true, }, ], - - // Keep the pre-eslint-plugin-react-hooks v6 lint policy until rules are adopted incrementally - "react-hooks/config": "off", - "react-hooks/error-boundaries": "off", - "react-hooks/exhaustive-deps": "warn", - "react-hooks/gating": "off", - "react-hooks/globals": "off", - "react-hooks/immutability": "off", - "react-hooks/incompatible-library": "off", - "react-hooks/preserve-manual-memoization": "off", - "react-hooks/purity": "off", - "react-hooks/refs": "off", - "react-hooks/rules-of-hooks": "error", - "react-hooks/set-state-in-effect": "off", - "react-hooks/set-state-in-render": "off", - "react-hooks/static-components": "off", - "react-hooks/unsupported-syntax": "off", - "react-hooks/use-memo": "off", }, }, // Vitest tests often intentionally place imports after `vi.mock(...)` to ensure diff --git a/package.json b/package.json index e15277f5f..7adf00be8 100644 --- a/package.json +++ b/package.json @@ -23,12 +23,12 @@ "gamedig": "^5.3.3", "i18next": "^26.3.6", "ical.js": "^2.2.1", - "js-yaml": "^5.3.0", + "js-yaml": "^5.4.0", "json-rpc-2.0": "^1.7.1", "luxon": "^3.7.2", "memory-cache": "^0.2.0", "minecraftstatuspinger": "^1.2.2", - "next": "^16.2.12", + "next": "^16.3.3", "next-auth": "^4.24.15", "next-i18next": "^16.0.8", "ping": "^1.0.0", @@ -36,7 +36,7 @@ "raw-body": "^4.0.0", "react": "^19.2.8", "react-dom": "^19.2.8", - "react-i18next": "^17.0.11", + "react-i18next": "^17.0.12", "react-icons": "^5.6.0", "recharts": "^3.1.2", "swr": "^2.5.1", @@ -48,29 +48,21 @@ "xml-js": "^1.6.11" }, "devDependencies": { - "@eslint/compat": "^2.1.0", - "@eslint/eslintrc": "^3.3.3", - "@eslint/js": "^9.39.4", "@tailwindcss/forms": "^0.5.11", "@tailwindcss/postcss": "^4.3.3", "@testing-library/jest-dom": "^7.0.1", "@testing-library/react": "^16.3.0", "@vitest/coverage-v8": "^4.1.10", "eslint": "^9.25.1", - "eslint-config-next": "^15.5.11", + "eslint-config-next": "^16.3.3", "eslint-config-prettier": "^10.1.8", - "eslint-plugin-import": "^2.32.0", - "eslint-plugin-jsx-a11y": "^6.10.2", - "eslint-plugin-prettier": "^5.5.6", - "eslint-plugin-react": "^7.37.4", - "eslint-plugin-react-hooks": "^7.1.1", "jsdom": "^30.0.1", "postcss": "^8.5.26", "prettier": "^3.8.4", "prettier-plugin-organize-imports": "^4.3.0", "tailwind-scrollbar": "^4.0.2", "tailwindcss": "^4.3.3", - "typescript": "^5.7.3", + "typescript": "^6.0.3", "vitest": "^4.1.0" }, "optionalDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e37902703..46d5d67b7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,7 +13,7 @@ importers: version: 2.2.10(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@kubernetes/client-node': specifier: ^2.0.0 - version: 2.0.0 + version: 2.0.0(supports-color@7.2.0) classnames: specifier: ^2.5.1 version: 2.5.1 @@ -22,22 +22,22 @@ importers: version: 6.1.1 dockerode: specifier: ^5.0.0 - version: 5.0.1 + version: 5.0.1(supports-color@7.2.0) follow-redirects: specifier: ^1.16.0 - version: 1.16.0 + version: 1.16.0(debug@4.4.3(supports-color@7.2.0)) gamedig: specifier: ^5.3.3 version: 5.3.3 i18next: specifier: ^26.3.6 - version: 26.3.6(typescript@5.9.3) + version: 26.3.6(typescript@6.0.3) ical.js: specifier: ^2.2.1 version: 2.2.1 js-yaml: - specifier: ^5.3.0 - version: 5.3.0 + specifier: ^5.4.0 + version: 5.4.0 json-rpc-2.0: specifier: ^1.7.1 version: 1.7.1 @@ -51,14 +51,14 @@ importers: specifier: ^1.2.2 version: 1.2.2 next: - specifier: ^16.2.12 - version: 16.3.0(@babel/core@7.29.7)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + specifier: ^16.3.3 + version: 16.3.3(@babel/core@7.29.7(supports-color@7.2.0))(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) next-auth: specifier: ^4.24.15 - version: 4.24.15(next@16.3.0(@babel/core@7.29.7)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + version: 4.24.15(next@16.3.3(@babel/core@7.29.7(supports-color@7.2.0))(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8) next-i18next: specifier: ^16.0.8 - version: 16.0.10(@types/react@19.2.18)(i18next@26.3.6(typescript@5.9.3))(next@16.3.0(@babel/core@7.29.7)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-i18next@17.0.11(i18next@26.3.6(typescript@5.9.3))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(typescript@5.9.3))(react@19.2.8) + version: 16.0.10(@types/react@19.2.18)(i18next@26.3.6(typescript@6.0.3))(next@16.3.3(@babel/core@7.29.7(supports-color@7.2.0))(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-i18next@17.0.12(i18next@26.3.6(typescript@6.0.3))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(typescript@6.0.3))(react@19.2.8) ping: specifier: ^1.0.0 version: 1.0.0 @@ -75,8 +75,8 @@ importers: specifier: ^19.2.8 version: 19.2.8(react@19.2.8) react-i18next: - specifier: ^17.0.11 - version: 17.0.11(i18next@26.3.6(typescript@5.9.3))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(typescript@5.9.3) + specifier: ^17.0.12 + version: 17.0.12(i18next@26.3.6(typescript@6.0.3))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(typescript@6.0.3) react-icons: specifier: ^5.6.0 version: 5.7.0(react@19.2.8) @@ -105,15 +105,6 @@ importers: specifier: ^1.6.11 version: 1.6.11 devDependencies: - '@eslint/compat': - specifier: ^2.1.0 - version: 2.1.0(eslint@9.39.5(jiti@2.7.0)) - '@eslint/eslintrc': - specifier: ^3.3.3 - version: 3.3.6 - '@eslint/js': - specifier: ^9.39.4 - version: 9.39.5 '@tailwindcss/forms': specifier: ^0.5.11 version: 0.5.11(tailwindcss@4.3.3) @@ -131,28 +122,13 @@ importers: version: 4.1.10(vitest@4.1.10) eslint: specifier: ^9.25.1 - version: 9.39.5(jiti@2.7.0) + version: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) eslint-config-next: - specifier: ^15.5.11 - version: 15.5.22(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) + specifier: ^16.3.3 + version: 16.3.3(@typescript-eslint/parser@8.68.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.39.5(jiti@2.7.0)) - eslint-plugin-import: - specifier: ^2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.66.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)) - eslint-plugin-jsx-a11y: - specifier: ^6.10.2 - version: 6.10.2(eslint@9.39.5(jiti@2.7.0)) - eslint-plugin-prettier: - specifier: ^5.5.6 - version: 5.5.6(eslint-config-prettier@10.1.8(eslint@9.39.5(jiti@2.7.0)))(eslint@9.39.5(jiti@2.7.0))(prettier@3.9.6) - eslint-plugin-react: - specifier: ^7.37.4 - version: 7.37.5(eslint@9.39.5(jiti@2.7.0)) - eslint-plugin-react-hooks: - specifier: ^7.1.1 - version: 7.1.1(eslint@9.39.5(jiti@2.7.0)) + version: 10.1.8(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0)) jsdom: specifier: ^30.0.1 version: 30.0.1 @@ -164,7 +140,7 @@ importers: version: 3.9.6 prettier-plugin-organize-imports: specifier: ^4.3.0 - version: 4.3.0(prettier@3.9.6)(typescript@5.9.3) + version: 4.3.0(prettier@3.9.6)(typescript@6.0.3) tailwind-scrollbar: specifier: ^4.0.2 version: 4.0.2(react@19.2.8)(tailwindcss@4.3.3) @@ -172,8 +148,8 @@ importers: specifier: ^4.3.3 version: 4.3.3 typescript: - specifier: ^5.7.3 - version: 5.9.3 + specifier: ^6.0.3 + version: 6.0.3 vitest: specifier: ^4.1.0 version: 4.1.10(@types/node@26.2.0)(@vitest/coverage-v8@4.1.10)(jsdom@30.0.1)(vite@8.2.1(@types/node@26.2.0)(jiti@2.7.0)) @@ -342,19 +318,16 @@ packages: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + '@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.2': resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/compat@2.1.0': - resolution: {integrity: sha512-LgaSCymEpw7tF53xvDw9SNsraPb1IBHxpdABIOM0hW8UAlP8znrjYtuxfR58FSJ3L9BhwD+FaPRFQpZq84Nh6g==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - peerDependencies: - eslint: ^8.40 || 9 || 10 - peerDependenciesMeta: - eslint: - optional: true - '@eslint/config-array@0.21.2': resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -367,10 +340,6 @@ packages: resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@1.2.1': - resolution: {integrity: sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/eslintrc@3.3.6': resolution: {integrity: sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -670,60 +639,60 @@ packages: '@emnapi/core': ^1.7.1 || ^2.0.0-alpha.3 '@emnapi/runtime': ^1.7.1 || ^2.0.0-alpha.3 - '@next/env@16.3.0': - resolution: {integrity: sha512-o9r1S0BNiNreHP9Vs+Qnqd9kviDkJh8xIACY7UFZSmiGbbQRzPBBosvHzAU4TULHOIuOj/18RSsyz2qrREmIFw==} + '@next/env@16.3.3': + resolution: {integrity: sha512-U2eYQRwXj+dsqxV79zFqExDdatnNY/ZWc2nsJU1p/OgT7fd3dXwlF6OjYaFQCfMoeTA19PWq+wVmYgimVA+V+g==} - '@next/eslint-plugin-next@15.5.22': - resolution: {integrity: sha512-SB8PGBmpAiVmOtMOIfObnI2VA3MN3jUGg0iYTh4MO2efxQIV/IL0U8iYOok/8DldCEKARyCOJJix+Vvgzaic/Q==} + '@next/eslint-plugin-next@16.3.3': + resolution: {integrity: sha512-pbEh30vvjKpDoTAmo1v3q2uM4JUi8QaEBpbmjWvGfoec2jLghy/WNtvzAT0bk+Ik9oz6etjt4YjXEk4BQnicCw==} - '@next/swc-darwin-arm64@16.3.0': - resolution: {integrity: sha512-55hpqq18bEVAlxedlTt3tFqZmKg2nUXT1kn1G/BGEy0R13h3LwtwHPVzzjG6P4LLeOHE32PFDQUVaJEWvBEZBw==} + '@next/swc-darwin-arm64@16.3.3': + resolution: {integrity: sha512-8Hiv32QJPwdV6KYJ8meR9SBA061tQqnIKTJDocvOXlEQqib0xMFpzArosuffFUUc0sslbh7QQ8a3Yey1QV8EIw==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@next/swc-darwin-x64@16.3.0': - resolution: {integrity: sha512-SOi96kSaF5T+0wW4koiM1bWzSPwjzTesC1p3df+FjdOi5LIQkBK/blxh7HdoKnNuI4PURF1OO7TZqtfnbWDSgw==} + '@next/swc-darwin-x64@16.3.3': + resolution: {integrity: sha512-A1lgKgwVchRYmSe467zdwhxT9040dd8lH+o65sL5Jet8fjB4kegw/rDyPIpYVRb6jAqwXFOJpjIXJLxQKLiE3A==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@next/swc-linux-arm64-gnu@16.3.0': - resolution: {integrity: sha512-P0gZAoPMF4dyTRzhmkV4PrqVzSOB6t4mC1oI3c4dqijJ+OVEVx5clIXAKR4/uQpsqw2KKM/0D5tVumcR2r5blg==} + '@next/swc-linux-arm64-gnu@16.3.3': + resolution: {integrity: sha512-bf0FIssMFueU2dm7vQEWWxk0c8UjKTdW0yzuh0sQsD8pf1+KCLDdaqhYZNMYGmXwEOiHAUzgBKudovIlcvvBjg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] libc: [glibc] - '@next/swc-linux-arm64-musl@16.3.0': - resolution: {integrity: sha512-tXXGKJw0m37O0eKJARVTX/TheKPhz0QFVtVVZXmOig+9YKLQOSP6hvf2pxv5DO7CLEJyTHx3Pg043CDQkv1G4Q==} + '@next/swc-linux-arm64-musl@16.3.3': + resolution: {integrity: sha512-W7viwCk9JY/cAkdz/A273rd5bb3RgT/IHwR7Upv90tunjBWNtAAhGhoecHh+teRNRSinuAFmE+l7fwZ4YKkrXg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] libc: [musl] - '@next/swc-linux-x64-gnu@16.3.0': - resolution: {integrity: sha512-pjGxK5EY7yWml78ALejFkWmgHsU7wbFQrISiugpH6FbUJhgEvw3xFZ/EBAtLl7QtL0WdQKiG9eWJ3mOKGTukHw==} + '@next/swc-linux-x64-gnu@16.3.3': + resolution: {integrity: sha512-0W46zw1N3ODpI6n0GeivHvvob1pooozgZVqy65k0mh4/7vr+FbY9+WpHzNVXjHipJf/A3FDheBG19H1s5A25rA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] libc: [glibc] - '@next/swc-linux-x64-musl@16.3.0': - resolution: {integrity: sha512-sjo++Xx+lomlPs3HRsHWhVDyGG6ms1kGW5EtHLERdII8AyG1i+f6aq68xHREO6AEMlhjTNEWBSmfJfqm9orf7g==} + '@next/swc-linux-x64-musl@16.3.3': + resolution: {integrity: sha512-H4mBso8ZTMBPtdT0PN0pBx2ayTvQuTuvS6qT13d77yVFJXAPCxkyIhLTmdMaGTJs0krQYI/qpzdHijCeihXhbg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] libc: [musl] - '@next/swc-win32-arm64-msvc@16.3.0': - resolution: {integrity: sha512-C5JSgiO54wURdaxdEUIXqkz04uMqC9UmPX1gtDrV/5Tf1UowdWYI8uA5hfFbPolTlp0q4KZ60xlHePNibf0VIw==} + '@next/swc-win32-arm64-msvc@16.3.3': + resolution: {integrity: sha512-cTMUJpcEGmeywofCUfhR+rSsoE33+rVPnPEYNTNdLNlsOeEg/vktOsKUSTb28vUGqD2jkm4Zaskcwn7OCI6FQg==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@next/swc-win32-x64-msvc@16.3.0': - resolution: {integrity: sha512-fDOggsweNb5SSw0ZKVk6U+gxSyGFFlIBY/LBc1r8GUj4u/6t6oArL+Pmkg0MBnsgR+KkdsURilVH4F3GXUGepA==} + '@next/swc-win32-x64-msvc@16.3.3': + resolution: {integrity: sha512-2VR4cTBzHXaBjnGsuH6GyJjENzQOmHeAh11uY1iUhjm3j5dEUrVJuUj+VL78jaGi/Dik8xS76zEj18BsFhlVZQ==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -753,10 +722,6 @@ packages: '@panva/hkdf@1.2.1': resolution: {integrity: sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw==} - '@pkgr/core@0.3.6': - resolution: {integrity: sha512-SEeaJLb3qBNF/OaXnaR1NmmBbFYk1zC0ZH/52fATcRPLFg/p791YrcyFFy44Bo9sLaGuSuLp5Q6axbb/O+v/RA==} - engines: {node: ^14.18.0 || >=16.0.0} - '@protobufjs/aspromise@1.1.2': resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} @@ -908,9 +873,6 @@ packages: '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} - '@rushstack/eslint-patch@1.16.1': - resolution: {integrity: sha512-TvZbIpeKqGQQ7X0zSCvPH9riMSFQFSggnfBjFZ1mEoILW+UuXCKwOoPcgjMwiUtRqFZ8jWhPJc4um14vC6I4ag==} - '@sindresorhus/is@5.6.0': resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==} engines: {node: '>=14.16'} @@ -924,9 +886,6 @@ packages: '@standard-schema/utils@0.3.0': resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==} - '@swc/helpers@0.5.15': - resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} - '@swc/helpers@0.5.23': resolution: {integrity: sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==} @@ -1146,63 +1105,63 @@ packages: '@types/use-sync-external-store@0.0.6': resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==} - '@typescript-eslint/eslint-plugin@8.66.0': - resolution: {integrity: sha512-p088eaGrzYz1s+7cov0aMOCkNGTJlVxF4jgubf28c8L0Cv9Rloj8YBHnv4hXLq6IIEE1AsjNWavO+k+8kP2Y0A==} + '@typescript-eslint/eslint-plugin@8.68.0': + resolution: {integrity: sha512-WASHDpCm6qO5jj9g1a+8NiW5+GCkAyLReR56/4VruYmNgfUmqpxOfZ2Yfb8xGfJPWv5Qi6LSD8sXdces3vbp/Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.66.0 + '@typescript-eslint/parser': ^8.68.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/parser@8.66.0': - resolution: {integrity: sha512-X6ypGChaWYk6PBtUg2BwuTZEFFcHJAtGTVJ9/lCTOufhZ4i9fNolQNnktq+kkMCwMj7V8Svsq7+TxSDslmhE0g==} + '@typescript-eslint/parser@8.68.0': + resolution: {integrity: sha512-fHq2VC1kpyYfvEcbiMjOpySY4WS7voEp89yAThrHRX5sm9j2lzYppCb2umFMEed4fWcyeLjHxrz0mpjNBaBxMQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.66.0': - resolution: {integrity: sha512-7MthGPTt4BP69lSryqpqq8HQqxuzynssckL/jyDyk3+TNMQ3y2jFWkptCrktWvBrP+EH787Nl5N5Qpw7WZg+5g==} + '@typescript-eslint/project-service@8.68.0': + resolution: {integrity: sha512-5GQtWZCXFcFYux955pvoS02WLc49pXNlvIxocKjS0clvwo3in1RdlzVKyiqQH9vE5AKWFLTaUgeQkOrTS+0Qxw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/scope-manager@8.66.0': - resolution: {integrity: sha512-8TGcH25j9zqJ/IULB/ppyhRvxA8QYfFEZ7nfbg6/BN9spDgb8fPWQXlE5l8TWBL50EtUx007uZ1o9VOwrq2/9g==} + '@typescript-eslint/scope-manager@8.68.0': + resolution: {integrity: sha512-T5eXpcaJNg8bhjHJ8Rjp68Vq/QBteYtTKY8TZqVNPaUbuz0f6jI9t6aDkylwvalpAB9XTTFeFOjrjXAZ3YvmVA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.66.0': - resolution: {integrity: sha512-9D5gLYZG4rOjcoag8MQ/fWI8WqA9wcPDyOGyWtWFhvM1lHRbliqUSPIY5J3zqCU1tvSwzXxnnjhQhz5Ne7mJ4g==} + '@typescript-eslint/tsconfig-utils@8.68.0': + resolution: {integrity: sha512-F7zrGQfiJHojPwi8vhxZQC1tWtJzvL74cK/nqri2lk8YUXvYaYwl263xOJ69jDWPUk1hmcdoayFwk9lX09npVw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/type-utils@8.66.0': - resolution: {integrity: sha512-LG2dWfjZQQp0ADtAu/EWJVayefGL2UEZ3CDeI44D9v3rXB/WYUqE/jpO28KrEKul5AySrmI+Zh1v6v+xW2U9+g==} + '@typescript-eslint/type-utils@8.68.0': + resolution: {integrity: sha512-X77zqoY1EjeWGs/0JNxeaMfp5C5lIz4Tw8y66F1Ne8Faq6g424sBNYM6xBAqElfGZPLpWS+CZAp0DXyKDzWiHg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/types@8.66.0': - resolution: {integrity: sha512-H6gcYaSDOyvL3AD/jHUtUFo2jqGgn/F6nuyuZSu0QTesxL+cP4dQoIMrODRofuJC09g64+WgZ6tE19Y1N2YIFQ==} + '@typescript-eslint/types@8.68.0': + resolution: {integrity: sha512-9RnpsGJjrAllCMefGVVsImJM24YurhC0Q1h4UbvivtvOqXmR/vEJge2OoE++z9m6hyg8T1Q8t5SNT6tHSbrxcg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.66.0': - resolution: {integrity: sha512-8/x4INiiQb10jGgXYD7116/zQ+OL84ZIFn0za68wwFHCanT/VLbBEroWht8RV8fn0/ZCAoazHLQgwUC0UQcDfg==} + '@typescript-eslint/typescript-estree@8.68.0': + resolution: {integrity: sha512-OKKsD0tYmoNiU5PW2zehO1yO56jYOm1ShYlxon/Z0SJNidAkdVg86eg9ruRuoXf8xfnuWZGbwDsStkoXbZtIIA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.66.0': - resolution: {integrity: sha512-jasearZPolBw5NJNYGMwxzHMF83niVWmMU1VdHzG1CyfI2VS7f7nZltnKtHcg20hW+7Uo5GfK4MeDPoU3qI8EA==} + '@typescript-eslint/utils@8.68.0': + resolution: {integrity: sha512-PB5gJMMOg0Q5P1tsgWtEAqQacJXq0qEqRHDX/YJ4FaTMLfZPpHB3gjl2EJuiZyPABxmj4ZQYiY9m1bdAJ5y7tQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/visitor-keys@8.66.0': - resolution: {integrity: sha512-dkKR8q+lKciskj1Y3vthHktl+3cMLWGyVUP23bRiPZ5O9BRT++4EqDDV+TVeIKBL1VXVEqrJlz8MYbcnvJcAlg==} + '@typescript-eslint/visitor-keys@8.68.0': + resolution: {integrity: sha512-YR65gGdGvTUAWLldC3xLOvOzamdGzB4A5/N8rehEaHs3Zvoe39BhgY+u0SPch1OvrVTfLcc55wsSgK2NcnTS/A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@unrs/resolver-binding-android-arm-eabi@1.12.2': @@ -1540,13 +1499,8 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.11.12: - resolution: {integrity: sha512-r7WnVImvVCeFpf2DOXfy41aPWzeNg3H/A2X4dKmy1QL0MSyyk/e7z8ihJ3N6Nn2PsdhkVlqnEfnUE4a05P2aTA==} - engines: {node: '>=6.0.0'} - hasBin: true - - baseline-browser-mapping@2.11.14: - resolution: {integrity: sha512-JyJ954WzuIR8/FFzX0o5krdSTrBAkcCSRfWSleRsIHSWV+cZe2FI1PKggVkFke1hBldRs+LRxUczzE9iPmgZww==} + baseline-browser-mapping@2.11.19: + resolution: {integrity: sha512-Grytf1xOxOEMTGRwx6rLGKkTabd4vMg3VrKdj/7joCmV0qgh4QwMMO6xh34YEXQqirAuUdgQGa5orJQQ+69RBw==} engines: {node: '>=6.0.0'} hasBin: true @@ -1610,11 +1564,8 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - caniuse-lite@1.0.30001807: - resolution: {integrity: sha512-daRXJ9EB/rdRgu7kV+TTl1YUKtlsMWblPl2sLnpg9DZae16QCegol6A1SmCE31Lm9mXC1sRWGt/krouH+/dl7Q==} - - caniuse-lite@1.0.30001809: - resolution: {integrity: sha512-xxWVywk6a6Arlk+hymeycyn/VgqEfLDxupvhH/xiY5SJ/18kmi9o6MiO320DCUzypORHLtvh0I4i04tUhCNHNQ==} + caniuse-lite@1.0.30001810: + resolution: {integrity: sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==} chai@6.2.2: resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} @@ -1925,10 +1876,10 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - eslint-config-next@15.5.22: - resolution: {integrity: sha512-HhZsB3dvBsYwQpnymZm/Ps9NVaSYiSzDSXkR02CjyOcQutCuea3cF7NxE8i8Drs2+Dgw95WUzK2CMBIHd5YbMw==} + eslint-config-next@16.3.3: + resolution: {integrity: sha512-teqtsR26tnlfXFHfVLTM/4tzEzU8DMu6GS1sddZzhfGzgd2f2ofbgDUcsk6cssSCzX6Tk6fmWifJcdANSdPJrw==} peerDependencies: - eslint: ^7.23.0 || ^8.0.0 || ^9.0.0 + eslint: '>=9.0.0' typescript: '>=3.3.1' peerDependenciesMeta: typescript: @@ -1993,26 +1944,6 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 - eslint-plugin-prettier@5.5.6: - resolution: {integrity: sha512-ifetmTcxWfz+4qRW3pH/ujdTq2jQIj59AxJMIN26K5avYgU8dxycUETQonWiW+wPrYXA0j3Try0l1CnwVQtDqQ==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - '@types/eslint': '>=8.0.0' - eslint: '>=8.0.0' - eslint-config-prettier: '>= 7.0.0 <10.0.0 || >=10.1.0' - prettier: '>=3.0.0' - peerDependenciesMeta: - '@types/eslint': - optional: true - eslint-config-prettier: - optional: true - - eslint-plugin-react-hooks@5.2.0: - resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} - engines: {node: '>=10'} - peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 - eslint-plugin-react-hooks@7.1.1: resolution: {integrity: sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==} engines: {node: '>=18'} @@ -2092,9 +2023,6 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - fast-diff@1.3.0: - resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} - fast-fifo@1.3.2: resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} @@ -2243,6 +2171,10 @@ packages: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} + globals@16.4.0: + resolution: {integrity: sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==} + engines: {node: '>=18'} + globalthis@1.0.4: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} @@ -2549,8 +2481,8 @@ packages: resolution: {integrity: sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==} hasBin: true - js-yaml@5.3.0: - resolution: {integrity: sha512-muutsYr+e2+d3rTgUGslq5rxbBlUy3cJ61IsHag2QNDQV+7zXWjkUpmALIajhrlLlrgRUiymj6U3zUr/TMK84Q==} + js-yaml@5.4.0: + resolution: {integrity: sha512-jE7vUJIebKzYQI5xu4co5CRBDlDEYnHrdzsxs4O2giCz4v2SbVMYKpmt1D9L38OKQAeCWmrOTRiCV93u0UkaJA==} hasBin: true jsdom@30.0.1: @@ -2890,6 +2822,11 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + nanoid@3.3.18: + resolution: {integrity: sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + napi-postinstall@0.3.4: resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} @@ -2924,8 +2861,8 @@ packages: react: '>= 18.0.0' react-i18next: '>= 14.0.0' - next@16.3.0: - resolution: {integrity: sha512-NEdGOzH+08eTXMUp9UYkA99Nhi5N6Thrhc1jgFOQgfgnGK/dA2hRwBpXep+exdFQrnwlRf/3Wixyp8lLBUpE2A==} + next@16.3.3: + resolution: {integrity: sha512-tuRTx1nQ/yVw83cwJBo9F+njGUgMn3UHQycreWHB8XsStvvAh1AthbI8/4IpKnFaF58F+iSiHejYOlMQ/eq83g==} engines: {node: '>=20.9.0'} hasBin: true peerDependencies: @@ -3113,10 +3050,6 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier-linter-helpers@1.0.1: - resolution: {integrity: sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==} - engines: {node: '>=6.0.0'} - prettier-plugin-organize-imports@4.3.0: resolution: {integrity: sha512-FxFz0qFhyBsGdIsb697f/EkvHzi5SZOhWAjxcx2dLt+Q532bAlhswcXGYB1yzjZ69kW8UoadFBw7TyNwlq96Iw==} peerDependencies: @@ -3187,8 +3120,8 @@ packages: peerDependencies: react: ^19.2.8 - react-i18next@17.0.11: - resolution: {integrity: sha512-cDtkXgxjuFTWUH6V+aQn1Ve5vDiUztCNPWW5GtSHDccsgRXO1nE6QFWCEmc1KAutrb3OUv87wFShJL5RhUwPXg==} + react-i18next@17.0.12: + resolution: {integrity: sha512-lFWPEGkxQ6RhusdUkysFBD58VHfSSzvHBzqMgN0SvfVpdQGfwtNkStTqdy08/sJd7s807qqutgx93fRpD0DJ3Q==} peerDependencies: i18next: '>= 26.2.0' react: '>= 16.8.0' @@ -3561,10 +3494,6 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} - synckit@0.11.13: - resolution: {integrity: sha512-eNRKgb3z66Yp3D2CixVujOUvXLFUTij/zVnV8KRyvFdQwpz7I5DS8UfRkTeLzb64u+dkzDSdelE24izu+zSSUg==} - engines: {node: ^14.18.0 || >=16.0.0} - systeminformation@5.33.1: resolution: {integrity: sha512-DEN6ICHk3Tk0Uf/hrAHh7xlt7iL5CJFBtPZinA0H62DrGG/KPKqq/Nzj6lCXPS4Ay/sf/14zNnk9LpqKzBIc+w==} engines: {node: '>=10.0.0'} @@ -3692,8 +3621,15 @@ packages: resolution: {integrity: sha512-phPGCwqr2+Qo0fwniCE8e4pKnGu/yFb5nD5Y8bf0EEeiI5GklnACYA9GFy/DrAeRrKHXvHn+1SUsOWgJp6RO+g==} engines: {node: '>= 0.4'} - typescript@5.9.3: - resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + typescript-eslint@8.68.0: + resolution: {integrity: sha512-MHy0Y0ynqeEbx/S45+i/bBssdy3X6KNBfmJAP35GrgtNxu2TQ5K5xsFDhAnmsq1jvpdoZOPG1LGtJo0HWqYCrQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + typescript@6.0.3: + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} engines: {node: '>=14.17'} hasBin: true @@ -3989,20 +3925,20 @@ snapshots: '@babel/compat-data@7.29.7': {} - '@babel/core@7.29.7': + '@babel/core@7.29.7(supports-color@7.2.0)': dependencies: '@babel/code-frame': 7.29.7 '@babel/generator': 7.29.8 '@babel/helper-compilation-targets': 7.29.7 - '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) + '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7(supports-color@7.2.0))(supports-color@7.2.0) '@babel/helpers': 7.29.7 '@babel/parser': 7.29.8 '@babel/template': 7.29.7 - '@babel/traverse': 7.29.8 + '@babel/traverse': 7.29.8(supports-color@7.2.0) '@babel/types': 7.29.8 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@7.2.0) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -4027,19 +3963,19 @@ snapshots: '@babel/helper-globals@7.29.7': {} - '@babel/helper-module-imports@7.29.7': + '@babel/helper-module-imports@7.29.7(supports-color@7.2.0)': dependencies: - '@babel/traverse': 7.29.8 + '@babel/traverse': 7.29.8(supports-color@7.2.0) '@babel/types': 7.29.8 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)': + '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7(supports-color@7.2.0))(supports-color@7.2.0)': dependencies: - '@babel/core': 7.29.7 - '@babel/helper-module-imports': 7.29.7 + '@babel/core': 7.29.7(supports-color@7.2.0) + '@babel/helper-module-imports': 7.29.7(supports-color@7.2.0) '@babel/helper-validator-identifier': 7.29.7 - '@babel/traverse': 7.29.8 + '@babel/traverse': 7.29.8(supports-color@7.2.0) transitivePeerDependencies: - supports-color @@ -4066,7 +4002,7 @@ snapshots: '@babel/parser': 7.29.8 '@babel/types': 7.29.8 - '@babel/traverse@7.29.8': + '@babel/traverse@7.29.8(supports-color@7.2.0)': dependencies: '@babel/code-frame': 7.29.7 '@babel/generator': 7.29.8 @@ -4074,7 +4010,7 @@ snapshots: '@babel/parser': 7.29.8 '@babel/template': 7.29.7 '@babel/types': 7.29.8 - debug: 4.4.3 + debug: 4.4.3(supports-color@7.2.0) transitivePeerDependencies: - supports-color @@ -4144,23 +4080,22 @@ snapshots: tslib: 2.8.1 optional: true - '@eslint-community/eslint-utils@4.10.1(eslint@9.39.5(jiti@2.7.0))': + '@eslint-community/eslint-utils@4.10.1(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))': dependencies: - eslint: 9.39.5(jiti@2.7.0) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))': + dependencies: + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} - '@eslint/compat@2.1.0(eslint@9.39.5(jiti@2.7.0))': - dependencies: - '@eslint/core': 1.2.1 - optionalDependencies: - eslint: 9.39.5(jiti@2.7.0) - - '@eslint/config-array@0.21.2': + '@eslint/config-array@0.21.2(supports-color@7.2.0)': dependencies: '@eslint/object-schema': 2.1.7 - debug: 4.4.3 + debug: 4.4.3(supports-color@7.2.0) minimatch: 3.1.5 transitivePeerDependencies: - supports-color @@ -4173,14 +4108,10 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/core@1.2.1': - dependencies: - '@types/json-schema': 7.0.15 - - '@eslint/eslintrc@3.3.6': + '@eslint/eslintrc@3.3.6(supports-color@7.2.0)': dependencies: ajv: 6.15.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@7.2.0) espree: 10.4.0 globals: 14.0.0 ignore: 5.3.2 @@ -4420,7 +4351,7 @@ snapshots: dependencies: jsep: 1.4.0 - '@kubernetes/client-node@2.0.0': + '@kubernetes/client-node@2.0.0(supports-color@7.2.0)': dependencies: '@types/js-yaml': 4.0.9 '@types/node': 26.2.0 @@ -4428,12 +4359,12 @@ snapshots: form-data: 4.0.6 hpagent: 1.2.0 isomorphic-ws: 5.0.0(ws@8.21.2) - js-yaml: 5.3.0 + js-yaml: 5.4.0 jsonpath-plus: 10.4.0 openid-client: 6.8.5 rfc4648: 1.5.4 socks: 2.8.9 - socks-proxy-agent: 10.1.0 + socks-proxy-agent: 10.1.0(supports-color@7.2.0) stream-buffers: 3.0.3 tar-fs: 3.1.3 undici: 8.10.0 @@ -4453,34 +4384,37 @@ snapshots: '@tybys/wasm-util': 0.10.3 optional: true - '@next/env@16.3.0': {} + '@next/env@16.3.3': {} - '@next/eslint-plugin-next@15.5.22': + '@next/eslint-plugin-next@16.3.3(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))': dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0)) fast-glob: 3.3.1 + transitivePeerDependencies: + - eslint - '@next/swc-darwin-arm64@16.3.0': + '@next/swc-darwin-arm64@16.3.3': optional: true - '@next/swc-darwin-x64@16.3.0': + '@next/swc-darwin-x64@16.3.3': optional: true - '@next/swc-linux-arm64-gnu@16.3.0': + '@next/swc-linux-arm64-gnu@16.3.3': optional: true - '@next/swc-linux-arm64-musl@16.3.0': + '@next/swc-linux-arm64-musl@16.3.3': optional: true - '@next/swc-linux-x64-gnu@16.3.0': + '@next/swc-linux-x64-gnu@16.3.3': optional: true - '@next/swc-linux-x64-musl@16.3.0': + '@next/swc-linux-x64-musl@16.3.3': optional: true - '@next/swc-win32-arm64-msvc@16.3.0': + '@next/swc-win32-arm64-msvc@16.3.3': optional: true - '@next/swc-win32-x64-msvc@16.3.0': + '@next/swc-win32-x64-msvc@16.3.3': optional: true '@nodable/entities@2.2.0': {} @@ -4503,8 +4437,6 @@ snapshots: '@panva/hkdf@1.2.1': {} - '@pkgr/core@0.3.6': {} - '@protobufjs/aspromise@1.1.2': {} '@protobufjs/base64@1.1.2': {} @@ -4602,8 +4534,6 @@ snapshots: '@rtsao/scc@1.1.0': {} - '@rushstack/eslint-patch@1.16.1': {} - '@sindresorhus/is@5.6.0': {} '@so-ric/colorspace@1.1.6': @@ -4615,10 +4545,6 @@ snapshots: '@standard-schema/utils@0.3.0': {} - '@swc/helpers@0.5.15': - dependencies: - tslib: 2.8.1 - '@swc/helpers@0.5.23': dependencies: tslib: 2.8.1 @@ -4812,95 +4738,95 @@ snapshots: '@types/use-sync-external-store@0.0.6': {} - '@typescript-eslint/eslint-plugin@8.66.0(@typescript-eslint/parser@8.66.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.68.0(@typescript-eslint/parser@8.68.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.66.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.66.0 - '@typescript-eslint/type-utils': 8.66.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) - '@typescript-eslint/utils': 8.66.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.66.0 - eslint: 9.39.5(jiti@2.7.0) + '@typescript-eslint/parser': 8.68.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.68.0 + '@typescript-eslint/type-utils': 8.68.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3) + '@typescript-eslint/utils': 8.68.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.68.0 + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) ignore: 7.0.6 natural-compare: 1.4.0 - ts-api-utils: 2.5.0(typescript@5.9.3) - typescript: 5.9.3 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.66.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)': + '@typescript-eslint/parser@8.68.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3)': dependencies: - '@typescript-eslint/scope-manager': 8.66.0 - '@typescript-eslint/types': 8.66.0 - '@typescript-eslint/typescript-estree': 8.66.0(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.66.0 - debug: 4.4.3 - eslint: 9.39.5(jiti@2.7.0) - typescript: 5.9.3 + '@typescript-eslint/scope-manager': 8.68.0 + '@typescript-eslint/types': 8.68.0 + '@typescript-eslint/typescript-estree': 8.68.0(supports-color@7.2.0)(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.68.0 + debug: 4.4.3(supports-color@7.2.0) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) + typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.66.0(typescript@5.9.3)': + '@typescript-eslint/project-service@8.68.0(supports-color@7.2.0)(typescript@6.0.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.66.0(typescript@5.9.3) - '@typescript-eslint/types': 8.66.0 - debug: 4.4.3 - typescript: 5.9.3 + '@typescript-eslint/tsconfig-utils': 8.68.0(typescript@6.0.3) + '@typescript-eslint/types': 8.68.0 + debug: 4.4.3(supports-color@7.2.0) + typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.66.0': + '@typescript-eslint/scope-manager@8.68.0': dependencies: - '@typescript-eslint/types': 8.66.0 - '@typescript-eslint/visitor-keys': 8.66.0 + '@typescript-eslint/types': 8.68.0 + '@typescript-eslint/visitor-keys': 8.68.0 - '@typescript-eslint/tsconfig-utils@8.66.0(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.68.0(typescript@6.0.3)': dependencies: - typescript: 5.9.3 + typescript: 6.0.3 - '@typescript-eslint/type-utils@8.66.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.68.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3)': dependencies: - '@typescript-eslint/types': 8.66.0 - '@typescript-eslint/typescript-estree': 8.66.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.66.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) - debug: 4.4.3 - eslint: 9.39.5(jiti@2.7.0) - ts-api-utils: 2.5.0(typescript@5.9.3) - typescript: 5.9.3 + '@typescript-eslint/types': 8.68.0 + '@typescript-eslint/typescript-estree': 8.68.0(supports-color@7.2.0)(typescript@6.0.3) + '@typescript-eslint/utils': 8.68.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3) + debug: 4.4.3(supports-color@7.2.0) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.66.0': {} + '@typescript-eslint/types@8.68.0': {} - '@typescript-eslint/typescript-estree@8.66.0(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.68.0(supports-color@7.2.0)(typescript@6.0.3)': dependencies: - '@typescript-eslint/project-service': 8.66.0(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.66.0(typescript@5.9.3) - '@typescript-eslint/types': 8.66.0 - '@typescript-eslint/visitor-keys': 8.66.0 - debug: 4.4.3 + '@typescript-eslint/project-service': 8.68.0(supports-color@7.2.0)(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.68.0(typescript@6.0.3) + '@typescript-eslint/types': 8.68.0 + '@typescript-eslint/visitor-keys': 8.68.0 + debug: 4.4.3(supports-color@7.2.0) minimatch: 10.2.6 semver: 7.8.5 tinyglobby: 0.2.17 - ts-api-utils: 2.5.0(typescript@5.9.3) - typescript: 5.9.3 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.66.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)': + '@typescript-eslint/utils@8.68.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3)': dependencies: - '@eslint-community/eslint-utils': 4.10.1(eslint@9.39.5(jiti@2.7.0)) - '@typescript-eslint/scope-manager': 8.66.0 - '@typescript-eslint/types': 8.66.0 - '@typescript-eslint/typescript-estree': 8.66.0(typescript@5.9.3) - eslint: 9.39.5(jiti@2.7.0) - typescript: 5.9.3 + '@eslint-community/eslint-utils': 4.10.1(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0)) + '@typescript-eslint/scope-manager': 8.68.0 + '@typescript-eslint/types': 8.68.0 + '@typescript-eslint/typescript-estree': 8.68.0(supports-color@7.2.0)(typescript@6.0.3) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) + typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.66.0': + '@typescript-eslint/visitor-keys@8.68.0': dependencies: - '@typescript-eslint/types': 8.66.0 + '@typescript-eslint/types': 8.68.0 eslint-visitor-keys: 5.0.1 '@unrs/resolver-binding-android-arm-eabi@1.12.2': @@ -5207,9 +5133,7 @@ snapshots: base64-js@1.5.1: {} - baseline-browser-mapping@2.11.12: {} - - baseline-browser-mapping@2.11.14: {} + baseline-browser-mapping@2.11.19: {} bcrypt-pbkdf@1.0.2: dependencies: @@ -5240,8 +5164,8 @@ snapshots: browserslist@4.28.8: dependencies: - baseline-browser-mapping: 2.11.14 - caniuse-lite: 1.0.30001809 + baseline-browser-mapping: 2.11.19 + caniuse-lite: 1.0.30001810 electron-to-chromium: 1.5.406 node-releases: 2.0.53 update-browserslist-db: 1.3.1(browserslist@4.28.8) @@ -5287,9 +5211,7 @@ snapshots: callsites@3.1.0: {} - caniuse-lite@1.0.30001807: {} - - caniuse-lite@1.0.30001809: {} + caniuse-lite@1.0.30001810: {} chai@6.2.2: {} @@ -5435,13 +5357,17 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.2 - debug@3.2.7: + debug@3.2.7(supports-color@7.2.0): dependencies: ms: 2.1.3 + optionalDependencies: + supports-color: 7.2.0 - debug@4.4.3: + debug@4.4.3(supports-color@7.2.0): dependencies: ms: 2.1.3 + optionalDependencies: + supports-color: 7.2.0 decimal.js-light@2.5.1: {} @@ -5475,21 +5401,21 @@ snapshots: detect-libc@2.1.2: {} - docker-modem@5.0.7: + docker-modem@5.0.7(supports-color@7.2.0): dependencies: - debug: 4.4.3 + debug: 4.4.3(supports-color@7.2.0) readable-stream: 3.6.2 split-ca: 1.0.1 ssh2: 1.17.0 transitivePeerDependencies: - supports-color - dockerode@5.0.1: + dockerode@5.0.1(supports-color@7.2.0): dependencies: '@balena/dockerignore': 1.0.2 '@grpc/grpc-js': 1.14.4 '@grpc/proto-loader': 0.7.15 - docker-modem: 5.0.7 + docker-modem: 5.0.7(supports-color@7.2.0) protobufjs: 7.6.5 tar-fs: 2.1.5 transitivePeerDependencies: @@ -5649,76 +5575,76 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-next@15.5.22(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3): + eslint-config-next@16.3.3(@typescript-eslint/parser@8.68.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3): dependencies: - '@next/eslint-plugin-next': 15.5.22 - '@rushstack/eslint-patch': 1.16.1 - '@typescript-eslint/eslint-plugin': 8.66.0(@typescript-eslint/parser@8.66.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) - '@typescript-eslint/parser': 8.66.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) - eslint: 9.39.5(jiti@2.7.0) - eslint-import-resolver-node: 0.3.10 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(jiti@2.7.0)) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.66.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)) - eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.5(jiti@2.7.0)) - eslint-plugin-react: 7.37.5(eslint@9.39.5(jiti@2.7.0)) - eslint-plugin-react-hooks: 5.2.0(eslint@9.39.5(jiti@2.7.0)) + '@next/eslint-plugin-next': 16.3.3(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0)) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) + eslint-import-resolver-node: 0.3.10(supports-color@7.2.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.68.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0)) + eslint-plugin-react: 7.37.5(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0)) + eslint-plugin-react-hooks: 7.1.1(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) + globals: 16.4.0 + typescript-eslint: 8.68.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3) optionalDependencies: - typescript: 5.9.3 + typescript: 6.0.3 transitivePeerDependencies: + - '@typescript-eslint/parser' - eslint-import-resolver-webpack - eslint-plugin-import-x - supports-color - eslint-config-prettier@10.1.8(eslint@9.39.5(jiti@2.7.0)): + eslint-config-prettier@10.1.8(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0)): dependencies: - eslint: 9.39.5(jiti@2.7.0) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) - eslint-import-resolver-node@0.3.10: + eslint-import-resolver-node@0.3.10(supports-color@7.2.0): dependencies: - debug: 3.2.7 + debug: 3.2.7(supports-color@7.2.0) is-core-module: 2.16.2 resolve: 2.0.0-next.7 transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(jiti@2.7.0)): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0): dependencies: '@nolyfill/is-core-module': 1.0.39 - debug: 4.4.3 - eslint: 9.39.5(jiti@2.7.0) + debug: 4.4.3(supports-color@7.2.0) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) get-tsconfig: 4.14.1 is-bun-module: 2.0.0 stable-hash: 0.0.5 tinyglobby: 0.2.17 unrs-resolver: 1.12.2 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.66.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.68.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) transitivePeerDependencies: - supports-color - eslint-module-utils@2.14.0(@typescript-eslint/parser@8.66.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)): + eslint-module-utils@2.14.0(@typescript-eslint/parser@8.68.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@7.2.0))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0): dependencies: - debug: 3.2.7 + debug: 3.2.7(supports-color@7.2.0) optionalDependencies: - '@typescript-eslint/parser': 8.66.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) - eslint: 9.39.5(jiti@2.7.0) - eslint-import-resolver-node: 0.3.10 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(jiti@2.7.0)) + '@typescript-eslint/parser': 8.68.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) + eslint-import-resolver-node: 0.3.10(supports-color@7.2.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.66.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.68.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 array.prototype.findlastindex: 1.2.6 array.prototype.flat: 1.3.3 array.prototype.flatmap: 1.3.3 - debug: 3.2.7 + debug: 3.2.7(supports-color@7.2.0) doctrine: 2.1.0 - eslint: 9.39.5(jiti@2.7.0) - eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.66.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) + eslint-import-resolver-node: 0.3.10(supports-color@7.2.0) + eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.68.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@7.2.0))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) hasown: 2.0.4 is-core-module: 2.16.2 is-glob: 4.0.3 @@ -5730,13 +5656,13 @@ snapshots: string.prototype.trimend: 1.0.10 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.66.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) + '@typescript-eslint/parser': 8.68.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.5(jiti@2.7.0)): + eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0)): dependencies: aria-query: 5.3.2 array-includes: 3.1.9 @@ -5746,7 +5672,7 @@ snapshots: axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - eslint: 9.39.5(jiti@2.7.0) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) hasown: 2.0.4 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 @@ -5755,31 +5681,18 @@ snapshots: safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 - eslint-plugin-prettier@5.5.6(eslint-config-prettier@10.1.8(eslint@9.39.5(jiti@2.7.0)))(eslint@9.39.5(jiti@2.7.0))(prettier@3.9.6): + eslint-plugin-react-hooks@7.1.1(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0): dependencies: - eslint: 9.39.5(jiti@2.7.0) - prettier: 3.9.6 - prettier-linter-helpers: 1.0.1 - synckit: 0.11.13 - optionalDependencies: - eslint-config-prettier: 10.1.8(eslint@9.39.5(jiti@2.7.0)) - - eslint-plugin-react-hooks@5.2.0(eslint@9.39.5(jiti@2.7.0)): - dependencies: - eslint: 9.39.5(jiti@2.7.0) - - eslint-plugin-react-hooks@7.1.1(eslint@9.39.5(jiti@2.7.0)): - dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@7.2.0) '@babel/parser': 7.29.8 - eslint: 9.39.5(jiti@2.7.0) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) hermes-parser: 0.25.1 zod: 4.4.3 zod-validation-error: 4.0.2(zod@4.4.3) transitivePeerDependencies: - supports-color - eslint-plugin-react@7.37.5(eslint@9.39.5(jiti@2.7.0)): + eslint-plugin-react@7.37.5(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0)): dependencies: array-includes: 3.1.9 array.prototype.findlast: 1.2.5 @@ -5787,7 +5700,7 @@ snapshots: array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 es-iterator-helpers: 1.4.0 - eslint: 9.39.5(jiti@2.7.0) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) estraverse: 5.3.0 hasown: 2.0.4 jsx-ast-utils: 3.3.5 @@ -5812,14 +5725,14 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@9.39.5(jiti@2.7.0): + eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0): dependencies: - '@eslint-community/eslint-utils': 4.10.1(eslint@9.39.5(jiti@2.7.0)) + '@eslint-community/eslint-utils': 4.10.1(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0)) '@eslint-community/regexpp': 4.12.2 - '@eslint/config-array': 0.21.2 + '@eslint/config-array': 0.21.2(supports-color@7.2.0) '@eslint/config-helpers': 0.4.2 '@eslint/core': 0.17.0 - '@eslint/eslintrc': 3.3.6 + '@eslint/eslintrc': 3.3.6(supports-color@7.2.0) '@eslint/js': 9.39.5 '@eslint/plugin-kit': 0.4.1 '@humanfs/node': 0.16.8 @@ -5829,7 +5742,7 @@ snapshots: ajv: 6.15.0 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.3 + debug: 4.4.3(supports-color@7.2.0) escape-string-regexp: 4.0.0 eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -5889,8 +5802,6 @@ snapshots: fast-deep-equal@3.1.3: {} - fast-diff@1.3.0: {} - fast-fifo@1.3.2: {} fast-glob@3.3.1: @@ -5950,7 +5861,9 @@ snapshots: fn.name@1.1.0: {} - follow-redirects@1.16.0: {} + follow-redirects@1.16.0(debug@4.4.3(supports-color@7.2.0)): + optionalDependencies: + debug: 4.4.3(supports-color@7.2.0) for-each@0.3.5: dependencies: @@ -6053,6 +5966,8 @@ snapshots: globals@14.0.0: {} + globals@16.4.0: {} + globalthis@1.0.4: dependencies: define-properties: 1.2.1 @@ -6139,9 +6054,9 @@ snapshots: dependencies: '@babel/runtime': 7.29.7 - i18next@26.3.6(typescript@5.9.3): + i18next@26.3.6(typescript@6.0.3): optionalDependencies: - typescript: 5.9.3 + typescript: 6.0.3 ical.js@2.2.1: {} @@ -6348,7 +6263,7 @@ snapshots: dependencies: argparse: 2.0.1 - js-yaml@5.3.0: + js-yaml@5.4.0: dependencies: argparse: 2.0.1 @@ -6625,19 +6540,21 @@ snapshots: nanoid@3.3.17: {} + nanoid@3.3.18: {} + napi-postinstall@0.3.4: {} natural-compare@1.4.0: {} net@1.0.2: {} - next-auth@4.24.15(next@16.3.0(@babel/core@7.29.7)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8): + next-auth@4.24.15(next@16.3.3(@babel/core@7.29.7(supports-color@7.2.0))(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8): dependencies: '@babel/runtime': 7.29.7 '@panva/hkdf': 1.2.1 cookie: 0.7.2 jose: 4.15.9 - next: 16.3.0(@babel/core@7.29.7)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + next: 16.3.3(@babel/core@7.29.7(supports-color@7.2.0))(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) oauth: 0.9.15 openid-client: 5.7.1 preact: 10.29.8(preact-render-to-string@5.2.6) @@ -6646,37 +6563,37 @@ snapshots: react-dom: 19.2.8(react@19.2.8) uuid: 11.1.1 - next-i18next@16.0.10(@types/react@19.2.18)(i18next@26.3.6(typescript@5.9.3))(next@16.3.0(@babel/core@7.29.7)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-i18next@17.0.11(i18next@26.3.6(typescript@5.9.3))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(typescript@5.9.3))(react@19.2.8): + next-i18next@16.0.10(@types/react@19.2.18)(i18next@26.3.6(typescript@6.0.3))(next@16.3.3(@babel/core@7.29.7(supports-color@7.2.0))(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-i18next@17.0.12(i18next@26.3.6(typescript@6.0.3))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(typescript@6.0.3))(react@19.2.8): dependencies: '@types/hoist-non-react-statics': 3.3.7(@types/react@19.2.18) hoist-non-react-statics: 3.3.2 - i18next: 26.3.6(typescript@5.9.3) + i18next: 26.3.6(typescript@6.0.3) i18next-resources-to-backend: 1.2.3 - next: 16.3.0(@babel/core@7.29.7)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + next: 16.3.3(@babel/core@7.29.7(supports-color@7.2.0))(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) react: 19.2.8 - react-i18next: 17.0.11(i18next@26.3.6(typescript@5.9.3))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(typescript@5.9.3) + react-i18next: 17.0.12(i18next@26.3.6(typescript@6.0.3))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(typescript@6.0.3) transitivePeerDependencies: - '@types/react' - next@16.3.0(@babel/core@7.29.7)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8): + next@16.3.3(@babel/core@7.29.7(supports-color@7.2.0))(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8): dependencies: - '@next/env': 16.3.0 - '@swc/helpers': 0.5.15 - baseline-browser-mapping: 2.11.12 - caniuse-lite: 1.0.30001807 + '@next/env': 16.3.3 + '@swc/helpers': 0.5.23 + baseline-browser-mapping: 2.11.19 + caniuse-lite: 1.0.30001810 postcss: 8.5.23 react: 19.2.8 react-dom: 19.2.8(react@19.2.8) - styled-jsx: 5.1.6(@babel/core@7.29.7)(react@19.2.8) + styled-jsx: 5.1.6(@babel/core@7.29.7(supports-color@7.2.0))(react@19.2.8) optionalDependencies: - '@next/swc-darwin-arm64': 16.3.0 - '@next/swc-darwin-x64': 16.3.0 - '@next/swc-linux-arm64-gnu': 16.3.0 - '@next/swc-linux-arm64-musl': 16.3.0 - '@next/swc-linux-x64-gnu': 16.3.0 - '@next/swc-linux-x64-musl': 16.3.0 - '@next/swc-win32-arm64-msvc': 16.3.0 - '@next/swc-win32-x64-msvc': 16.3.0 + '@next/swc-darwin-arm64': 16.3.3 + '@next/swc-darwin-x64': 16.3.3 + '@next/swc-linux-arm64-gnu': 16.3.3 + '@next/swc-linux-arm64-musl': 16.3.3 + '@next/swc-linux-x64-gnu': 16.3.3 + '@next/swc-linux-x64-musl': 16.3.3 + '@next/swc-win32-arm64-msvc': 16.3.3 + '@next/swc-win32-x64-msvc': 16.3.3 sharp: 0.35.3(@types/node@26.2.0) transitivePeerDependencies: - '@babel/core' @@ -6825,7 +6742,7 @@ snapshots: postcss@8.5.23: dependencies: - nanoid: 3.3.17 + nanoid: 3.3.18 picocolors: 1.1.1 source-map-js: 1.2.1 @@ -6846,14 +6763,10 @@ snapshots: prelude-ls@1.2.1: {} - prettier-linter-helpers@1.0.1: - dependencies: - fast-diff: 1.3.0 - - prettier-plugin-organize-imports@4.3.0(prettier@3.9.6)(typescript@5.9.3): + prettier-plugin-organize-imports@4.3.0(prettier@3.9.6)(typescript@6.0.3): dependencies: prettier: 3.9.6 - typescript: 5.9.3 + typescript: 6.0.3 prettier@3.9.6: {} @@ -6930,16 +6843,16 @@ snapshots: react: 19.2.8 scheduler: 0.27.0 - react-i18next@17.0.11(i18next@26.3.6(typescript@5.9.3))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(typescript@5.9.3): + react-i18next@17.0.12(i18next@26.3.6(typescript@6.0.3))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(typescript@6.0.3): dependencies: '@babel/runtime': 7.29.7 html-parse-stringify: 4.0.1 - i18next: 26.3.6(typescript@5.9.3) + i18next: 26.3.6(typescript@6.0.3) react: 19.2.8 use-sync-external-store: 1.6.0(react@19.2.8) optionalDependencies: react-dom: 19.2.8(react@19.2.8) - typescript: 5.9.3 + typescript: 6.0.3 react-icons@5.7.0(react@19.2.8): dependencies: @@ -7238,10 +7151,10 @@ snapshots: smart-buffer@4.2.0: {} - socks-proxy-agent@10.1.0: + socks-proxy-agent@10.1.0(supports-color@7.2.0): dependencies: agent-base: 9.0.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@7.2.0) socks: 2.8.9 transitivePeerDependencies: - supports-color @@ -7381,12 +7294,12 @@ snapshots: dependencies: anynum: 1.0.1 - styled-jsx@5.1.6(@babel/core@7.29.7)(react@19.2.8): + styled-jsx@5.1.6(@babel/core@7.29.7(supports-color@7.2.0))(react@19.2.8): dependencies: client-only: 0.0.1 react: 19.2.8 optionalDependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@7.2.0) supports-color@7.2.0: dependencies: @@ -7402,10 +7315,6 @@ snapshots: symbol-tree@3.2.4: {} - synckit@0.11.13: - dependencies: - '@pkgr/core': 0.3.6 - systeminformation@5.33.1: {} tabbable@6.5.0: {} @@ -7514,9 +7423,9 @@ snapshots: triple-beam@1.4.1: {} - ts-api-utils@2.5.0(typescript@5.9.3): + ts-api-utils@2.5.0(typescript@6.0.3): dependencies: - typescript: 5.9.3 + typescript: 6.0.3 tsconfig-paths@3.15.0: dependencies: @@ -7566,7 +7475,18 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typescript@5.9.3: {} + typescript-eslint@8.68.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.68.0(@typescript-eslint/parser@8.68.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3) + '@typescript-eslint/parser': 8.68.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3) + '@typescript-eslint/typescript-estree': 8.68.0(supports-color@7.2.0)(typescript@6.0.3) + '@typescript-eslint/utils': 8.68.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + typescript@6.0.3: {} unbox-primitive@1.1.0: dependencies: diff --git a/public/images/solisquad.svg b/public/images/solisquad.svg new file mode 100644 index 000000000..b7d6b25ae --- /dev/null +++ b/public/images/solisquad.svg @@ -0,0 +1 @@ + diff --git a/public/locales/af/common.json b/public/locales/af/common.json index 196e1f769..fd9d4c559 100644 --- a/public/locales/af/common.json +++ b/public/locales/af/common.json @@ -39,7 +39,9 @@ "wait": "Wag asseblief" }, "search": { - "placeholder": "Soek…" + "placeholder": "Soek…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "SVE", diff --git a/public/locales/ar/common.json b/public/locales/ar/common.json index 0a766c932..73ba12912 100644 --- a/public/locales/ar/common.json +++ b/public/locales/ar/common.json @@ -39,7 +39,9 @@ "wait": "الرجاء الإنتظار" }, "search": { - "placeholder": "بحث …" + "placeholder": "بحث …", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "المعالج", diff --git a/public/locales/bg/common.json b/public/locales/bg/common.json index 2d447bfe1..f221bc90f 100644 --- a/public/locales/bg/common.json +++ b/public/locales/bg/common.json @@ -39,7 +39,9 @@ "wait": "Моля изчакайте" }, "search": { - "placeholder": "Търсене…" + "placeholder": "Търсене…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "Процесор", diff --git a/public/locales/ca/common.json b/public/locales/ca/common.json index 02c2c386f..2c1c9269b 100644 --- a/public/locales/ca/common.json +++ b/public/locales/ca/common.json @@ -21,7 +21,7 @@ "seconds": "s" }, "auth": { - "signout": "Sign out" + "signout": "Tanca la sessió" }, "widget": { "missing_type": "Falta el tipus de widget: {{type}}", @@ -39,7 +39,9 @@ "wait": "Si us plau, espereu" }, "search": { - "placeholder": "Cerca…" + "placeholder": "Cerca…", + "provider": "Motor de cerca: {{name}}", + "select_provider": "Escull motor de cerca" }, "resources": { "cpu": "CPU", @@ -70,17 +72,17 @@ "empty_data": "Estat del subsistema desconegut" }, "unifi_drive": { - "healthy": "Healthy", - "degraded": "Degraded", - "no_data": "No storage data available" + "healthy": "Saludable", + "degraded": "Degradat", + "no_data": "Sense dades d'emmagatzematge disponible" }, "duplicati": { - "jobs": "Jobs", - "stored": "Stored", - "lastBackup": "Last Run", - "nextRun": "Next Run", - "running": "Running", - "warnings": "Warnings", + "jobs": "Tasques", + "stored": "Desat", + "lastBackup": "Darrera execució", + "nextRun": "Propera execució", + "running": "En execució", + "warnings": "Avisos", "errors": "Errors" }, "docker": { @@ -133,7 +135,7 @@ "series": "Sèries", "episodes": "Episodis", "songs": "Cançons", - "albums": "Albums" + "albums": "Àlbums" }, "esphome": { "offline": "Desconnectat", @@ -244,10 +246,10 @@ "seed": "Sembrat" }, "qbittorrent": { - "download": "Download", - "upload": "Upload", - "leech": "Leech", - "seed": "Seed" + "download": "Baixada", + "upload": "Pujada", + "leech": "Sangonera", + "seed": "Sembrat" }, "qnap": { "cpuUsage": "Ús de CPU", @@ -258,44 +260,44 @@ "invalid": "No vàlid" }, "deluge": { - "download": "Download", - "upload": "Upload", - "leech": "Leech", - "seed": "Seed" + "download": "Baixada", + "upload": "Pujada", + "leech": "Sangonera", + "seed": "Sembrat" }, "develancacheui": { "cachehitbytes": "Bytes trobats a la memòria cau", "cachemissbytes": "Bytes no trobats a la memòria cau" }, "downloadstation": { - "download": "Download", - "upload": "Upload", - "leech": "Leech", - "seed": "Seed" + "download": "Baixada", + "upload": "Pujada", + "leech": "Sangonera", + "seed": "Sembrat" }, "sonarr": { "wanted": "Volgut", "queued": "En cua", - "series": "Series", - "queue": "Queue", - "unknown": "Unknown" + "series": "Sèries", + "queue": "Cua", + "unknown": "Desconegut" }, "radarr": { - "wanted": "Wanted", + "wanted": "Volguts", "missing": "Falten", - "queued": "Queued", - "movies": "Movies", - "queue": "Queue", - "unknown": "Unknown" + "queued": "Encuat", + "movies": "Pel·lícules", + "queue": "Cua", + "unknown": "Desconegut" }, "lidarr": { - "wanted": "Wanted", - "queued": "Queued", + "wanted": "Volguts", + "queued": "Encuat", "artists": "Artistes" }, "readarr": { - "wanted": "Wanted", - "queued": "Queued", + "wanted": "Volguts", + "queued": "Encuat", "books": "Llibres" }, "bazarr": { @@ -308,16 +310,16 @@ "available": "Disponible" }, "seerr": { - "pending": "Pending", - "approved": "Approved", - "available": "Available", - "completed": "Completed", - "processing": "Processing", - "issues": "Open Issues" + "pending": "Pendent", + "approved": "Aprovat", + "available": "Disponible", + "completed": "Completat", + "processing": "Processant", + "issues": "Temes oberts" }, "netalertx": { "total": "Total", - "connected": "Connected", + "connected": "Connectat", "new_devices": "Nous dispositius", "down_alerts": "Alertes de caigudes" }, @@ -328,18 +330,18 @@ "gravity": "Gravetat" }, "adguard": { - "queries": "Queries", - "blocked": "Blocked", + "queries": "Consultes", + "blocked": "Bloquejat", "filtered": "Filtrat", "latency": "Latència" }, "speedtest": { - "upload": "Upload", - "download": "Download", - "ping": "Ping" + "upload": "Pujada", + "download": "Baixada", + "ping": "Latència" }, "portainer": { - "running": "Running", + "running": "En execució", "stopped": "Aturat", "total": "Total" }, @@ -357,16 +359,16 @@ "address": "Adreça", "expires": "Caduca", "never": "Mai", - "user": "User", - "hostname": "Hostname", - "name": "Name", - "client_version": "Client Version", + "user": "Usuari", + "hostname": "Nom d'hoste", + "name": "Nom", + "client_version": "Versió de client", "os": "OS", - "created": "Created", - "authorized": "Authorized", - "is_external": "Is External", - "update_available": "Update Available", - "tags": "Tags", + "created": "Creat", + "authorized": "Autoritzat", + "is_external": "És extern", + "update_available": "Actualització disponible", + "tags": "Etiquetes", "last_seen": "Vist per darrer cop", "now": "Ara", "years": "{{number}}a", @@ -376,7 +378,7 @@ "minutes": "{{number}}m", "seconds": "{{number}}s", "ago": "Fa {{value}}", - "true": "Yes", + "true": "Sí", "false": "No" }, "technitium": { @@ -472,7 +474,7 @@ "users": "Usuaris", "loginsLast24H": "Inicis de sessió (24h)", "failedLoginsLast24H": "Errors d'inici de sessió (24h)", - "authorizationsLast24H": "Auths (24h)" + "authorizationsLast24H": "Autentificacions (últ. 24h)" }, "proxmox": { "mem": "MEM", @@ -540,37 +542,37 @@ "61-day": "Pluja lleugera", "61-night": "Pluja lleugera", "63-day": "Pluja", - "63-night": "Rain", + "63-night": "Pluja", "65-day": "Pluja intensa", - "65-night": "Heavy Rain", + "65-night": "Pluja forta", "66-day": "Pluja gelada", - "66-night": "Freezing Rain", - "67-day": "Freezing Rain", - "67-night": "Freezing Rain", + "66-night": "Pluja gelada", + "67-day": "Pluja gelada", + "67-night": "Pluja gelada", "71-day": "Neu lleugera", - "71-night": "Light Snow", + "71-night": "Nevada lleugera", "73-day": "Neu", - "73-night": "Snow", + "73-night": "Nevada", "75-day": "Neu intensa", - "75-night": "Heavy Snow", + "75-night": "Nevada forta", "77-day": "Neu lleugera", - "77-night": "Snow Grains", + "77-night": "Flocs de neu", "80-day": "Plovisqueig", - "80-night": "Light Showers", + "80-night": "Plugims suaus", "81-day": "Xàfecs", - "81-night": "Showers", + "81-night": "Plugims", "82-day": "Xàfecs intensos", - "82-night": "Heavy Showers", + "82-night": "Plugims forts", "85-day": "Xàfecs de neu", - "85-night": "Snow Showers", - "86-day": "Snow Showers", - "86-night": "Snow Showers", + "85-night": "Plugims amb neu", + "86-day": "Plugims amb neu", + "86-night": "Plugims amb neu", "95-day": "Tempesta", - "95-night": "Thunderstorm", + "95-night": "Tormenta", "96-day": "Tempesta amb calamarsa", - "96-night": "Thunderstorm With Hail", - "99-day": "Thunderstorm With Hail", - "99-night": "Thunderstorm With Hail" + "96-night": "Tormenta amb calamarsa", + "99-day": "Tormenta amb calamarsa", + "99-night": "Tormenta amb calamarsa" }, "homebridge": { "available_update": "Sistema", @@ -579,18 +581,18 @@ "up_to_date": "Actualitzat", "child_bridges": "Ponts fills", "child_bridges_status": "{{ok}}/{{total}}", - "up": "Up", - "pending": "Pending", - "down": "Down", + "up": "En línia", + "pending": "Pendent", + "down": "Inactiu", "ok": "Ok" }, "healthchecks": { "new": "Nou", - "up": "Up", + "up": "Actiu", "grace": "En Període de gràcia", - "down": "Down", + "down": "Inactiu", "paused": "En pausa", - "status": "Status", + "status": "Estat", "last_ping": "Últim ping", "never": "Sense pings" }, @@ -600,74 +602,74 @@ "containers_failed": "Error" }, "autobrr": { - "approvedPushes": "Approved", + "approvedPushes": "Aprovat", "rejectedPushes": "Rebutjat", "filters": "Filtres", - "indexers": "Indexers" + "indexers": "Indexadors" }, "tubearchivist": { - "downloads": "Queue", + "downloads": "Cua", "videos": "Vídeos", "channels": "Canals", "playlists": "Llistes de reproducció" }, "truenas": { "load": "Càrrega del sistema", - "uptime": "Uptime", - "alerts": "Alerts" + "uptime": "Temps actiu", + "alerts": "Alertes" }, "pyload": { "speed": "Velocitat", - "active": "Active", - "queue": "Queue", + "active": "Actiu", + "queue": "Cua", "total": "Total" }, "gluetun": { "public_ip": "IP Pública", "region": "Regió", "country": "País", - "port_forwarded": "Port Forwarded" + "port_forwarded": "Ports redirigits" }, "hdhomerun": { - "channels": "Channels", + "channels": "Canals", "hd": "HD", "tunerCount": "Sintonitzadors", "channelNumber": "Canal", "channelNetwork": "Xarxa", "signalStrength": "Intensitat", "signalQuality": "Qualitat", - "symbolQuality": "Quality", - "networkRate": "Bitrate", + "symbolQuality": "Qualitat", + "networkRate": "Taxa de bits", "clientIP": "Client" }, "scrutiny": { "passed": "Aprovat", - "failed": "Failed", - "unknown": "Unknown" + "failed": "Error", + "unknown": "Desconegut" }, "paperlessngx": { "inbox": "Safata d'entrada", "total": "Total" }, "pangolin": { - "orgs": "Orgs", - "sites": "Sites", - "resources": "Resources", - "targets": "Targets", - "traffic": "Traffic", - "in": "In", - "out": "Out" + "orgs": "Organitzacions", + "sites": "Llocs", + "resources": "Recursos", + "targets": "Objectius", + "traffic": "Tràfic", + "in": "Dins", + "out": "Fora" }, "peanut": { "battery_charge": "Càrrega de la bateria", "ups_load": "Càrrega del SAI", "ups_status": "Estat del SAI", - "online": "Online", + "online": "En línia", "on_battery": "En Bateria", "low_battery": "Bateria Baixa" }, "nextdns": { - "wait": "Please Wait", + "wait": "Espereu si us plau", "no_devices": "No s'han rebut dades del Dispositiu" }, "mikrotik": { @@ -855,37 +857,37 @@ "jdownloader": { "downloadCount": "Cua", "downloadBytesRemaining": "Restant", - "downloadTotalBytes": "Size", - "downloadSpeed": "Speed" + "downloadTotalBytes": "Mida", + "downloadSpeed": "Velocitat" }, "kavita": { - "seriesCount": "Series", - "totalFiles": "Files" + "seriesCount": "Sèries", + "totalFiles": "Fitxers" }, "azuredevops": { "result": "Resultat", - "status": "Status", + "status": "Estat", "buildId": "Id de compilació", "succeeded": "Amb èxit", "notStarted": "No Iniciat", - "failed": "Failed", + "failed": "Error", "canceled": "Cancel·lat", "inProgress": "En curs", "totalPrs": "PRs Totals", "myPrs": "Les meves PRs", - "approved": "Approved" + "approved": "Aprovat" }, "gamedig": { - "status": "Status", - "online": "Online", - "offline": "Offline", + "status": "Estat", + "online": "En línia", + "offline": "Desconnectat", "name": "Nom", "map": "Mapa", "currentPlayers": "Jugadors actuals", - "players": "Players", + "players": "Jugadors", "maxPlayers": "Màxim de jugadors", "bots": "Bots", - "ping": "Ping" + "ping": "Latència" }, "urbackup": { "ok": "Ok", @@ -895,39 +897,39 @@ }, "mealie": { "recipes": "Receptes", - "users": "Users", + "users": "Usuaris", "categories": "Categories", "tags": "Etiquetes" }, "openmediavault": { "downloading": "Descarregant", "total": "Total", - "running": "Running", - "stopped": "Stopped", - "passed": "Passed", - "failed": "Failed" + "running": "En execució", + "stopped": "Aturat", + "passed": "Aprovat", + "failed": "Error" }, "openwrt": { - "uptime": "Uptime", + "uptime": "Temps actiu", "cpuLoad": "Càrrega mitjana de CPU (5min)", - "up": "Up", - "down": "Down", + "up": "En línia", + "down": "Desconnectat", "bytesTx": "Enviat", - "bytesRx": "Received" + "bytesRx": "Rebut" }, "uptimerobot": { - "status": "Status", - "uptime": "Uptime", + "status": "Estat", + "uptime": "Temps actiu", "lastDown": "Darrera Inactivitat", "downDuration": "Duració d'Inactivitat", - "sitesUp": "Sites Up", - "sitesDown": "Sites Down", - "paused": "Paused", + "sitesUp": "Pàgines actives", + "sitesDown": "Pàgines inactives", + "paused": "Pausat", "notyetchecked": "Sense verificar", - "up": "Up", + "up": "En línia", "seemsdown": "Sembla caigut", - "down": "Down", - "unknown": "Unknown" + "down": "Desconnectat", + "unknown": "Desconegut" }, "calendar": { "inCinemas": "En cines", @@ -935,7 +937,7 @@ "digitalRelease": "Estrena digital", "noEventsToday": "Cap esdeveniment per avui!", "noEventsFound": "No s'han trobat esdeveniments", - "errorWhenLoadingData": "Error when loading calendar data" + "errorWhenLoadingData": "Error carregant dades del calendari" }, "romm": { "platforms": "Plataformes", @@ -946,50 +948,50 @@ "totalfilesize": "Tamany total" }, "mailcow": { - "domains": "Domains", + "domains": "Dominis", "mailboxes": "Bústies", "mails": "Correus", - "storage": "Storage" + "storage": "Emmagatzematge" }, "maintainerr": { - "itemsHandled": "Items Handled", - "episodesHandled": "Episodes Handled", - "moviesHandled": "Movies Handled", - "showsHandled": "Shows Handled", - "seasonsHandled": "Seasons Handled", - "reclaimable": "Reclaimable", - "movieReclaimable": "Movie Reclaimable", - "showReclaimable": "Show Reclaimable", - "totalCapacity": "Total Capacity" + "itemsHandled": "Items gestionats", + "episodesHandled": "Episodis gestionats", + "moviesHandled": "Pel·lícules gestionades", + "showsHandled": "Sèries gestionades", + "seasonsHandled": "Temporades gestionades", + "reclaimable": "Reclamable", + "movieReclaimable": "Pel·lícula reclamable", + "showReclaimable": "Sèrie reclamable", + "totalCapacity": "Capacitat total" }, "netdata": { "warnings": "Avisos", "criticals": "Crítics" }, "ntfy": { - "title": "Title", - "priority": "Priority", - "lastReceived": "Last Received", - "message": "Message", - "tags": "Tags", - "none": "None", + "title": "Títol", + "priority": "Prioritat", + "lastReceived": "Rebut per últim cop", + "message": "Missatge", + "tags": "Etiquetes", + "none": "Cap", "min": "Min", - "low": "Low", - "default": "Default", - "high": "High", + "low": "Baix", + "default": "Per defecte", + "high": "Alt", "urgent": "Urgent" }, "plantit": { "events": "Esdeveniments", "plants": "Plantes", - "photos": "Photos", + "photos": "Fotos", "species": "Espècies" }, "gitea": { "notifications": "Notificacions", - "issues": "Issues", + "issues": "Problemes", "pulls": "Sol·licitud de Canvis", - "repositories": "Repositories" + "repositories": "Repositoris" }, "stash": { "scenes": "Escenes", @@ -1003,13 +1005,13 @@ "galleries": "Biblioteques", "performers": "Intèrprets", "studios": "Estudis", - "movies": "Movies", - "tags": "Tags", + "movies": "Pel·lícules", + "tags": "Etiquetes", "oCount": "O Count" }, "tandoor": { - "users": "Users", - "recipes": "Recipes", + "users": "Usuaris", + "recipes": "Receptes", "keywords": "Paraules claus" }, "homebox": { @@ -1017,17 +1019,17 @@ "totalWithWarranty": "Amb Garantia", "locations": "Ubicacions", "labels": "Etiquetes", - "users": "Users", + "users": "Usuaris", "totalValue": "Valor total" }, "crowdsec": { - "alerts": "Alerts", + "alerts": "Alertes", "bans": "Prohibicions" }, "wgeasy": { - "connected": "Connected", - "enabled": "Enabled", - "disabled": "Disabled", + "connected": "Connectat", + "enabled": "Habilitat", + "disabled": "Deshabilitat", "total": "Total" }, "swagdashboard": { @@ -1037,9 +1039,9 @@ "banned": "Bloquejat" }, "myspeed": { - "ping": "Ping", - "download": "Download", - "upload": "Upload" + "ping": "Latència", + "download": "Baixada", + "upload": "Pujada" }, "stocks": { "stocks": "Accions", @@ -1136,120 +1138,120 @@ "tags": "Etiquetes" }, "slskd": { - "slskStatus": "Network", - "connected": "Connected", - "disconnected": "Disconnected", - "updateStatus": "Update", - "update_yes": "Available", - "update_no": "Up to Date", - "downloads": "Downloads", - "uploads": "Uploads", - "sharedFiles": "Files" + "slskStatus": "Xarxa", + "connected": "Connectat", + "disconnected": "Desconnectat", + "updateStatus": "Actualitza", + "update_yes": "Disponible", + "update_no": "Actualitzat", + "downloads": "Descàrregues", + "uploads": "Pujades", + "sharedFiles": "Fitxers" }, "jellystat": { - "songs": "Songs", - "movies": "Movies", - "episodes": "Episodes", - "other": "Other" + "songs": "Cançons", + "movies": "Pel·lícules", + "episodes": "Episodis", + "other": "Altres" }, "checkmk": { - "serviceErrors": "Service issues", - "hostErrors": "Host issues" + "serviceErrors": "Errors de servei", + "hostErrors": "Problemes de l'hoste" }, "komodo": { "total": "Total", - "running": "Running", - "stopped": "Stopped", - "down": "Down", - "unhealthy": "Unhealthy", - "unknown": "Unknown", - "servers": "Servers", + "running": "En execució", + "stopped": "Aturat", + "down": "Fora de servei", + "unhealthy": "No saludable", + "unknown": "Desconegut", + "servers": "Servidors", "stacks": "Stacks", - "containers": "Containers" + "containers": "Contenidors" }, "filebrowser": { - "available": "Available", - "used": "Used", + "available": "Disponible", + "used": "Utilitzat", "total": "Total" }, "wallos": { - "activeSubscriptions": "Subscriptions", - "thisMonthlyCost": "This Month", - "nextMonthlyCost": "Next Month", - "previousMonthlyCost": "Prev. Month", - "nextRenewingSubscription": "Next Payment" + "activeSubscriptions": "Subscripcions", + "thisMonthlyCost": "Aquest mes", + "nextMonthlyCost": "Mes que ve", + "previousMonthlyCost": "Mes passat", + "nextRenewingSubscription": "Proper pagament" }, "unraid": { - "STARTED": "Started", - "STOPPED": "Stopped", - "NEW_ARRAY": "New Array", - "RECON_DISK": "Reconstructing Disk", - "DISABLE_DISK": "Disk Disabled", - "SWAP_DSBL": "Swap Disable", - "INVALID_EXPANSION": "Invalid Expansion", - "PARITY_NOT_BIGGEST": "Parity Not Biggest", - "TOO_MANY_MISSING_DISKS": "Too Many Missing Disks", - "NEW_DISK_TOO_SMALL": "New Disk Too Small", - "NO_DATA_DISKS": "No Data Disks", - "notifications": "Notifications", - "status": "Status", + "STARTED": "Iniciat", + "STOPPED": "Aturat", + "NEW_ARRAY": "Nou array", + "RECON_DISK": "Reconstruint disc", + "DISABLE_DISK": "Disc desactivat", + "SWAP_DSBL": "Swap desactivat", + "INVALID_EXPANSION": "Expansió invàlida", + "PARITY_NOT_BIGGEST": "Paritat no del més gran", + "TOO_MANY_MISSING_DISKS": "Falten masses discs", + "NEW_DISK_TOO_SMALL": "Nou disc massa petit", + "NO_DATA_DISKS": "Sense discs de dades", + "notifications": "Notificacions", + "status": "Estat", "cpu": "CPU", - "memoryUsed": "Memory Used", - "memoryAvailable": "Memory Available", - "arrayUsed": "Array Used", - "arrayFree": "Array Free", - "poolUsed": "{{pool}} Used", - "poolFree": "{{pool}} Free" + "memoryUsed": "Memòria emprada", + "memoryAvailable": "Memòria disponible", + "arrayUsed": "Array en ús", + "arrayFree": "Array lliure", + "poolUsed": "{{pool}} en ús", + "poolFree": "{{pool}} lliure" }, "backrest": { "num_plans": "Plans", - "num_success_30": "Successes", - "num_failure_30": "Failures", - "num_success_latest": "Succeeding", - "num_failure_latest": "Failing", - "bytes_added_30": "Bytes Added" + "num_success_30": "Èxits", + "num_failure_30": "Fallades", + "num_success_latest": "Triomfant", + "num_failure_latest": "Fallant", + "bytes_added_30": "Bytes afegits" }, "yourspotify": { - "songs": "Songs", - "time": "Time", - "artists": "Artists" + "songs": "Cançons", + "time": "Temps", + "artists": "Artistes" }, "arcane": { - "containers": "Containers", - "images": "Images", - "image_updates": "Image Updates", - "images_unused": "Unused", - "environment_required": "Environment ID Required" + "containers": "Contenidors", + "images": "Imatges", + "image_updates": "Actualitzacions d'imatges", + "images_unused": "Sense utilitzar", + "environment_required": "ID d'entorn requerit" }, "dockhand": { - "running": "Running", - "stopped": "Stopped", + "running": "En execució", + "stopped": "Aturats", "cpu": "CPU", - "memory": "Memory", - "images": "Images", - "volumes": "Volumes", - "events_today": "Events Today", - "pending_updates": "Pending Updates", + "memory": "Memòria", + "images": "Imatges", + "volumes": "Volums", + "events_today": "Esdeveniments avui", + "pending_updates": "Actualitzacions pendents", "stacks": "Stacks", - "paused": "Paused", + "paused": "Pausats", "total": "Total", - "environment_not_found": "Environment Not Found" + "environment_not_found": "Entorn no trobat" }, "sparkyfitness": { - "eaten": "Eaten", - "burned": "Burned", - "remaining": "Remaining", - "steps": "Steps" + "eaten": "Menjat", + "burned": "Cremat", + "remaining": "Restant", + "steps": "Passes" }, "syncthing": { - "connected": "Connected", - "synced": "Synced", + "connected": "Connectat", + "synced": "Sincronitzat", "errors": "Errors", - "storage": "Storage" + "storage": "Emmagatzematge" }, "sportarr": { - "wanted": "Wanted", - "queued": "Queued", - "leagues": "Leagues" + "wanted": "Volgut", + "queued": "Encuat", + "leagues": "Lligues" } } diff --git a/public/locales/cs/common.json b/public/locales/cs/common.json index 275a6f202..021ec116b 100644 --- a/public/locales/cs/common.json +++ b/public/locales/cs/common.json @@ -39,7 +39,9 @@ "wait": "Počkejte prosím" }, "search": { - "placeholder": "Hledat…" + "placeholder": "Hledat…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "Využití procesoru", diff --git a/public/locales/da/common.json b/public/locales/da/common.json index da4f22817..dfbe71c26 100644 --- a/public/locales/da/common.json +++ b/public/locales/da/common.json @@ -39,7 +39,9 @@ "wait": "Vent venligst" }, "search": { - "placeholder": "Søg…" + "placeholder": "Søg…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "CPU", diff --git a/public/locales/de/common.json b/public/locales/de/common.json index 97ac2c198..48adf183d 100644 --- a/public/locales/de/common.json +++ b/public/locales/de/common.json @@ -39,7 +39,9 @@ "wait": "Bitte warten" }, "search": { - "placeholder": "Suche…" + "placeholder": "Suche…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "CPU", diff --git a/public/locales/el/common.json b/public/locales/el/common.json index 9af34a384..4b2c74bf6 100644 --- a/public/locales/el/common.json +++ b/public/locales/el/common.json @@ -39,7 +39,9 @@ "wait": "Παρακαλώ περιμένετε" }, "search": { - "placeholder": "Αναζήτηση…" + "placeholder": "Αναζήτηση…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "Επεξεργαστής", diff --git a/public/locales/en/common.json b/public/locales/en/common.json index cb72b9f4d..e355c2efd 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -39,7 +39,9 @@ "wait": "Please wait" }, "search": { - "placeholder": "Search…" + "placeholder": "Search…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "CPU", diff --git a/public/locales/eo/common.json b/public/locales/eo/common.json index b534f49c3..626a0711a 100644 --- a/public/locales/eo/common.json +++ b/public/locales/eo/common.json @@ -39,7 +39,9 @@ "wait": "Bonvolu atendi" }, "search": { - "placeholder": "Serĉi…" + "placeholder": "Serĉi…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "Ĉefprocesoro", diff --git a/public/locales/es/common.json b/public/locales/es/common.json index 91c68b309..ded79c26a 100644 --- a/public/locales/es/common.json +++ b/public/locales/es/common.json @@ -39,7 +39,9 @@ "wait": "Espera, por favor" }, "search": { - "placeholder": "Buscar…" + "placeholder": "Buscar…", + "provider": "Motor de búsqueda: {{name}}", + "select_provider": "Seleccionar motores de búsqueda" }, "resources": { "cpu": "CPU", diff --git a/public/locales/eu/common.json b/public/locales/eu/common.json index 625b0584a..a56d395e4 100644 --- a/public/locales/eu/common.json +++ b/public/locales/eu/common.json @@ -39,7 +39,9 @@ "wait": "Itxaron mesedez" }, "search": { - "placeholder": "Bilatu…" + "placeholder": "Bilatu…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "CPU", diff --git a/public/locales/fi/common.json b/public/locales/fi/common.json index c11dc8968..a6fa57228 100644 --- a/public/locales/fi/common.json +++ b/public/locales/fi/common.json @@ -39,7 +39,9 @@ "wait": "Odota, ole hyvä" }, "search": { - "placeholder": "Hae…" + "placeholder": "Hae…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "CPU", diff --git a/public/locales/fr/common.json b/public/locales/fr/common.json index 27a770bd6..697524468 100644 --- a/public/locales/fr/common.json +++ b/public/locales/fr/common.json @@ -39,7 +39,9 @@ "wait": "Veuillez patienter" }, "search": { - "placeholder": "Recherche…" + "placeholder": "Recherche…", + "provider": "Moteur de recherche : {{name}}", + "select_provider": "Sélectionnez un moteur de recherche" }, "resources": { "cpu": "CPU", diff --git a/public/locales/he/common.json b/public/locales/he/common.json index 5b3cff9c5..b0928d031 100644 --- a/public/locales/he/common.json +++ b/public/locales/he/common.json @@ -39,7 +39,9 @@ "wait": "המתן בבקשה" }, "search": { - "placeholder": "חיפוש…" + "placeholder": "חיפוש…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "מעבד", diff --git a/public/locales/hi/common.json b/public/locales/hi/common.json index 3d20dd74a..f114a6a76 100644 --- a/public/locales/hi/common.json +++ b/public/locales/hi/common.json @@ -39,7 +39,9 @@ "wait": "Please wait" }, "search": { - "placeholder": "Search…" + "placeholder": "Search…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "CPU", diff --git a/public/locales/hr/common.json b/public/locales/hr/common.json index 67bef0514..c849326c3 100644 --- a/public/locales/hr/common.json +++ b/public/locales/hr/common.json @@ -21,7 +21,7 @@ "seconds": "s" }, "auth": { - "signout": "Sign out" + "signout": "Odjavi se" }, "widget": { "missing_type": "Nedostajuća vrsta widgeta: {{type}}", @@ -39,7 +39,9 @@ "wait": "Pričekaj" }, "search": { - "placeholder": "Traži …" + "placeholder": "Traži …", + "provider": "Tražilica: {{name}}", + "select_provider": "Odaberi tražilicu" }, "resources": { "cpu": "CPU", @@ -133,7 +135,7 @@ "series": "Serije", "episodes": "Epizode", "songs": "Pjesme", - "albums": "Albums" + "albums": "Albumi" }, "esphome": { "offline": "Offline", @@ -472,7 +474,7 @@ "users": "Korisnici", "loginsLast24H": "Prijave (24 h)", "failedLoginsLast24H": "Neuspjele prijave (24 h)", - "authorizationsLast24H": "Auths (24h)" + "authorizationsLast24H": "Autorizacije (24h)" }, "proxmox": { "mem": "MEM", @@ -952,15 +954,15 @@ "storage": "Spremište" }, "maintainerr": { - "itemsHandled": "Items Handled", - "episodesHandled": "Episodes Handled", - "moviesHandled": "Movies Handled", - "showsHandled": "Shows Handled", - "seasonsHandled": "Seasons Handled", + "itemsHandled": "Obrađene stavke", + "episodesHandled": "Obrađene epizode", + "moviesHandled": "Obrađeni filmovi", + "showsHandled": "Obrađene emisije", + "seasonsHandled": "Obrađene sezone", "reclaimable": "Reclaimable", "movieReclaimable": "Movie Reclaimable", "showReclaimable": "Show Reclaimable", - "totalCapacity": "Total Capacity" + "totalCapacity": "Ukupni kapacitet" }, "netdata": { "warnings": "Upozorenja", @@ -1248,8 +1250,8 @@ "storage": "Spremište" }, "sportarr": { - "wanted": "Wanted", - "queued": "Queued", - "leagues": "Leagues" + "wanted": "Željeno", + "queued": "U redu čekanja", + "leagues": "Lige" } } diff --git a/public/locales/hu/common.json b/public/locales/hu/common.json index f573aab0b..979474218 100644 --- a/public/locales/hu/common.json +++ b/public/locales/hu/common.json @@ -39,7 +39,9 @@ "wait": "Kérjük várjon" }, "search": { - "placeholder": "Keresés…" + "placeholder": "Keresés…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "Processzor", diff --git a/public/locales/id/common.json b/public/locales/id/common.json index 088ebfbe6..96bd6f036 100644 --- a/public/locales/id/common.json +++ b/public/locales/id/common.json @@ -39,7 +39,9 @@ "wait": "Harap tunggu" }, "search": { - "placeholder": "Telusuri…" + "placeholder": "Telusuri…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "CPU", diff --git a/public/locales/it/common.json b/public/locales/it/common.json index 583c8014a..278107b7d 100644 --- a/public/locales/it/common.json +++ b/public/locales/it/common.json @@ -39,7 +39,9 @@ "wait": "Attendi per favore" }, "search": { - "placeholder": "Cerca…" + "placeholder": "Cerca…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "CPU", diff --git a/public/locales/ja/common.json b/public/locales/ja/common.json index b776fc63d..2efcb8b6d 100644 --- a/public/locales/ja/common.json +++ b/public/locales/ja/common.json @@ -39,7 +39,9 @@ "wait": "お待ちください" }, "search": { - "placeholder": "検索…" + "placeholder": "検索…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "CPU", diff --git a/public/locales/ko/common.json b/public/locales/ko/common.json index 230e5d3f9..7b6e0a9be 100644 --- a/public/locales/ko/common.json +++ b/public/locales/ko/common.json @@ -39,7 +39,9 @@ "wait": "잠시만 기다리세요" }, "search": { - "placeholder": "검색…" + "placeholder": "검색…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "CPU", @@ -472,7 +474,7 @@ "users": "사용자", "loginsLast24H": "로그인 (24시간)", "failedLoginsLast24H": "실패한 로그인 (24시간)", - "authorizationsLast24H": "Auths (24h)" + "authorizationsLast24H": "인증(24시간)" }, "proxmox": { "mem": "메모리", diff --git a/public/locales/lv/common.json b/public/locales/lv/common.json index 3f2212ecb..7e3da5e2c 100644 --- a/public/locales/lv/common.json +++ b/public/locales/lv/common.json @@ -39,7 +39,9 @@ "wait": "Lūdzu, uzgaidiet" }, "search": { - "placeholder": "Meklēt…" + "placeholder": "Meklēt…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "CPU", diff --git a/public/locales/ms/common.json b/public/locales/ms/common.json index 9c47efbf8..58aedd33c 100644 --- a/public/locales/ms/common.json +++ b/public/locales/ms/common.json @@ -39,7 +39,9 @@ "wait": "Sila tunggu" }, "search": { - "placeholder": "Carian…" + "placeholder": "Carian…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "CPU", diff --git a/public/locales/nl/common.json b/public/locales/nl/common.json index 3bec3fb94..4a30e547d 100644 --- a/public/locales/nl/common.json +++ b/public/locales/nl/common.json @@ -39,7 +39,9 @@ "wait": "Even geduld" }, "search": { - "placeholder": "Zoeken…" + "placeholder": "Zoeken…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "CPU", diff --git a/public/locales/no/common.json b/public/locales/no/common.json index df2e839cb..f94efeb7d 100644 --- a/public/locales/no/common.json +++ b/public/locales/no/common.json @@ -39,7 +39,9 @@ "wait": "Vennligst vent" }, "search": { - "placeholder": "Søk…" + "placeholder": "Søk…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "CPU", diff --git a/public/locales/pl/common.json b/public/locales/pl/common.json index 96babaef4..f00d21d25 100644 --- a/public/locales/pl/common.json +++ b/public/locales/pl/common.json @@ -39,7 +39,9 @@ "wait": "Proszę czekać" }, "search": { - "placeholder": "Szukaj…" + "placeholder": "Szukaj…", + "provider": "Wyszukiwarka: {{name}}", + "select_provider": "Wybierz wyszukiwarkę" }, "resources": { "cpu": "Procesor", @@ -472,7 +474,7 @@ "users": "Użytkownicy", "loginsLast24H": "Logowania (24h)", "failedLoginsLast24H": "Nieudane logowania (24h)", - "authorizationsLast24H": "Auths (24h)" + "authorizationsLast24H": "Uwierzytelnienia (24h)" }, "proxmox": { "mem": "RAM", diff --git a/public/locales/pt/common.json b/public/locales/pt/common.json index 7d1393659..bf5687cfb 100644 --- a/public/locales/pt/common.json +++ b/public/locales/pt/common.json @@ -39,7 +39,9 @@ "wait": "Por favor aguarde" }, "search": { - "placeholder": "Pesquisar…" + "placeholder": "Pesquisar…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "CPU", diff --git a/public/locales/pt_BR/common.json b/public/locales/pt_BR/common.json index 2f9cc91cb..09afc6d12 100644 --- a/public/locales/pt_BR/common.json +++ b/public/locales/pt_BR/common.json @@ -39,7 +39,9 @@ "wait": "Por favor, aguarde" }, "search": { - "placeholder": "Pesquisar…" + "placeholder": "Pesquisar…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "CPU", diff --git a/public/locales/ro/common.json b/public/locales/ro/common.json index 828664534..75293f677 100644 --- a/public/locales/ro/common.json +++ b/public/locales/ro/common.json @@ -39,7 +39,9 @@ "wait": "Va rugăm așteptați" }, "search": { - "placeholder": "Caută…" + "placeholder": "Caută…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "Procesor", diff --git a/public/locales/ru/common.json b/public/locales/ru/common.json index 4b8dc07d7..90c8193e2 100644 --- a/public/locales/ru/common.json +++ b/public/locales/ru/common.json @@ -39,7 +39,9 @@ "wait": "Пожалуйста, подождите" }, "search": { - "placeholder": "Поиск…" + "placeholder": "Поиск…", + "provider": "Поисковая система: {{name}}", + "select_provider": "Выберите поисковую систему" }, "resources": { "cpu": "ЦП", diff --git a/public/locales/sk/common.json b/public/locales/sk/common.json index eb181f410..421335bed 100644 --- a/public/locales/sk/common.json +++ b/public/locales/sk/common.json @@ -39,7 +39,9 @@ "wait": "Počkajte prosím" }, "search": { - "placeholder": "Hľadať…" + "placeholder": "Hľadať…", + "provider": "Vyhľadávač: {{name}}", + "select_provider": "Vyberte vyhľadávač" }, "resources": { "cpu": "CPU", diff --git a/public/locales/sl/common.json b/public/locales/sl/common.json index 644d22f9f..086d41f5e 100644 --- a/public/locales/sl/common.json +++ b/public/locales/sl/common.json @@ -39,7 +39,9 @@ "wait": "Prosimo počakajte" }, "search": { - "placeholder": "Iskanje…" + "placeholder": "Iskanje…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "CPU", diff --git a/public/locales/sr/common.json b/public/locales/sr/common.json index 1d852c3e8..19c90547c 100644 --- a/public/locales/sr/common.json +++ b/public/locales/sr/common.json @@ -39,7 +39,9 @@ "wait": "Молим сачекајте" }, "search": { - "placeholder": "Претражи…" + "placeholder": "Претражи…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "Процесор", diff --git a/public/locales/sv/common.json b/public/locales/sv/common.json index 8361d966f..be57d399e 100644 --- a/public/locales/sv/common.json +++ b/public/locales/sv/common.json @@ -39,7 +39,9 @@ "wait": "Vänligen vänta" }, "search": { - "placeholder": "Sök…" + "placeholder": "Sök…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "CPU", diff --git a/public/locales/te/common.json b/public/locales/te/common.json index ad7eff90e..6312f27ba 100644 --- a/public/locales/te/common.json +++ b/public/locales/te/common.json @@ -39,7 +39,9 @@ "wait": "దయచేసి వేచి ఉండండి" }, "search": { - "placeholder": "వెతకండి…" + "placeholder": "వెతకండి…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "సీపియూ", diff --git a/public/locales/th/common.json b/public/locales/th/common.json index 95176de3d..27d94d0bf 100644 --- a/public/locales/th/common.json +++ b/public/locales/th/common.json @@ -39,7 +39,9 @@ "wait": "โปรดรอ" }, "search": { - "placeholder": "ค้นหา…" + "placeholder": "ค้นหา…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "ซีพียู", diff --git a/public/locales/tr/common.json b/public/locales/tr/common.json index 5b4301c59..ed1cf64a4 100644 --- a/public/locales/tr/common.json +++ b/public/locales/tr/common.json @@ -39,7 +39,9 @@ "wait": "Lütfen bekleyin" }, "search": { - "placeholder": "Ara…" + "placeholder": "Ara…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "İşlemci", diff --git a/public/locales/uk/common.json b/public/locales/uk/common.json index 1f613ab8f..1a088b49e 100644 --- a/public/locales/uk/common.json +++ b/public/locales/uk/common.json @@ -39,7 +39,9 @@ "wait": "Будь ласка, зачекайте" }, "search": { - "placeholder": "Пошук…" + "placeholder": "Пошук…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "ЦП", diff --git a/public/locales/vi/common.json b/public/locales/vi/common.json index 6a12f3e6d..08be98b40 100644 --- a/public/locales/vi/common.json +++ b/public/locales/vi/common.json @@ -21,7 +21,7 @@ "seconds": "giây" }, "auth": { - "signout": "Sign out" + "signout": "Đăng xuất" }, "widget": { "missing_type": "Thiếu loại Widget: {{type}}", @@ -39,7 +39,9 @@ "wait": "Vui lòng chờ" }, "search": { - "placeholder": "Tìm kiếm…" + "placeholder": "Tìm kiếm…", + "provider": "Công cụ tìm kiếm: {{name}}", + "select_provider": "Chọn công cụ tìm kiếm" }, "resources": { "cpu": "CPU", @@ -48,7 +50,7 @@ "free": "Dư", "used": "Đã dùng", "load": "\n", - "temp": "TEMP", + "temp": "Tạm thời", "max": "Tối đa", "uptime": "UP" }, @@ -64,24 +66,24 @@ "wlan_devices": "Thiết bị trong mạng WLAN", "lan_users": "Người dùng mạng LAN", "wlan_users": "Người dùng mạng WLAN", - "up": "UP", - "down": "DOWN", + "up": "Hoạt động", + "down": "Không hoạt động", "wait": "Vui lòng chờ", "empty_data": "Trạng thái hệ thống phụ không xác định" }, "unifi_drive": { - "healthy": "Healthy", - "degraded": "Degraded", - "no_data": "No storage data available" + "healthy": "Bình thường", + "degraded": "Suy giảm", + "no_data": "Không có dữ liệu" }, "duplicati": { - "jobs": "Jobs", - "stored": "Stored", - "lastBackup": "Last Run", - "nextRun": "Next Run", - "running": "Running", - "warnings": "Warnings", - "errors": "Errors" + "jobs": "Tác vụ", + "stored": "Đã lưu", + "lastBackup": "Lần chạy cuối", + "nextRun": "Lần chạy tiếp theo", + "running": "Đang chạy", + "warnings": "Cảnh báo", + "errors": "Lỗi" }, "docker": { "rx": "RX", @@ -96,8 +98,8 @@ "starting": "Đang bắt đầu", "unhealthy": "Bất thường", "not_found": "Không tìm thấy", - "exited": "Exited", - "partial": "Partial" + "exited": "Đã thoát", + "partial": "Một phần" }, "ping": { "error": "Lỗi", @@ -118,35 +120,35 @@ "playing": "Đang chơi", "transcoding": "Chuyển định dạng", "bitrate": "Bitrate", - "no_active": "No Active Streams", + "no_active": "Không có luồng đang hoạt động", "movies": "Phim ảnh", "series": "Series", - "episodes": "Episodes", + "episodes": "Tập", "songs": "Bài hát" }, "jellyfin": { - "playing": "Playing", - "transcoding": "Transcoding", - "bitrate": "Bitrate", - "no_active": "No Active Streams", - "movies": "Movies", + "playing": "Đang phát", + "transcoding": "Đang chuyển mã", + "bitrate": "Tốc độ bit", + "no_active": "Không có luồng đang hoạt động", + "movies": "Phim", "series": "Series", - "episodes": "Episodes", - "songs": "Songs", - "albums": "Albums" + "episodes": "Tập", + "songs": "Bài hát", + "albums": "Album" }, "esphome": { "offline": "Offline", "offline_alt": "Offline", "online": "Online", - "total": "Total", + "total": "Tổng cộng", "unknown": "Không xác định" }, "evcc": { - "pv_power": "Production", + "pv_power": "Công suất phát", "battery_soc": "Pin", "grid_power": "Lưới", - "home_power": "Consumption", + "home_power": "Công suất tiêu thụ", "charge_power": "Bộ sạc", "kilowatt": "kW" }, @@ -154,7 +156,7 @@ "download": "Tải xuống", "upload": "Tải lên", "leech": "", - "seed": "Seed" + "seed": "Seeder" }, "freshrss": { "subscriptions": "Đăng ký", @@ -173,115 +175,115 @@ "maxDown": "Tải xuống tối đa", "maxUp": "Tải lên tối đa", "down": "Down", - "up": "Up", - "received": "Received", - "sent": "Sent", - "externalIPAddress": "Ext. IP", - "externalIPv6Address": "Ext. IPv6", - "externalIPv6Prefix": "Ext. IPv6-Prefix" + "up": "Tải lên", + "received": "Đã nhận", + "sent": "Đã gửi", + "externalIPAddress": "Địa chỉ IP bên ngoài", + "externalIPv6Address": "Địa chỉ IPv6 bên ngoài", + "externalIPv6Prefix": "Tiền tố IPv6 bên ngoài" }, "caddy": { - "upstreams": "Upstreams", - "requests": "Current requests", - "requests_failed": "Failed requests" + "upstreams": "Máy chủ backend", + "requests": "Yêu cầu hiện tại", + "requests_failed": "Yêu cầu thất bại" }, "changedetectionio": { - "totalObserved": "Total Observed", - "diffsDetected": "Diffs Detected" + "totalObserved": "Tổng số đã theo dõi", + "diffsDetected": "Số thay đổi đã phát hiện" }, "channelsdvrserver": { - "shows": "Shows", - "recordings": "Recordings", - "scheduled": "Scheduled", - "passes": "Passes" + "shows": "Chương trình", + "recordings": "Bản ghi", + "scheduled": "Đã lên lịch", + "passes": "Quy tắc ghi" }, "tautulli": { - "playing": "Playing", - "transcoding": "Transcoding", - "bitrate": "Bitrate", - "no_active": "No Active Streams", - "plex_connection_error": "Check Plex Connection" + "playing": "Đang phát", + "transcoding": "Đang chuyển mã", + "bitrate": "Tốc độ bit", + "no_active": "Không có luồng đang hoạt động", + "plex_connection_error": "Kiểm tra kết nối Plex" }, "tracearr": { - "no_active": "No Active Streams", - "streams": "Streams", - "transcodes": "Transcodes", - "directplay": "Direct Play", - "bitrate": "Bitrate" + "no_active": "Không có luồng đang hoạt động", + "streams": "Luồng", + "transcodes": "Luồng chuyển mã", + "directplay": "Phát trực tiếp", + "bitrate": "Tốc độ bit" }, "omada": { - "connectedAp": "Connected APs", - "activeUser": "Active devices", - "alerts": "Alerts", - "connectedGateways": "Connected gateways", - "connectedSwitches": "Connected switches" + "connectedAp": "AP đã kết nối", + "activeUser": "Thiết bị đang hoạt động", + "alerts": "Cảnh báo", + "connectedGateways": "Gateway đã kết nối", + "connectedSwitches": "Switch đã kết nối" }, "nzbget": { - "rate": "Rate", - "remaining": "Remaining", + "rate": "Tốc độ", + "remaining": "Còn lại", "downloaded": "Đã tải" }, "plex": { - "streams": "Active Streams", - "albums": "Albums", - "movies": "Movies", - "tv": "TV Shows" + "streams": "Luồng đang hoạt động", + "albums": "Album", + "movies": "Phim", + "tv": "Chương trình TV" }, "sabnzbd": { - "rate": "Rate", + "rate": "Tốc độ", "queue": "Hàng chờ", "timeleft": "Thời gian còn lại" }, "rutorrent": { "active": "Hoạt động", - "upload": "Upload", - "download": "Download" + "upload": "Tải lên", + "download": "Tải xuống" }, "transmission": { - "download": "Download", - "upload": "Upload", - "leech": "Leech", - "seed": "Seed" + "download": "Tải xuống", + "upload": "Tải lên", + "leech": "Leecher", + "seed": "Seeder" }, "qbittorrent": { - "download": "Download", - "upload": "Upload", - "leech": "Leech", - "seed": "Seed" + "download": "Tải xuống", + "upload": "Tải lên", + "leech": "Leecher", + "seed": "Seeder" }, "qnap": { - "cpuUsage": "CPU Usage", - "memUsage": "MEM Usage", - "systemTempC": "System Temp", - "poolUsage": "Pool Usage", - "volumeUsage": "Volume Usage", - "invalid": "Invalid" + "cpuUsage": "Mức sử dụng CPU", + "memUsage": "Mức sử dụng bộ nhớ", + "systemTempC": "Nhiệt độ hệ thống", + "poolUsage": "Mức sử dụng pool", + "volumeUsage": "Mức sử dụng volume", + "invalid": "Không hợp lệ" }, "deluge": { - "download": "Download", - "upload": "Upload", - "leech": "Leech", - "seed": "Seed" + "download": "Tải xuống", + "upload": "Tải lên", + "leech": "Leecher", + "seed": "Seeder" }, "develancacheui": { - "cachehitbytes": "Cache Hit Bytes", - "cachemissbytes": "Cache Miss Bytes" + "cachehitbytes": "Dung lượng cache hit", + "cachemissbytes": "Dung lượng cache miss" }, "downloadstation": { - "download": "Download", - "upload": "Upload", - "leech": "Leech", - "seed": "Seed" + "download": "Tải xuống", + "upload": "Tải lên", + "leech": "Leecher", + "seed": "Seeder" }, "sonarr": { - "wanted": "Wanted", + "wanted": "Cần tải", "queued": "Queued", - "series": "Series", + "series": "Phim bộ", "queue": "Queue", "unknown": "Unknown" }, "radarr": { - "wanted": "Wanted", + "wanted": "Cần tải", "missing": "Missing", "queued": "Queued", "movies": "Movies", @@ -289,12 +291,12 @@ "unknown": "Unknown" }, "lidarr": { - "wanted": "Wanted", + "wanted": "Cần tải", "queued": "Queued", "artists": "Artists" }, "readarr": { - "wanted": "Wanted", + "wanted": "Cần tải", "queued": "Queued", "books": "Sách" }, @@ -334,66 +336,66 @@ "latency": "Latency" }, "speedtest": { - "upload": "Upload", - "download": "Download", + "upload": "Tải lên", + "download": "Tải xuống", "ping": "Ping" }, "portainer": { - "running": "Running", - "stopped": "Stopped", - "total": "Total" + "running": "Đang chạy", + "stopped": "Đã dừng", + "total": "Tổng cộng" }, "suwayomi": { - "download": "Downloaded", - "nondownload": "Non-Downloaded", - "read": "Read", - "unread": "Unread", - "downloadedread": "Downloaded & Read", - "downloadedunread": "Downloaded & Unread", - "nondownloadedread": "Non-Downloaded & Read", - "nondownloadedunread": "Non-Downloaded & Unread" + "download": "Đã tải xuống", + "nondownload": "Chưa tải xuống", + "read": "Đã đọc", + "unread": "Chưa đọc", + "downloadedread": "Đã tải xuống & Đã đọc", + "downloadedunread": "Đã tải xuống & Chưa đọc", + "nondownloadedread": "Chưa tải xuống & Đã đọc", + "nondownloadedunread": "Chưa tải xuống & Chưa đọc" }, "tailscale": { - "address": "Address", - "expires": "Expires", - "never": "Never", - "user": "User", - "hostname": "Hostname", - "name": "Name", - "client_version": "Client Version", - "os": "OS", - "created": "Created", - "authorized": "Authorized", - "is_external": "Is External", - "update_available": "Update Available", - "tags": "Tags", - "last_seen": "Last Seen", - "now": "Now", - "years": "{{number}}y", - "weeks": "{{number}}w", - "days": "{{number}}d", - "hours": "{{number}}h", - "minutes": "{{number}}m", - "seconds": "{{number}}s", - "ago": "{{value}} Ago", - "true": "Yes", - "false": "No" + "address": "Địa chỉ", + "expires": "Hết hạn", + "never": "Không bao giờ", + "user": "Người dùng", + "hostname": "Tên máy chủ", + "name": "Tên", + "client_version": "Phiên bản máy khách", + "os": "Hệ điều hành", + "created": "Đã tạo", + "authorized": "Đã cấp quyền", + "is_external": "Là bên ngoài", + "update_available": "Có bản cập nhật", + "tags": "Thẻ", + "last_seen": "Lần cuối nhìn thấy", + "now": "Bây giờ", + "years": "{{number}} năm", + "weeks": "{{number}} tuần", + "days": "{{number}} ngày", + "hours": "{{number}} giờ", + "minutes": "{{number}} phút", + "seconds": "{{number}} giây", + "ago": "{{value}} trước", + "true": "Có", + "false": "Không" }, "technitium": { - "totalQueries": "Queries", - "totalNoError": "Success", - "totalServerFailure": "Failures", - "totalNxDomain": "NX Domains", - "totalRefused": "Refused", + "totalQueries": "Tổng số truy vấn", + "totalNoError": "Thành công", + "totalServerFailure": "Lỗi máy chủ", + "totalNxDomain": "NX Domain", + "totalRefused": "Bị từ chối", "totalAuthoritative": "Authoritative", "totalRecursive": "Recursive", - "totalCached": "Cached", - "totalBlocked": "Blocked", - "totalDropped": "Dropped", - "totalClients": "Clients" + "totalCached": "Được lưu trong bộ nhớ đệm", + "totalBlocked": "Bị chặn", + "totalDropped": "Bị loại bỏ", + "totalClients": "Số máy khách" }, "tdarr": { - "queue": "Queue", + "queue": "Hàng đợi", "processed": "Processed", "errored": "Errored", "saved": "Saved" @@ -410,7 +412,7 @@ "unknown": "Unknown" }, "navidrome": { - "nothing_streaming": "No Active Streams", + "nothing_streaming": "Không có luồng đang hoạt động", "please_wait": "Please Wait" }, "npm": { @@ -453,9 +455,9 @@ "domain_count": "Domains" }, "medusa": { - "wanted": "Wanted", + "wanted": "Cần tải", "queued": "Queued", - "series": "Series" + "series": "Phim bộ" }, "minecraft": { "players": "Players", @@ -472,66 +474,66 @@ "users": "Users", "loginsLast24H": "Logins (24h)", "failedLoginsLast24H": "Failed Logins (24h)", - "authorizationsLast24H": "Auths (24h)" + "authorizationsLast24H": "Lượt ủy quyền (24 giờ)" }, "proxmox": { - "mem": "MEM", + "mem": "Bộ nhớ", "cpu": "CPU", "lxc": "LXC", - "vms": "VMs" + "vms": "VM" }, "pulse": { - "nodes": "Nodes", - "vms": "VMs", - "lxcs": "LXCs" + "nodes": "Node", + "vms": "VM", + "lxcs": "LXC" }, "glances": { "cpu": "CPU", - "load": "Load", - "wait": "Please wait", - "temp": "TEMP", - "_temp": "Temp", - "warn": "Warn", - "uptime": "UP", - "total": "Total", - "free": "Free", - "used": "Used", - "days": "d", - "hours": "h", - "crit": "Crit", - "read": "Read", - "write": "Write", + "load": "Tải hệ thống", + "wait": "Vui lòng đợi", + "temp": "Nhiệt độ", + "_temp": "Nhiệt độ", + "warn": "Cảnh báo", + "uptime": "Thời gian hoạt động", + "total": "Tổng cộng", + "free": "Còn trống", + "used": "Đã sử dụng", + "days": "ngày", + "hours": "giờ", + "crit": "Nghiêm trọng", + "read": "Đọc", + "write": "Ghi", "gpu": "GPU", - "mem": "Mem", + "mem": "Bộ nhớ", "swap": "Swap" }, "quicklaunch": { - "bookmark": "Bookmark", - "service": "Service", - "search": "Search", - "custom": "Custom", - "visit": "Visit", + "bookmark": "Dấu trang", + "service": "Dịch vụ", + "search": "Tìm kiếm", + "custom": "Tùy chỉnh", + "visit": "Truy cập", "url": "URL", - "searchsuggestion": "Suggestion" + "searchsuggestion": "Gợi ý" }, "wmo": { - "0-day": "Sunny", - "0-night": "Clear", - "1-day": "Mainly Sunny", - "1-night": "Mainly Clear", - "2-day": "Partly Cloudy", - "2-night": "Partly Cloudy", - "3-day": "Cloudy", - "3-night": "Cloudy", - "45-day": "Foggy", - "45-night": "Foggy", - "48-day": "Foggy", - "48-night": "Foggy", - "51-day": "Light Drizzle", - "51-night": "Light Drizzle", - "53-day": "Drizzle", - "53-night": "Drizzle", - "55-day": "Heavy Drizzle", + "0-day": "Trời nắng", + "0-night": "Trời quang", + "1-day": "Chủ yếu có nắng", + "1-night": "Chủ yếu trời quang", + "2-day": "Có mây từng phần", + "2-night": "Có mây từng phần", + "3-day": "Nhiều mây", + "3-night": "Nhiều mây", + "45-day": "Có sương mù", + "45-night": "Có sương mù", + "48-day": "Có sương mù", + "48-night": "Có sương mù", + "51-day": "Mưa phùn nhẹ", + "51-night": "Mưa phùn nhẹ", + "53-day": "Mưa phùn", + "53-night": "Mưa phùn", + "55-day": "Mưa phùn lớn", "55-night": "Heavy Drizzle", "56-day": "Light Freezing Drizzle", "56-night": "Light Freezing Drizzle", @@ -739,14 +741,14 @@ "m": "m" }, "atsumeru": { - "series": "Series", + "series": "Bộ truyện", "archives": "Archives", "chapters": "Chapters", "categories": "Categories" }, "komga": { "libraries": "Libraries", - "series": "Series", + "series": "Bộ truyện", "books": "Books" }, "diskstation": { @@ -759,9 +761,9 @@ "streams": "Streams" }, "mylar": { - "series": "Series", + "series": "Phim bộ", "issues": "Issues", - "wanted": "Wanted" + "wanted": "Cần tải" }, "photoprism": { "albums": "Albums", @@ -844,7 +846,7 @@ "books": "Books", "authors": "Authors", "categories": "Categories", - "series": "Series" + "series": "Bộ sách" }, "booklore": { "libraries": "Libraries", @@ -859,7 +861,7 @@ "downloadSpeed": "Speed" }, "kavita": { - "seriesCount": "Series", + "seriesCount": "Số bộ truyện", "totalFiles": "Files" }, "azuredevops": { @@ -1248,7 +1250,7 @@ "storage": "Storage" }, "sportarr": { - "wanted": "Wanted", + "wanted": "Cần tải", "queued": "Queued", "leagues": "Leagues" } diff --git a/public/locales/yue/common.json b/public/locales/yue/common.json index e21d96624..09fbbb8b3 100644 --- a/public/locales/yue/common.json +++ b/public/locales/yue/common.json @@ -39,7 +39,9 @@ "wait": "請稍後" }, "search": { - "placeholder": "搜索緊…" + "placeholder": "搜索緊…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "CPU", diff --git a/public/locales/zh-Hans/common.json b/public/locales/zh-Hans/common.json index cda0dcfdf..cca2a9869 100644 --- a/public/locales/zh-Hans/common.json +++ b/public/locales/zh-Hans/common.json @@ -39,7 +39,9 @@ "wait": "请稍候" }, "search": { - "placeholder": "搜索…" + "placeholder": "搜索…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "CPU", diff --git a/public/locales/zh-Hant/common.json b/public/locales/zh-Hant/common.json index fb8699408..97eec8ac7 100644 --- a/public/locales/zh-Hant/common.json +++ b/public/locales/zh-Hant/common.json @@ -39,7 +39,9 @@ "wait": "請稍候" }, "search": { - "placeholder": "搜尋…" + "placeholder": "搜尋…", + "provider": "Search engine: {{name}}", + "select_provider": "Select search engine" }, "resources": { "cpu": "CPU", diff --git a/src/__tests__/pages/api/auth/[...nextauth].test.js b/src/__tests__/pages/api/auth/[...nextauth].test.js index e963b3b59..05f670f50 100644 --- a/src/__tests__/pages/api/auth/[...nextauth].test.js +++ b/src/__tests__/pages/api/auth/[...nextauth].test.js @@ -73,6 +73,7 @@ describe("pages/api/auth/[...nextauth]", () => { it("routes sanitized NextAuth logs through the Homepage logger", async () => { const mod = await import("pages/api/auth/[...nextauth]"); const sensitiveMetadata = { + error: Object.assign(new Error("State cookie was missing."), { access_token: "sensitive-access-token" }), clientSecret: "sensitive-client-secret", access_token: "sensitive-access-token", id_token: "sensitive-id-token", @@ -82,7 +83,7 @@ describe("pages/api/auth/[...nextauth]", () => { mod.authOptions.logger.warn("NEXTAUTH_URL", sensitiveMetadata); mod.authOptions.logger.debug("OAUTH_CALLBACK_RESPONSE", sensitiveMetadata); - expect(errorMock).toHaveBeenCalledWith("%s", "OAUTH_CALLBACK_ERROR"); + expect(errorMock).toHaveBeenCalledWith("%s: %s", "OAUTH_CALLBACK_ERROR", "State cookie was missing."); expect(warnMock).toHaveBeenCalledWith("%s", "NEXTAUTH_URL"); expect(debugMock).toHaveBeenCalledWith("%s", "OAUTH_CALLBACK_RESPONSE"); expect(JSON.stringify([...errorMock.mock.calls, ...warnMock.mock.calls, ...debugMock.mock.calls])).not.toContain( diff --git a/src/__tests__/pages/index.test.jsx b/src/__tests__/pages/index.test.jsx index 1d8c03240..c543161c7 100644 --- a/src/__tests__/pages/index.test.jsx +++ b/src/__tests__/pages/index.test.jsx @@ -1,6 +1,6 @@ // @vitest-environment jsdom -import { fireEvent, render, screen, waitFor } from "@testing-library/react"; +import { act, fireEvent, render, screen, waitFor } from "@testing-library/react"; import { beforeEach, describe, expect, it, vi } from "vitest"; import { ColorContext } from "utils/contexts/color"; @@ -25,6 +25,7 @@ const { throwIn: null, validateData: [], hashData: null, + hashConfig: null, mutateHash: vi.fn(), servicesData: [], bookmarksData: [], @@ -59,9 +60,12 @@ const { const serverSideTranslations = vi.fn(async (language) => ({ _translations: language })); const logger = { error: vi.fn() }; - const useSWR = vi.fn((key) => { + const useSWR = vi.fn((key, config) => { if (key === "/api/validate") return { data: state.validateData }; - if (key === "/api/hash") return { data: state.hashData, mutate: state.mutateHash }; + if (key === "/api/hash") { + state.hashConfig = config; + return { data: state.hashData, mutate: state.mutateHash }; + } if (key === "/api/services") return { data: state.servicesData }; if (key === "/api/bookmarks") return { data: state.bookmarksData }; if (key === "/api/widgets") return { data: state.widgetsData }; @@ -172,6 +176,7 @@ describe("pages/index getStaticProps", () => { state.throwIn = null; state.validateData = []; state.hashData = null; + state.hashConfig = null; state.servicesData = []; state.bookmarksData = []; state.widgetsData = []; @@ -351,6 +356,7 @@ describe("pages/index Index routing + SWR branches", () => { } await renderIndex({ initialSettings: { title: "Homepage", layout: {} }, settings: { layout: {} } }); + act(() => state.hashConfig.onSuccess(state.hashData)); await waitFor(() => { expect(fetchSpy).toHaveBeenCalledWith("/api/revalidate"); @@ -379,11 +385,24 @@ describe("pages/index Index routing + SWR branches", () => { localStorage.removeItem("hash"); await renderIndex({ initialSettings: { title: "Homepage", layout: {} }, settings: { layout: {} } }); + act(() => state.hashConfig.onSuccess(state.hashData)); await waitFor(() => { expect(localStorage.getItem("hash")).toBe("first-hash"); }); }); + + it("ignores a hash response without a hash", async () => { + state.validateData = []; + localStorage.setItem("hash", "old-hash"); + + await renderIndex({ initialSettings: { title: "Homepage", layout: {} }, settings: { layout: {} } }); + + expect(() => act(() => state.hashConfig.onSuccess(null))).not.toThrow(); + expect(() => act(() => state.hashConfig.onSuccess({}))).not.toThrow(); + expect(localStorage.getItem("hash")).toBe("old-hash"); + expect(document.querySelector(".animate-spin")).toBeFalsy(); + }); }); describe("pages/index Home behavior", () => { @@ -419,11 +438,27 @@ describe("pages/index Home behavior", () => { fireEvent.keyDown(document.body, { key: "a" }); expect(screen.getByTestId("quicklaunch")).toHaveTextContent("open:3"); + expect(state.quickLaunchProps.searchString).toBe("a"); fireEvent.keyDown(document.body, { key: "Escape" }); expect(screen.getByTestId("quicklaunch")).toHaveTextContent("closed:3"); }); + it("opens search on space without seeding the query with whitespace", async () => { + await renderIndex({ + initialSettings: { title: "Homepage", layout: {} }, + settings: { title: "Homepage", layout: {}, language: "en" }, + }); + + await waitFor(() => { + expect(state.quickLaunchProps).toBeTruthy(); + }); + + fireEvent.keyDown(document.body, { key: " " }); + expect(screen.getByTestId("quicklaunch")).toHaveTextContent("open:3"); + expect(state.quickLaunchProps.searchString).toBe(""); + }); + it("renders services and bookmark groups when present", async () => { await renderIndex({ initialSettings: { title: "Homepage", layout: {} }, @@ -489,7 +524,7 @@ describe("pages/index Home behavior", () => { state.widgetsData = []; const { setTheme, setColor, setSettings } = await renderIndex({ - initialSettings: { title: "Homepage", layout: {} }, + initialSettings: { title: "Homepage", layout: {}, favicon: "/x.ico" }, settings: { title: "Homepage", layout: {}, @@ -498,7 +533,6 @@ describe("pages/index Home behavior", () => { color: "emerald", disableIndexing: true, base: "/base/", - favicon: "/x.ico", }, theme: "dark", color: "slate", @@ -516,6 +550,20 @@ describe("pages/index Home behavior", () => { expect(document.querySelector('link[rel="icon"]')?.getAttribute("href")).toBe("/x.ico"); }); + // Safari reads the head without running JS, so the favicon has to be there before the + // settings context is populated, and mask-icon must not be + it("renders a custom favicon before the settings context is populated", async () => { + await renderIndex({ + initialSettings: { title: "Homepage", layout: {}, favicon: "/x.ico" }, + settings: {}, + }); + + expect(document.querySelector('link[rel="icon"]')?.getAttribute("href")).toBe("/x.ico"); + expect(document.querySelector('link[rel="apple-touch-icon"]')?.getAttribute("href")).toBe("/x.ico"); + expect(document.querySelector('link[rel="mask-icon"]')).toBeNull(); + expect(document.querySelector('link[rel="shortcut icon"]')).toBeNull(); + }); + it("marks information widgets as right-aligned for known widget types", async () => { await renderIndex({ initialSettings: { title: "Homepage", layout: {} }, diff --git a/src/components/bookmarks/group.jsx b/src/components/bookmarks/group.jsx index 88d4d7e8c..3030cfe15 100644 --- a/src/components/bookmarks/group.jsx +++ b/src/components/bookmarks/group.jsx @@ -1,10 +1,11 @@ import { Disclosure, Transition } from "@headlessui/react"; import classNames from "classnames"; +import { useEffect, useRef } from "react"; +import { MdKeyboardArrowDown } from "react-icons/md"; + import List from "components/bookmarks/list"; import ErrorBoundary from "components/errorboundry"; import ResolvedIcon from "components/resolvedicon"; -import { useEffect, useRef } from "react"; -import { MdKeyboardArrowDown } from "react-icons/md"; export default function BookmarksGroup({ bookmarks, diff --git a/src/components/bookmarks/item.jsx b/src/components/bookmarks/item.jsx index 7ea16bbaa..6d2c427bc 100644 --- a/src/components/bookmarks/item.jsx +++ b/src/components/bookmarks/item.jsx @@ -1,6 +1,7 @@ import classNames from "classnames"; -import ResolvedIcon from "components/resolvedicon"; import { useContext } from "react"; + +import ResolvedIcon from "components/resolvedicon"; import { SettingsContext } from "utils/contexts/settings"; export default function Item({ bookmark, iconOnly = false }) { diff --git a/src/components/bookmarks/list.jsx b/src/components/bookmarks/list.jsx index f24794db9..8f41afdfa 100644 --- a/src/components/bookmarks/list.jsx +++ b/src/components/bookmarks/list.jsx @@ -1,8 +1,9 @@ import classNames from "classnames"; -import Item from "components/bookmarks/item"; import { columnMap } from "../../utils/layout/columns"; +import Item from "components/bookmarks/item"; + export default function List({ bookmarks, layout, bookmarksStyle }) { let classes = layout?.style === "row" ? `grid ${columnMap[layout?.columns]} gap-x-2` : "flex flex-col bookmark-list"; const style = {}; diff --git a/src/components/favicon.jsx b/src/components/favicon.jsx index 8961d655e..591a88943 100644 --- a/src/components/favicon.jsx +++ b/src/components/favicon.jsx @@ -1,8 +1,8 @@ /* eslint-disable @next/next/no-img-element */ /* eslint-disable jsx-a11y/alt-text */ import { useContext, useEffect, useRef } from "react"; -import { ColorContext } from "utils/contexts/color"; +import { ColorContext } from "utils/contexts/color"; import themes from "utils/styles/themes"; export function Svg({ svgRef = null }) { diff --git a/src/components/quicklaunch.jsx b/src/components/quicklaunch.jsx index f89192a66..7375259ce 100644 --- a/src/components/quicklaunch.jsx +++ b/src/components/quicklaunch.jsx @@ -3,11 +3,12 @@ import { useTranslation } from "next-i18next/pages"; import { useCallback, useContext, useEffect, useRef, useState } from "react"; import { FiSearch } from "react-icons/fi"; import useSWR from "swr"; -import { SettingsContext } from "utils/contexts/settings"; import ResolvedIcon from "./resolvedicon"; import { getStoredProvider, searchProviders } from "./widgets/search/search"; +import { SettingsContext } from "utils/contexts/settings"; + const MOBILE_BUTTON_POSITIONS = { "top-left": "top-4 left-4", "top-right": "top-4 right-4", @@ -15,6 +16,69 @@ const MOBILE_BUTTON_POSITIONS = { "bottom-right": "bottom-4 right-4", }; +function parseUrl(searchString) { + if (!/.+[.:].+/.test(searchString)) return null; // basic test for probably a url + + try { + return new URL(searchString.toLowerCase().startsWith("http") ? searchString : `https://${searchString}`); + } catch { + return null; + } +} + +function getSearchResults({ + hideVisitURL, + searchDescriptions, + searchProvider, + searchString, + searchSuggestions, + servicesAndBookmarks, + t, + url, +}) { + if (searchString.trim().length === 0) return []; + + const results = servicesAndBookmarks.flatMap((result) => { + const nameMatch = result.name.toLowerCase().includes(searchString); + const descriptionMatch = searchDescriptions && result.description?.toLowerCase().includes(searchString); + + if (!nameMatch && !descriptionMatch) return []; + return [{ ...result, ...(searchDescriptions && { priority: nameMatch ? 2 : +descriptionMatch }) }]; + }); + + if (searchDescriptions) { + results.sort((a, b) => b.priority - a.priority); + } + + if (searchProvider) { + results.push({ + href: searchProvider.url + encodeURIComponent(searchString), + name: `${searchProvider.name ?? t("quicklaunch.custom")} ${t("quicklaunch.search")}`, + type: "search", + }); + + if (searchProvider.showSearchSuggestions && searchProvider.suggestionUrl && searchSuggestions[1]) { + results.push( + ...searchSuggestions[1].map((suggestion) => ({ + href: searchProvider.url + encodeURIComponent(suggestion), + name: suggestion, + type: "searchSuggestion", + })), + ); + } + } + + if (!hideVisitURL && url) { + results.unshift({ + href: url.toString(), + name: `${t("quicklaunch.visit")} URL`, + type: "url", + }); + } + + return results; +} + export default function QuickLaunch({ servicesAndBookmarks, searchString, setSearchString, isOpen, setSearching }) { const { t } = useTranslation(); @@ -23,9 +87,8 @@ export default function QuickLaunch({ servicesAndBookmarks, searchString, setSea const searchField = useRef(); - const [results, setResults] = useState([]); const [currentItemIndex, setCurrentItemIndex] = useState(null); - const [url, setUrl] = useState(null); + const url = parseUrl(searchString); const [searchSuggestions, setSearchSuggestions] = useState([]); const { data: widgets } = useSWR("/api/widgets"); @@ -62,7 +125,7 @@ export default function QuickLaunch({ servicesAndBookmarks, searchString, setSea : null; function openCurrentItem(newWindow) { - const result = results[currentItemIndex]; + const result = results[activeItemIndex]; window.open( result.href, newWindow ? "_blank" : (result.target ?? searchProvider?.target ?? settings.target ?? "_blank"), @@ -81,17 +144,9 @@ export default function QuickLaunch({ servicesAndBookmarks, searchString, setSea function handleSearchChange(event) { const rawSearchString = event.target.value; - try { - if (!/.+[.:].+/g.test(rawSearchString)) throw new Error(); // basic test for probably a url - let urlString = rawSearchString; - if (urlString.toLowerCase().indexOf("http") !== 0) urlString = `https://${rawSearchString}`; - setUrl(new URL(urlString)); // basic validation - setSearchString(rawSearchString); - return; - } catch (e) { - setUrl(null); - } - setSearchString(rawSearchString.toLowerCase()); + setCurrentItemIndex(null); + // urls keep their casing, everything else is lowercased for matching + setSearchString(parseUrl(rawSearchString) ? rawSearchString : rawSearchString.toLowerCase()); } function handleSearchKeyDown(event) { @@ -103,18 +158,19 @@ export default function QuickLaunch({ servicesAndBookmarks, searchString, setSea } else if (event.key === "Enter" && results.length) { closeAndReset(); openCurrentItem(event.metaKey); - } else if (event.key === "ArrowDown" && results[currentItemIndex + 1]) { - setCurrentItemIndex(currentItemIndex + 1); + } else if (event.key === "ArrowDown" && results[activeItemIndex + 1]) { + setCurrentItemIndex(activeItemIndex + 1); event.preventDefault(); - } else if (event.key === "ArrowUp" && currentItemIndex > 0) { - setCurrentItemIndex(currentItemIndex - 1); + } else if (event.key === "ArrowUp" && activeItemIndex > 0) { + setCurrentItemIndex(activeItemIndex - 1); event.preventDefault(); } else if ( event.key === "ArrowRight" && - results[currentItemIndex] && - results[currentItemIndex].type === "searchSuggestion" + results[activeItemIndex] && + results[activeItemIndex].type === "searchSuggestion" ) { - setSearchString(results[currentItemIndex].name); + setCurrentItemIndex(null); + setSearchString(results[activeItemIndex].name); } } @@ -138,88 +194,51 @@ export default function QuickLaunch({ servicesAndBookmarks, searchString, setSea } useEffect(() => { - const abortController = new AbortController(); - - if (searchString.trim().length === 0) setResults([]); - else { - let newResults = servicesAndBookmarks.filter((r) => { - const nameMatch = r.name.toLowerCase().includes(searchString); - let descriptionMatch; - if (searchDescriptions) { - descriptionMatch = r.description?.toLowerCase().includes(searchString); - r.priority = nameMatch ? 2 * +nameMatch : +descriptionMatch; - } - return nameMatch || descriptionMatch; - }); - - if (searchDescriptions) { - newResults = newResults.sort((a, b) => b.priority - a.priority); - } - - if (searchProvider) { - newResults.push({ - href: searchProvider.url + encodeURIComponent(searchString), - name: `${searchProvider.name ?? t("quicklaunch.custom")} ${t("quicklaunch.search")}`, - type: "search", - }); - - if (searchProvider.showSearchSuggestions && searchProvider.suggestionUrl) { - if (searchString.trim() !== searchSuggestions[0]?.trim()) { - fetch( - `/api/search/searchSuggestion?query=${encodeURIComponent(searchString)}&providerName=${ - searchProvider.name ?? "Custom" - }`, - { signal: abortController.signal }, - ) - .then(async (searchSuggestionResult) => { - const newSearchSuggestions = await searchSuggestionResult.json(); - - if (newSearchSuggestions) { - if (newSearchSuggestions[1].length > 4) { - newSearchSuggestions[1] = newSearchSuggestions[1].splice(0, 4); - } - setSearchSuggestions(newSearchSuggestions); - } - }) - .catch(() => { - // If there is an error, just ignore it. There just will be no search suggestions. - }); - } - - if (searchSuggestions[1]) { - newResults = newResults.concat( - searchSuggestions[1].map((suggestion) => ({ - href: searchProvider.url + encodeURIComponent(suggestion), - name: suggestion, - type: "searchSuggestion", - })), - ); - } - } - } - - if (!hideVisitURL && url) { - newResults.unshift({ - href: url.toString(), - name: `${t("quicklaunch.visit")} URL`, - type: "url", - }); - } - - setResults(newResults); - - if (newResults.length) { - setCurrentItemIndex(0); - } + if ( + searchString.trim().length === 0 || + !searchProvider?.showSearchSuggestions || + !searchProvider.suggestionUrl || + searchString.trim() === searchSuggestions[0]?.trim() + ) { + return undefined; } - return () => { - abortController.abort(); - }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [searchString, servicesAndBookmarks, searchDescriptions, hideVisitURL, searchSuggestions, searchProvider, url]); + const abortController = new AbortController(); + + fetch( + `/api/search/searchSuggestion?query=${encodeURIComponent(searchString)}&providerName=${ + searchProvider.name ?? "Custom" + }`, + { signal: abortController.signal }, + ) + .then(async (searchSuggestionResult) => { + const newSearchSuggestions = await searchSuggestionResult.json(); + + if (newSearchSuggestions) { + setCurrentItemIndex(null); + setSearchSuggestions([newSearchSuggestions[0], newSearchSuggestions[1].slice(0, 4)]); + } + }) + .catch(() => { + // If there is an error, just ignore it. There just will be no search suggestions. + }); + + return () => abortController.abort(); + }, [searchProvider, searchString, searchSuggestions]); + + const results = getSearchResults({ + hideVisitURL, + searchDescriptions, + searchProvider, + searchString, + searchSuggestions, + servicesAndBookmarks, + t, + url, + }); + + const activeItemIndex = currentItemIndex ?? (results.length ? 0 : null); - const [hidden, setHidden] = useState(true); useEffect(() => { function handleBackdropClick(event) { if (event.target?.tagName === "DIV") closeAndReset(); @@ -228,14 +247,11 @@ export default function QuickLaunch({ servicesAndBookmarks, searchString, setSea if (isOpen) { searchField.current.focus(); document.body.addEventListener("click", handleBackdropClick); - setHidden(false); } else { - document.body.removeEventListener("click", handleBackdropClick); searchField.current.blur(); - setTimeout(() => { - setHidden(true); - }, 300); // disable on close } + + return () => document.body.removeEventListener("click", handleBackdropClick); }, [isOpen, closeAndReset]); function highlightText(text) { @@ -259,13 +275,17 @@ export default function QuickLaunch({ servicesAndBookmarks, searchString, setSea <>